Ajout d’un panneau gauche
Le panneau gauche permet de naviguer dans une app O3. Il est basé sur le UI shell left panel de Carbon et se place sous l’en-tête, fixé au bord gauche de la page.
Ce guide utilise l’application Bed Management du monorepo O3 Patient Management comme implémentation de référence. Bed Management contient plusieurs écrans liés, ce qui en fait un bon exemple d’utilisation d’un panneau gauche au niveau d’une app.
Exemple: ajouter un panneau gauche à l’app Bed Management
L’app Bed Management contient les écrans suivants:
- Un écran d’accueil qui résume les lits par emplacement.
- Un écran de détail pour un emplacement spécifique.
- Un écran d’administration pour l’allocation des lits.
- Des écrans d’administration pour les types de lits et les étiquettes de lits.
Le panneau gauche expose ces liens:
Summarypour l’écran d’accueil et l’écran de détail d’un emplacement.Bed allocationpour l’administration des lits.Bed typespour l’administration des types de lits.Bed tagspour l’administration des étiquettes de lits.
Voici une capture d’écran de l’app:
Pour obtenir ce résultat, suivez les étapes ci-dessous:
Étape 1: Enregistrer le panneau gauche depuis la racine de page
Commencez par mettre à jour le composant racine de l’app qui configure le routage:
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { useLeftNav, WorkspaceContainer } from "@openmrs/esm-framework";
import BedAdministrationTable from "./bed-administration/bed-administration-table.component";
import BedTagAdministrationTable from "./bed-tag/bed-tag-administration-table.component";
import BedTypeAdministrationTable from "./bed-type/bed-type-administration-table.component";
import Home from "./home.component";
import LeftPanel from "./left-panel/left-panel.component";
import WardWithBeds from "./ward-with-beds/ward-with-beds.component";
import styles from "./root.scss";
function Root() {
const spaBasePath = window.spaBase;
const bedManagementBasename = window.getOpenmrsSpaBase() + "bed-management";
useLeftNav({ name: "bed-management-left-panel-slot", basePath: spaBasePath });
return (
<BrowserRouter basename={bedManagementBasename}>
<LeftPanel />
<main className={styles.container}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/location/:location" element={<WardWithBeds />} />
<Route path="/bed-administration" element={<BedAdministrationTable />} />
<Route path="/bed-tags" element={<BedTagAdministrationTable />} />
<Route path="/bed-types" element={<BedTypeAdministrationTable />} />
</Routes>
</main>
<WorkspaceContainer contextKey="bed-management" />
</BrowserRouter>
);
}
export default Root;Points importants:
useLeftNav()enregistre le slot de navigation gauche actif tant que la page est montée, puis le désenregistre au démontage. Utilisez ce hook dans les composants de page, pas dans les composants d’extension.nameest le slot d’extension qui recevra les liens du panneau gauche. Le même nom de slot est utilisé dansroutes.json.basePathest le chemin de base de la SPA,/openmrs/spapar défaut.- L’app rend son propre composant
LeftPanelau lieu de rendreLeftNavMenudirectement. L’utilisation directe deLeftNavMenuen dehors de l’en-tête du shell est dépréciée dans le framework. WorkspaceContainergarde les workspaces de Bed Management dans le contexte de cette page.
Étape 2: Rendre une SideNav Carbon avec un slot d’extension
Créez un composant LeftPanel qui s’affiche sur les layouts desktop et fournit le slot dans lequel les extensions de liens seront rendues:
import React from "react";
import { useTranslation } from "react-i18next";
import { SideNav } from "@carbon/react";
import { attach, ExtensionSlot, isDesktop, useLayoutType } from "@openmrs/esm-framework";
import styles from "./left-panel.scss";
attach("nav-menu-slot", "bed-management-left-panel");
function LeftPanel() {
const { t } = useTranslation();
const layout = useLayoutType();
return (
isDesktop(layout) && (
<SideNav
aria-label={t("bedManagementLeftPanel", "Bed management left panel")}
className={styles.leftPanel}
expanded
>
<ExtensionSlot name="bed-management-left-panel-slot" />
</SideNav>
)
);
}
export default LeftPanel;Le nom de ExtensionSlot doit correspondre au slot enregistré avec useLeftNav() et au slot utilisé par les extensions de liens dans routes.json.
Étape 3: Câbler la page racine
Exportez le composant racine depuis index.ts et enregistrez le schéma de configuration pendant le démarrage:
import { defineConfigSchema, getAsyncLifecycle } from "@openmrs/esm-framework";
import { configSchema } from "./config-schema";
const moduleName = "@openmrs/esm-bed-management-app";
const options = {
featureName: "bed-management",
moduleName,
};
export const importTranslation = require.context("../translations", false, /.json$/, "lazy");
export function startupApp() {
defineConfigSchema(moduleName, configSchema);
}
export const root = getAsyncLifecycle(() => import("./root.component"), options);Ajoutez ensuite la route de page dans routes.json:
{
"$schema": "https://json.openmrs.org/routes.schema.json",
"backendDependencies": {
"fhir2": ">=1.2",
"webservices.rest": ">=2.2.0"
},
"pages": [
{
"component": "root",
"route": "bed-management"
}
]
}Cette définition indique à O3 de rendre le lifecycle root lorsque vous naviguez vers /openmrs/spa/bed-management.
Étape 4: Ajouter les liens au panneau gauche
Créez un export de lifecycle pour chaque lien:
import { getSyncLifecycle } from "@openmrs/esm-framework";
import { createLeftPanelLink } from "./left-panel-link.component";
export const summaryLeftPanelLink = getSyncLifecycle(
createLeftPanelLink({
name: "bed-management",
// t("summary", "Summary")
title: "Summary",
}),
options
);
export const adminLeftPanelLink = getSyncLifecycle(
createLeftPanelLink({
name: "bed-administration",
// t("bedAllocation", "Bed allocation")
title: "Bed allocation",
}),
options
);
export const bedTypeLeftPanelLink = getSyncLifecycle(
createLeftPanelLink({
name: "bed-types",
// t("bedTypes", "Bed types")
title: "Bed types",
}),
options
);
export const bedTagLeftPanelLink = getSyncLifecycle(
createLeftPanelLink({
name: "bed-tags",
// t("bedTags", "Bed tags")
title: "Bed tags",
}),
options
);Conservez les commentaires t() près des titres statiques afin que l’extraction des traductions puisse les trouver. Si un lien doit utiliser une traduction à l’exécution, gérez useTranslation() dans le composant de lien rendu plutôt que dans getSyncLifecycle().
Le helper createLeftPanelLink rend un ConfigurableLink et le marque comme actif lorsque son name correspond au segment courant de l’URL:
import React, { useMemo } from "react";
import classNames from "classnames";
import { last } from "lodash-es";
import { BrowserRouter, useLocation } from "react-router-dom";
import { ConfigurableLink } from "@openmrs/esm-framework";
export interface LinkConfig {
name: string;
title: string;
}
function LinkExtension({ config }: { config: LinkConfig }) {
const { name, title } = config;
const location = useLocation();
let urlSegment = useMemo(() => decodeURIComponent(last(location.pathname.split("/"))), [location.pathname]);
const isUUID = (value) => {
const regex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
return regex.test(value);
};
if (isUUID(urlSegment)) {
urlSegment = "bed-management";
}
return (
<ConfigurableLink
to={`${window.getOpenmrsSpaBase()}bed-management${name && name !== "bed-management" ? `/${name}` : ""}`}
className={classNames("cds--side-nav__link", name === urlSegment && "active-left-nav-link")}
>
{title}
</ConfigurableLink>
);
}
export const createLeftPanelLink = (config: LinkConfig) => () => (
<BrowserRouter>
<LinkExtension config={config} />
</BrowserRouter>
);Lorsque le dernier segment de l’URL est un UUID d’emplacement, le helper traite la section courante comme bed-management afin que le lien Summary reste actif sur les pages de détail.
Étape 5: Ajouter les extensions de liens à routes.json
Ajoutez les exports de liens au tableau extensions:
"extensions": [
{
"component": "adminCardLink",
"name": "bed-management-admin-card-link",
"slot": "system-admin-page-card-link-slot"
},
{
"component": "adminLeftPanelLink",
"name": "bed-administration-left-panel-link",
"slot": "bed-management-left-panel-slot"
},
{
"component": "bedTypeLeftPanelLink",
"name": "bed-type-left-panel-link",
"slot": "bed-management-left-panel-slot"
},
{
"component": "bedTagLeftPanelLink",
"name": "bed-tag-left-panel-link",
"slot": "bed-management-left-panel-slot"
},
{
"component": "summaryLeftPanelLink",
"name": "bed-management-home-dashboard-link",
"slot": "bed-management-left-panel-slot",
"order": 0
}
]Étape 6: Essayer le résultat
Naviguez vers /openmrs/spa/bed-management. Vous devriez voir l’écran d’accueil de Bed Management avec le panneau gauche:

Cliquer sur une carte d’emplacement ouvre une page de détail et garde le lien Summary actif:

Cliquer sur Bed allocation ouvre la page d’administration:
