Skip to content

Conversation

@myasonik
Copy link
Contributor

@myasonik myasonik commented May 15, 2020

Summary

  • Made Header a functional component
    • Shortened and simplified the file quite a bit
    • Part of this also meant pushing observers to their farthest leaf component of where they're actually used reducing the rerender count, roughly, from 36 to 1 🎉
      • This also helped shorten the file
    • Added tests (Add unit tests for new nav #65369)
  • Added href prop to ChromeNavLink
    • Moved creation of href into to_nav_link.ts which consolidated how many times we had time figure it out at a few different leaf nodes
    • In a roundabout way, simplified Header because a few places now didn't need to the full "EUI-ready" NavLink and could rely on the ChromeNavLink being passed around
  • Deleted a copy-paste of relativeToAbsolute() because imports are a thing and we don't need two of them
  • Renamed _collapsible_nav.scss to collapsible_nav.scss and used the fancy new Sass-in-JS import thing
  • Removed NavLink and RecentNavLink (Add unit tests for new nav #65369)
    • The functions that used return these still exist in some form but instead of happening in Header then being passed around all over the place, it happens just before being passed into EUI so the types don't need to hang around
  • Made HeaderBreadcrumbs and HeaderNavControls functional components
    • Just way easier to read and easier to manage the observers
  • Bloated NavDrawer a little but it's ready to be deleted as soon as the old nav is removed
  • Removed truncateRecentItemLabel because it wasn't working before my nav changes even went in and the new nav doesn't need it anyways so it'd be only for the old nav (Add unit tests for new nav #65369)

Closes #65369

Checklist

For maintainers

@myasonik
Copy link
Contributor Author

@pgayvallet @joshdover Hoping one/both of y'all can take a look at this while I start working on these tests. Hopefully this refactor is going in the right direction. Don't really plan on touching much more other than test files.

Full description of changes in the description.

Michail Yasonik added 2 commits May 19, 2020 20:15
Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

A few NITs and question, overall looking good. Thanks for the migration to FC!

Comment on lines -37 to 48
...(isLegacyApp(app)
? {}
? {
href: url && !url.startsWith(app.subUrlBase!) ? url : baseUrl,
}
: {
url: relativeToAbsolute(appendAppPath(baseUrl, app.defaultPath)),
href: url,
url,
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

Moving the url logic to this function instead of the component makes sense, but I'm not sure to understand why href was introduced instead of just using the existing url and baseUrl here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mostly to align with EUI prop names otherwise it's one more prop I have to alias at the component level.

Also has a couple side benefits:

  • Makes sure that nothing breaks if something else was low key relying on url being a certain thing at a certain time so makes the refactor a little safer (can refactor one thing at a time)
  • Also makes clear what this will be used for (URLs can be constructed in a lot of different ways so knowing exactly what you're getting can be a bit of a toss up. With href you know exactly what the ultimate purpose of the prop is.)

basePath: HttpStart['basePath'];
isLocked$: Rx.Observable<boolean>;
navType$: Rx.Observable<NavType>;
loadingCount$: ReturnType<HttpStart['getLoadingCount$']>;
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: would just use Observable<number> here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why's that? I thought it would be nice to have a single source of truth on the type.

Copy link
Contributor

Choose a reason for hiding this comment

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

IDK, either way, TS compilation would fail if HttpStart['getLoadingCount$'] type changes (just not in the same file), and I find it way more readable. But it's a personal option, you can keep it like that.

(The same way I would replace HttpStart['basePath'] by it's IBasePath actual type)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 I'll keep it like this for now then. If other people have opinions on this, would be nice to come to a consensus on what we should prefer in the Kibana repo.

@myasonik myasonik added Feature:Header Work related to the header section of the Kibana app. release_note:fix Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// v7.9.0 v8.0.0 labels May 20, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@myasonik
Copy link
Contributor Author

retest

@myasonik myasonik marked this pull request as ready for review May 22, 2020 14:27
@myasonik myasonik requested review from a team as code owners May 22, 2020 14:27
@pgayvallet
Copy link
Contributor

Ack: will review tomorrow

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

Some nits and comments, overall LGTM

dataTestSubj: 'collapsibleNavAppLink',
navigateToApp,
onClick: closeNav,
...(needsIcon && { basePath }),
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably minor, but I find it a little misleading that the addition of the icon in createEuiListItem is only based on the presence or not of the basePath input.

listItems={recentlyAccessed.map(link => {
// TODO #64541
// Can remove icon from recent links completely
const { iconType, ...hydratedLink } = createRecentNavLink(link, navLinks, basePath);
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: adding a omitIcon = false param to createRecentNavLink seems a little better than spread exclusion?

Comment on lines +95 to +97
export function HeaderLogo({ href, navigateToApp, ...observables }: Props) {
const forceNavigation = useObservable(observables.forceNavigation$, false);
const navLinks = useObservable(observables.navLinks$, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: not sure to see a real upside in using a rest parameter here, but I'm fine either way

Copy link
Contributor

@snide snide left a comment

Choose a reason for hiding this comment

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

Ran through the sass changes, which were minimal. File move looks good.

Copy link
Member

@lukeelmers lukeelmers left a comment

Choose a reason for hiding this comment

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

App arch change LGTM -- seems this just reordered some props that were included in our generated markdown documentation.

@myasonik myasonik requested a review from watson as a code owner May 27, 2020 23:06
@spalger spalger removed request for a team May 27, 2020 23:14
@myasonik myasonik removed the request for review from watson May 27, 2020 23:40
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@myasonik myasonik merged commit fce016c into elastic:master May 29, 2020
@myasonik myasonik deleted the nav-refactor branch May 29, 2020 14:26
myasonik pushed a commit to myasonik/kibana that referenced this pull request May 29, 2020
Co-authored-by: spalger <[email protected]>
# Conflicts:
#	docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md
#	docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md
#	src/core/public/chrome/chrome_service.tsx
#	src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap
#	src/core/public/chrome/ui/header/collapsible_nav.test.tsx
#	src/core/public/chrome/ui/header/collapsible_nav.tsx
#	src/core/public/chrome/ui/header/header.tsx
#	src/core/public/chrome/ui/header/header_logo.tsx
#	src/core/public/chrome/ui/header/nav_drawer.tsx
#	src/plugins/data/public/public.api.md
myasonik pushed a commit that referenced this pull request May 29, 2020
@kibanamachine
Copy link
Contributor

Looks like this PR has backport PRs but they still haven't been merged. Please merge them ASAP to keep the branches relatively in sync.

@kibanamachine kibanamachine added backport missing Added to PRs automatically when the are determined to be missing a backport. and removed backport missing Added to PRs automatically when the are determined to be missing a backport. labels Jun 1, 2020
myasonik pushed a commit that referenced this pull request Jun 1, 2020
Co-authored-by: spalger <[email protected]>
Co-authored-by: Josh Dover <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature:Header Work related to the header section of the Kibana app. release_note:fix Team:Core Platform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t// v7.8.0 v7.9.0 v8.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add unit tests for new nav

9 participants