Skip to content
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

[8.7] [Dashboard] [Navigation] Fix mount point bug (#150507) #150763

Merged
merged 1 commit into from
Feb 9, 2023

Conversation

kibanamachine
Copy link
Contributor

Backport

This will backport the following commits from main to 8.7:

Questions ?

Please refer to the Backport tool documentation

Closes elastic#150371

## Summary

Oooh, man. This was a fun one!

Okay, so. To try to understand this bug, we first have to understand a
little bit about how the header action menu is rendered as part of the
`TopNavMenu` component (in `dashboard_top_nav.tsx`). Essentially, as
part of rendering `TopNavMenu`, a `MountPointPortal` is created for the
`headerActionMenu` so that the items get rendered in the correct
location, like so:

![WithAndWithoutPortal](https://user-images.githubusercontent.com/8698078/217674254-cd27470b-fcce-4cb9-b960-51ea2b8a68c8.png)

When there is **no** filter pill (i.e. `showSearchBar` is `false`), this
`MountPointPortal` gets **unmounted** alongside the search bar as part
of the `TopNavMenu` component (after all, only the dashboard viewport is
getting rendered in this scenario). When you exit fullscreen mode, both
the search bar and the `MountPointPortal` get re-mounted, which triggers
a re-render, and so the `headerActionMenu` shows up as expected.

Now, consider what happens when there **is** a filter pill (i.e. when
`showSearchBar` is `true`). Because the search bar still needs to get
rendered, neither it **nor** the `MountPointPortal` get unmounted -
instead, the search bar simply gets re-rendered while the portal gets
updated to point at an element that no longer exists (since the place
where the `headerActionMenu` normally gets rendered is no longer
present). Now, when you exit fullscreen mode, neither element needs to
get re-mounted - they simply need to get re-rendered. Everything works
great for the search bar, but the `headerActionMenu` seems to be
rendering itself **before** the portal gets a chance to point to the
correct place again - so, it doesn't show up unless a re-render of
`TopNavMenu` is manually triggered (like, say, by removing the filter
pill):

https://user-images.githubusercontent.com/8698078/217868558-7eb73df8-3417-4d5a-ab5d-e7c9138532a9.mov

So essentially, from what I can understand, this bug comes down to a
race condition between the `MountPointPortal` telling the
`headerActionMenu` **where** to render and the `TopNavMenu` actually
rendering. Since the `MountPointPortal` **is not necessary** in
fullscreen mode, regardless of if `showSearchBar` is `true` or `false`,
the best way to prevent this bug is to simply ensure that it **always**
gets unmounted when entering fullscreen mode - this ensures that the
rendering always happens in the order that it is meant to. This can be
accomplished by setting the `MenuMountPoint` to `undefined` when the
dashboard enters fullscreen mode.

As far as why this bug only happened on **click** and not when the
escape key was hit... For some reason (React magic 🤷), hitting the
escape key causes two renders of the `TopNavMenu` component whereas
clicking the button only causes a single render. This means that, by the
time the second render occurs when hitting escape, `MountPointPortal`
has had a chance to update - hence, why the menu shows up where it's
supposed to.

### Checklist

- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)

### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

(cherry picked from commit 5d4c880)
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
dashboard 365.0KB 365.1KB +66.0B

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

cc @Heenawter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants