O3 side navigation technical design

I would like to see if we can kick off some discussions to move forward with implementing the new side navigation designs highlighted in @pauladams recent design proposal.

As highlighted in those designs, there are some specific features in particular that are not currently part of the existing side navigation implementation in openmrs-esm-home (or patient-chart).


Among these are:

  • Component to display and change current session location
  • Ability to associate an icon with each navigation menu item
  • Ability to group menu items under a collapsible section (eg. Administrator tools)
  • Ability to display or hide menu items based on the current context (privilege, location tag, current route as an MVP, but ideally want to make more flexible)
  • Ability to display notification badge icons (eg. the “2” associated with Radiology here)
  • Ability to add “dynamic” menu items (eg. for all Queues associated with the session location, add a menu item for each)

As an initial discussion point, it would be useful if we could identify where we would like to implement this. Some possible options:

  • Expanding the LeftNavMenu in the style guide
  • Expanding esm-home
  • Moving the side nav alongside the top-nav implementation in esm-primary-navigation-app
  • Creating a new microfrontend that could be used as an alternative to existing side nav(s)

One consideration to think about is whether the Side Navigation implemented within patient chart would also benefit from these same features and/or we would want to consider a unified Side Nav implementation in which the “context” that controls which side navigation elements are displayed is expanded to include an optional “patient”. One could also imagine further contexts like “Visit” or “Program” down the road.

Implementing these designs in primary-navigation or in a new microfrontend that operates similarly to how the primary-navigation-app works would mean that the Side Nav is more decoupled from the main content being rendered, and would also give us the option to choose to leverage this within the patient chart.

I’m interested in any and all feedback. It would be particularly good to learn from those who have worked on the existing side navigation approaches, or who have been considering a similar set of requirements. Thanks!


So, it’s worth pointing out that most of your “initial discussion points” are already handled, that is, the left nav menu on the home page is already part of a LeftNav component in esm-primary-navigation-app, meaning it’s already part of basically any page in the app (assuming they opt-in to using it; maybe the idea here is that we’d switch from an opt-in to an opt-out setup?).

The patient chart is a separate animal, but that’s because of the design requirements (specifically, we end up rendering the visit header over top of the usual primary navigation header and this kind of necessitates rendering a different LeftNav component mostly so it’s positioned correctly relative to the new header).

The left nav itself is just an extension slot and implementing what’s in the screen shot above is just a matter of having appropriate extensions wired into that slot. Nothing there isn’t easily achieved with those extension slots as-is (except the notification icon thing; maybe that should be a separate discussion; less because it’s a bad idea a more because it’s not necessarily obvious that we have the underlying data to populate that).

Expandable links (like Admin Tools in the screenshot) are also achievable… We even have an implementation of them in the patient chart (the nav-group). There’s no reason that couldn’t be refactored into a style-guide component rather than needing to live in the patient-common-lib.

What I mean to say, is I think there aren’t really any technical decisions in the way of just implementing that screenshot as-is. Product-wise, we’ve already been pushing Sonder to add icons into the design, so I don’t think this is necessarily anything PIH-specific (though the exact links themselves may be).

Thanks so much @ibacher for responding and engaging in this discussion - especially if the answer is to tell me that this already exists :slight_smile: To sum up my understanding of some of the results of some of our offline discussions on this:

I had not realized this! This is exactly what I was proposing, which is great. However, what we found is that this is only the case when the menu is not expanded. So, when the LHN menu is collapsed into the “hamburger menu” in the header, then this is being rendered by the primary-nav. And this only happens when the layout of the screen != desktop. So right now the LHN is only conditionally rendered within primary-navigation, and it is left to other esms (eg. home, patient chart) to render the LHN in the expanded view. We agreed in our discussion that:

  • The LHN should be rendered in all modes by primary navigation, not just in non-desktop mode.
  • This should allow us to remove the code that renders the LHN within the esm-home-app altogether, and things should “just work” as normal because the LHN is already there.
  • We should also be able to remove the code that renders the LHN component within patient chart for the same reason

Another aspect is that the LHN (both the expanded and non-expanded views) should not be rendered if there are no extensions attached to any of the slots (eg. don’t render if there is nothing to show).

Yes - It seems more appropriate to me to have an opt-out system, rather than an opt-in system. This can likely be easily accomplished by adding an additional slot to the LHN, right after the global-nav-menu-slot, maybe called something like default-nav-menu-slot, which is only rendered if the slotName state within the leftNavStore is unset. Implementations can still opt-out of using this by removing all extensions from the default-nav-menu-slot, in which case the current behavior would be achieved. But the benefit is that implementations would be able to leverage the LHN slot broadly, without needing an additional esm (eg. esm-home-app) to first call a hook with a specific slot name defined by that esm in order for it to be used.

I would think that this would be achieved in a similar way to what is described above. Just like a particular page component could declare that it wants to override the LHN with a custom slot of extensions, a particular page component could declare that it wants to override the header with a particular slot of extensions. The current header would be rendered by default, but the patient chart could override this by providing the visit header as an extension and attaching this to a slot that informs the primary-nav to use it instead. And implementations could opt-out of this by removing that visit header extension from that slot, if they always just want the normal header in place.

Yes, as we discussed, it would be great if we can support capabilities like this in the styleguide, or just move it into primary-navigation so it can be leveraged generally.