Skip to content

Conversation

@mareklibra
Copy link
Contributor

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.

First use-case: Virtual Machines of the kubevirt-plugin will be positioned after Pods as requested by UXD.

@openshift-ci-robot openshift-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 23, 2019
@openshift-ci-robot
Copy link
Contributor

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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions 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.

@mareklibra mareklibra mentioned this pull request May 23, 2019
3 tasks
@spadgett spadgett added this to the v4.2 milestone May 23, 2019
Copy link
Contributor

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;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, done

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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 (?)

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

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

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@spadgett
Copy link
Member

/assign @vojtechszocs
/approve

I haven't reviewed this closely, but approving the general change. @vojtechszocs feel free to add your slash-lgtm when this is ready.

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 27, 2019
@spadgett
Copy link
Member

/ok-to-test

@openshift-ci-robot openshift-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 27, 2019
Copy link
Contributor

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.

Copy link
Contributor

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) => {};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

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);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

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.

Copy link
Contributor Author

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>>

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@openshift-ci-robot openshift-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels May 28, 2019
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.
@openshift-ci-robot openshift-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 28, 2019
Copy link
Contributor

@vojtechszocs vojtechszocs left a 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 => {
Copy link
Contributor

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 => {
Copy link
Contributor

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) || [];
Copy link
Contributor

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.

@vojtechszocs
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label May 29, 2019
@openshift-ci-robot
Copy link
Contributor

[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

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit b02b06c into openshift:master May 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants