Skip to content

Commit

Permalink
EXPERIMENT: Use active single-spa app to name leftnav
Browse files Browse the repository at this point in the history
  • Loading branch information
ibacher committed May 10, 2024
1 parent 1015f82 commit 6a8246f
Show file tree
Hide file tree
Showing 34 changed files with 425 additions and 246 deletions.
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

set -e # die on error

npx lint-staged
yarn lint-staged
yarn turbo extract-translations
yarn turbo document --since main
1 change: 1 addition & 0 deletions packages/apps/esm-primary-navigation-app/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
moduleNameMapper: {
'lodash-es': 'lodash',
'@openmrs/esm-framework': '@openmrs/esm-framework/mock.tsx',
'@openmrs/esm-framework/src/internal': '@openmrs/esm-framework/mock.tsx',
'\\.(s?css)$': 'identity-obj-proxy',
'react-i18next': '<rootDir>/__mocks__/react-i18next.mock.js',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
/** @module @category UI */
import React from 'react';
import { ExtensionSlot, useStore, leftNavStore } from '@openmrs/esm-framework/src/internal';
import { ExtensionSlot, getActiveAppNames, useConnectedExtensions } from '@openmrs/esm-framework/src/internal';
import type { SideNavProps } from '@carbon/react';
import { SideNav } from '@carbon/react';
import styles from './left-nav.module.scss';

type LeftNavMenuProps = SideNavProps;

const basePath = window.getOpenmrsSpaBase();
const defaultNavSlot = 'default-dashboard-slot';

export const LeftNavMenu = React.forwardRef<HTMLElement, LeftNavMenuProps>((props, ref) => {
const { slotName, basePath } = useStore(leftNavStore);
const currentPath = window.location ?? { pathname: '' };
const activePages = getActiveAppNames();
const leftNavSlot = activePages && activePages.length === 1 ? `${activePages[0]}-dashboard-slot` : undefined;
const leftNavItems = useConnectedExtensions(leftNavSlot);
const slotName = leftNavSlot && leftNavItems.length > 0 ? leftNavSlot : defaultNavSlot;

return (
<SideNav ref={ref} expanded aria-label="Left navigation" className={styles.leftNav} {...props}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import { useOnClickOutside } from '@openmrs/esm-framework';
import { LeftNavMenu } from '../left-nav';
import { LeftNavMenu } from '../left-nav/left-nav.component';

interface SideMenuPanelProps {
expanded: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import classNames from 'classnames';
import { HeaderContainer, Header, HeaderMenuButton, HeaderGlobalBar, HeaderGlobalAction } from '@carbon/react';
import { Close, Switcher, UserAvatarFilledAlt } from '@carbon/react/icons';
import {
useLayoutType,
ExtensionSlot,
ConfigurableLink,
useSession,
getActiveAppNames,
useConnectedExtensions,
useConfig,
useStore,
} from '@openmrs/esm-framework';
import { leftNavStore } from '@openmrs/esm-framework/src/internal';
import { useTranslation } from 'react-i18next';
import { isDesktop } from '../../utils';
import AppMenuPanel from '../navbar-header-panels/app-menu-panel.component';
import Logo from '../logo/logo.component';
Expand All @@ -21,17 +20,18 @@ import OfflineBanner from '../offline-banner/offline-banner.component';
import UserMenuPanel from '../navbar-header-panels/user-menu-panel.component';
import SideMenuPanel from '../navbar-header-panels/side-menu-panel.component';
import styles from './navbar.scss';
import { useTranslation } from 'react-i18next';
import { LeftNavMenu } from '../left-nav';
import { LeftNavMenu } from '../left-nav/left-nav.component';

const HeaderItems: React.FC = () => {
const { t } = useTranslation();
const config = useConfig();
const [activeHeaderPanel, setActiveHeaderPanel] = useState<string>(null);
const layout = useLayoutType();
const appMenuItems = useConnectedExtensions('app-menu-slot');
const { slotName: leftNavSlot } = useStore(leftNavStore);
const activePages = getActiveAppNames();
const leftNavSlot = activePages && activePages.length > 0 ? `${activePages[0]}-dashboard-slot` : undefined;
const leftNavItems = useConnectedExtensions(leftNavSlot);
const defaultNavItems = useConnectedExtensions('default-dashboard-slot');
const userMenuItems = useConnectedExtensions('user-panel-slot');
const isActivePanel = useCallback((panelName: string) => activeHeaderPanel === panelName, [activeHeaderPanel]);

Expand All @@ -46,15 +46,21 @@ const HeaderItems: React.FC = () => {
[],
);

const showLeftNav = useMemo(() => isDesktop(layout) && leftNavItems.length > 0, [leftNavItems.length, layout]);
const showHamburger = useMemo(() => !isDesktop(layout) && leftNavItems.length > 0, [leftNavItems.length, layout]);
const showLeftNav = useMemo(
() => isDesktop(layout) && (leftNavItems.length > 0 || defaultNavItems.length > 0),
[leftNavItems.length, defaultNavItems.length, layout],
);
const showHamburgerMenu = useMemo(
() => !isDesktop(layout) && (leftNavItems.length > 0 || defaultNavItems.length > 0),
[leftNavItems.length, defaultNavItems.length, layout],
);
const showAppMenu = useMemo(() => appMenuItems.length > 0, [appMenuItems.length]);
const showUserMenu = useMemo(() => userMenuItems.length > 0, [userMenuItems.length]);
return (
<>
<OfflineBanner />
<Header aria-label="OpenMRS" className={styles.topNavHeader}>
{showHamburger && (
{showHamburgerMenu && (
<HeaderMenuButton
aria-label="Open menu"
isCollapsible
Expand All @@ -66,7 +72,7 @@ const HeaderItems: React.FC = () => {
/>
)}
<ConfigurableLink to={config.logo.link}>
<div className={showHamburger ? '' : styles.spacedLogo}>
<div className={showHamburgerMenu ? '' : styles.spacedLogo}>
<Logo />
</div>
</ConfigurableLink>
Expand Down Expand Up @@ -117,7 +123,7 @@ const HeaderItems: React.FC = () => {
</HeaderGlobalAction>
)}
</HeaderGlobalBar>
{showHamburger && <SideMenuPanel hidePanel={hidePanel('sideMenu')} expanded={isActivePanel('sideMenu')} />}
{showHamburgerMenu && <SideMenuPanel hidePanel={hidePanel('sideMenu')} expanded={isActivePanel('sideMenu')} />}
{showAppMenu && <AppMenuPanel expanded={isActivePanel('appMenu')} hidePanel={hidePanel('appMenu')} />}
<NotificationsMenuPanel expanded={isActivePanel('notificationsMenu')} />
{showUserMenu && <UserMenuPanel expanded={isActivePanel('userMenu')} hidePanel={hidePanel('userMenu')} />}
Expand Down
4 changes: 2 additions & 2 deletions packages/framework/esm-extensions/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/** @module @category Extension */
import isEqual from 'lodash-es/isEqual';
import type { ConfigExtensionStoreElement, ConfigObject, ExtensionSlotConfigObject } from '@openmrs/esm-config';
import { type Loadable } from '@openmrs/esm-globals';
import { configExtensionStore } from '@openmrs/esm-config';
import { createGlobalStore, getGlobalStore } from '@openmrs/esm-state';
import type { LifeCycles } from 'single-spa';

export interface ExtensionMeta {
[_: string]: any;
}

export interface ExtensionRegistration {
name: string;
load(): Promise<{ default?: LifeCycles } & LifeCycles>;
load: Loadable;
moduleName: string;
meta: ExtensionMeta;
order?: number;
Expand Down
Loading

0 comments on commit 6a8246f

Please sign in to comment.