-
Notifications
You must be signed in to change notification settings - Fork 667
NavSection: allow plugins to define their position #1609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NavSection: allow plugins to define their position #1609
Conversation
|
Hi @mareklibra. Thanks for your PR. I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "merge after" behavior is related to plugin-contributed nav links only, we shouldn't bloat existing nav link components themselves.
interface NavItem {
section: NavSectionTitle;
componentProps: Pick<NavLinkProps, 'name' | 'required' | 'disallowed' | 'startsWith'>;
+ mergeAfter?: string;
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary, Console NavList has no use for this prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit-pick: space before pc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, reworked due to change above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit-pick: the pc part of condition shouldn't be necessary (?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formerly the pc could be null - the _.compact() was farther modified by map().
But reworked due to change above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that React.Children.map may return null or undefined if there are no children.
Consequently, mergeElements function should be prepared to handle this situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to add types to function declarations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need all those parameters?
mapChild function has this bound through class field arrow function syntax, giving us access to this.props and this.state like in other methods.
const { activeNamespace, flags } = this.props;
const { activeChild } = this.state;As for the c parameter, it's currently inferred by TS as any because we're calling React.Children.map without specifying <T, C> type parameters (this code came from .jsx file).
For now, I'd suggest typing c as c: React.ReactElement (without type parameters) since the method needs access to c.props.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types added.
I considered the function to be single-purposed, just extracted from former render() closure to improve readability.
As requested, I changed it to access this directly but moved inside class definition as it expects this to meet certain contract.
|
/assign @vojtechszocs I haven't reviewed this closely, but approving the general change. @vojtechszocs feel free to add your slash-lgtm when this is ready. |
|
/ok-to-test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need all those parameters?
mapChild function has this bound through class field arrow function syntax, giving us access to this.props and this.state like in other methods.
const { activeNamespace, flags } = this.props;
const { activeChild } = this.state;As for the c parameter, it's currently inferred by TS as any because we're calling React.Children.map without specifying <T, C> type parameters (this code came from .jsx file).
For now, I'd suggest typing c as c: React.ReactElement (without type parameters) since the method needs access to c.props.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add proper typings:
const mergePluginChild = (Children: React.ReactElement[], pluginChild: React.ReactElement, mergeAfter?: string) => {};There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code complexity can be reduced:
const index = mergeAfter ? Children.findIndex(c => c.props.name === mergeAfter) : -1;
if (index >= 0) {
Children.splice(index + 1, 0, pluginChild);
} else {
Children.push(pluginChild);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add proper typings and use a method name that reflects the fact we're returning a React component created from the given nav item:
const getNavLink = (item: plugins.NavItem, key: number): NavLink<any> | null => {};You'll probably need to import NavLink type from ./items.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done with React.ReactElement<NavLink<any>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With mapChild having a single c argument, this helper function isn't needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, removed.
Anyway, .bind(this) needs to be used within React.Children.map() bellow.
Within NavSection, a plugin can provide "mergeAfter" optional string property to denote after which element will be rendered. If "mergeAfter" is omitted or not-matching, the item is appended at the end.
vojtechszocs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mareklibra @spadgett LGTM, posted some nit-picks regarding redundant type annotations (aiming for concise code).
| } | ||
| }; | ||
|
|
||
| const getNavLinkFromItem = (item: plugins.NavItem, key: number): React.ReactElement | null => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit-pick: the return type declaration React.ReactElement | null can be removed since TS compiler can infer that from code analysis.
This is similar to writing const foo = true instead of const foo: boolean = true, which keeps the code shorter.
| (section) => plugins.registry.getNavItems(section) | ||
| ); | ||
|
|
||
| mapChild = (c: React.ReactElement): React.ReactElement | null => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit-pick: the React.ReactElement | null return type can be automatically inferred, I'd remove it.
| } | ||
| if (plugins.isResourceClusterNavItem(item)) { | ||
| return <ResourceClusterLink key={index} {...item.properties.componentProps} />; | ||
| const Children: React.ReactElement[] | null = React.Children.map(children, this.mapChild) || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit-pick: the type of Children can be automatically inferred, I'd remove it.
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mareklibra, spadgett, vojtechszocs The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Within NavSection, a plugin can provide
mergeAfteroptional string propertyto denote after which element will be rendered.
If
mergeAfteris omitted or not-matching, the item is appended at the end.First use-case:
Virtual Machinesof thekubevirt-pluginwill be positioned afterPodsas requested by UXD.