@egen-civitas/esm-extensions 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/nav-entry.d.ts +19 -5
- package/dist/nav-entry.d.ts.map +1 -1
- package/dist/nav-entry.js +18 -3
- package/dist/public.d.ts +3 -1
- package/dist/public.d.ts.map +1 -1
- package/dist/public.js +3 -1
- package/dist/staggered-menu-registration.d.ts +27 -0
- package/dist/staggered-menu-registration.d.ts.map +1 -0
- package/dist/staggered-menu-registration.js +27 -0
- package/dist/staggered-menu-slot.d.ts +99 -0
- package/dist/staggered-menu-slot.d.ts.map +1 -0
- package/dist/staggered-menu-slot.js +93 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @egen-civitas/esm-extensions
|
|
2
2
|
|
|
3
|
+
## 2.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3d304d5: Slot de navigation de la TopBar sans numéro de niveau : nouvelle constante `TOPBAR_NAV_SLOT` (`topbar-nav-slot`) et `TOPBAR_NAV_SLOTS` (tous les noms à lire, officiel d'abord). `TOPBAR_LEVEL2_NAV_SLOT` (`topbar-level2-nav`) est conservée, marquée `@deprecated`, et reste honorée : `SectionNavPanel` lit les deux slots (sans doublon). Les apps migrent leur `routes.json` vers le nouveau nom quand elles veulent ; aucune rupture.
|
|
8
|
+
|
|
9
|
+
## 2.3.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 0afcb05: `StaggeredMenuPanel` accepte des composants libres posés par les apps, comme les rails. Nouveau slot `staggered-menu-slot` (`STAGGERED_MENU_SLOT`) : une extension y déclare dans sa `meta` sa zone (`top`, `content`, `bottom`), son `order`, sa `priority`, `global` (visible quelle que soit l'app active ; sinon seulement quand son app est montée), `showTitle`, `titleKey`. Nouveaux exports : `registerStaggeredMenuEntry` (déclaration par le code), `resolveStaggeredMenuEntries`, `isStaggeredMenuEntryMeta`, `getStaggeredMenuEntryProblems`, `useStaggeredMenuEntries` et les types associés. Nouvelles props du panneau : `extensionSlot` (slot dédié ou `false`) et `maxExtensions` (limite par priorité). Le contenu est chargé à la première ouverture ; chaque composant reçoit `closeMenu`, `position` et `isOpen` en props ; un clic dans un menu/dialogue ouvert par un composant ne ferme plus le panneau (`closeOnClickAway`) ; le panneau fermé est `inert`. Aucun changement pour les usages existants.
|
|
14
|
+
|
|
3
15
|
## 2.2.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export * from './helpers.js';
|
|
|
3
3
|
export * from './nav-entry.js';
|
|
4
4
|
export * from './tool-window.js';
|
|
5
5
|
export * from './tool-window-registration.js';
|
|
6
|
+
export * from './staggered-menu-slot.js';
|
|
7
|
+
export * from './staggered-menu-registration.js';
|
|
6
8
|
export * from './nav-behavior.js';
|
|
7
9
|
export * from './modals.js';
|
|
8
10
|
export * from './workspaces.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@ export * from "./helpers.js";
|
|
|
3
3
|
export * from "./nav-entry.js";
|
|
4
4
|
export * from "./tool-window.js";
|
|
5
5
|
export * from "./tool-window-registration.js";
|
|
6
|
+
export * from "./staggered-menu-slot.js";
|
|
7
|
+
export * from "./staggered-menu-registration.js";
|
|
6
8
|
export * from "./nav-behavior.js";
|
|
7
9
|
export * from "./modals.js";
|
|
8
10
|
export * from "./workspaces.js";
|
package/dist/nav-entry.d.ts
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
/** @module @category Extension */
|
|
2
2
|
/**
|
|
3
|
-
* Nom du slot sur lequel chaque app déclare ses entrées de navigation
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Nom du slot sur lequel chaque app déclare ses entrées de navigation de la TopBar. Déclaré dans le
|
|
4
|
+
* `routes.json` de l'app : `{ "slot": "topbar-nav-slot", "component": "navEntry", "meta": NavEntryMeta }`.
|
|
5
|
+
*
|
|
6
|
+
* Le nom ne désigne aucun niveau : la TopBar est une pile de N niveaux et la navigation peut être placée dans
|
|
7
|
+
* n'importe lequel (c'est la config de la TopBar qui décide).
|
|
8
|
+
*/
|
|
9
|
+
export declare const TOPBAR_NAV_SLOT = "topbar-nav-slot";
|
|
10
|
+
/**
|
|
11
|
+
* Ancien nom du slot de navigation (`topbar-level2-nav`), de l'époque où la TopBar n'avait que deux niveaux.
|
|
12
|
+
* Toujours honoré pour les apps déjà déployées.
|
|
13
|
+
*
|
|
14
|
+
* @deprecated Déclarer les entrées sur {@link TOPBAR_NAV_SLOT}.
|
|
6
15
|
*/
|
|
7
16
|
export declare const TOPBAR_LEVEL2_NAV_SLOT = "topbar-level2-nav";
|
|
8
17
|
/**
|
|
9
|
-
*
|
|
18
|
+
* Tous les noms de slot de navigation, le nom officiel d'abord. Un lecteur (TopBar, panneau de section…) doit
|
|
19
|
+
* les lire TOUS et fusionner les entrées, tant que des apps déclarent encore l'ancien nom.
|
|
20
|
+
*/
|
|
21
|
+
export declare const TOPBAR_NAV_SLOTS: readonly string[];
|
|
22
|
+
/**
|
|
23
|
+
* Métadonnées d'une entrée de navigation de la TopBar.
|
|
10
24
|
* Partagé par les apps (qui le déclarent dans `meta`) et par la TopBar
|
|
11
|
-
* (qui le lit
|
|
25
|
+
* (qui le lit sur tous les slots de {@link TOPBAR_NAV_SLOTS}).
|
|
12
26
|
*/
|
|
13
27
|
export interface NavEntryMeta {
|
|
14
28
|
/** Entrée de niveau 2 (ex. `informations`) ; regroupe les colonnes du méga-menu. */
|
package/dist/nav-entry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-entry.d.ts","sourceRoot":"","sources":["../src/nav-entry.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC
|
|
1
|
+
{"version":3,"file":"nav-entry.d.ts","sourceRoot":"","sources":["../src/nav-entry.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAA8C,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2GAA2G;IAC3G,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,YAAY,CAelE;AAED,wGAAwG;AACxG,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAItF"}
|
package/dist/nav-entry.js
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
/** @module @category Extension */ /**
|
|
2
|
-
* Nom du slot sur lequel chaque app déclare ses entrées de navigation
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Nom du slot sur lequel chaque app déclare ses entrées de navigation de la TopBar. Déclaré dans le
|
|
3
|
+
* `routes.json` de l'app : `{ "slot": "topbar-nav-slot", "component": "navEntry", "meta": NavEntryMeta }`.
|
|
4
|
+
*
|
|
5
|
+
* Le nom ne désigne aucun niveau : la TopBar est une pile de N niveaux et la navigation peut être placée dans
|
|
6
|
+
* n'importe lequel (c'est la config de la TopBar qui décide).
|
|
7
|
+
*/ export const TOPBAR_NAV_SLOT = 'topbar-nav-slot';
|
|
8
|
+
/**
|
|
9
|
+
* Ancien nom du slot de navigation (`topbar-level2-nav`), de l'époque où la TopBar n'avait que deux niveaux.
|
|
10
|
+
* Toujours honoré pour les apps déjà déployées.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated Déclarer les entrées sur {@link TOPBAR_NAV_SLOT}.
|
|
5
13
|
*/ export const TOPBAR_LEVEL2_NAV_SLOT = 'topbar-level2-nav';
|
|
14
|
+
/**
|
|
15
|
+
* Tous les noms de slot de navigation, le nom officiel d'abord. Un lecteur (TopBar, panneau de section…) doit
|
|
16
|
+
* les lire TOUS et fusionner les entrées, tant que des apps déclarent encore l'ancien nom.
|
|
17
|
+
*/ export const TOPBAR_NAV_SLOTS = [
|
|
18
|
+
TOPBAR_NAV_SLOT,
|
|
19
|
+
TOPBAR_LEVEL2_NAV_SLOT
|
|
20
|
+
];
|
|
6
21
|
/** Valeur de `NavEntryMeta.workspaces` qui désigne « tous les espaces ». */ export const NAV_ALL_WORKSPACES = '*';
|
|
7
22
|
/** Valide une `meta` d'extension : vrai si c'est une `NavEntryMeta` exploitable. */ export function isNavEntryMeta(meta) {
|
|
8
23
|
if (!meta || typeof meta !== 'object') return false;
|
package/dist/public.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ export { type CancelLoading, renderExtension } from './render.js';
|
|
|
3
3
|
export { type ExtensionMeta, type ExtensionRegistration, type ExtensionStore, type AssignedExtension, type ConnectedExtension, type ExtensionSlotState, getExtensionStore, } from './store.js';
|
|
4
4
|
export { type WorkspaceRegistration } from './workspaces.js';
|
|
5
5
|
export { type ExtensionData, type ComponentConfig } from './types.js';
|
|
6
|
-
export { TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, type NavEntryMeta, isNavEntryMeta, isNavEntryInWorkspace, } from './nav-entry.js';
|
|
6
|
+
export { TOPBAR_NAV_SLOT, TOPBAR_NAV_SLOTS, TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, type NavEntryMeta, isNavEntryMeta, isNavEntryInWorkspace, } from './nav-entry.js';
|
|
7
7
|
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, type ToolWindowAnchor, type ToolWindowMeta, isToolWindowMeta, isToolWindowSlot, isSafeToolWindowIconUrl, getToolWindowMetaProblems, getToolWindowCompartment, DEFAULT_COMPARTMENT_HEIGHTS, type ToolWindowCompartment, type ResolvedToolWindowCompartment, } from './tool-window.js';
|
|
8
8
|
export { registerToolWindow, type ToolWindowRegistration } from './tool-window-registration.js';
|
|
9
|
+
export { STAGGERED_MENU_SLOT, STAGGERED_MENU_AREAS, DEFAULT_STAGGERED_MENU_AREA, type StaggeredMenuArea, type StaggeredMenuEntryMeta, type StaggeredMenuAssignedExtension, type ResolvedStaggeredMenuEntry, type ResolveStaggeredMenuEntriesOptions, isStaggeredMenuArea, isStaggeredMenuEntryMeta, getStaggeredMenuEntryProblems, resolveStaggeredMenuEntries, } from './staggered-menu-slot.js';
|
|
10
|
+
export { registerStaggeredMenuEntry, type StaggeredMenuEntryRegistration } from './staggered-menu-registration.js';
|
|
9
11
|
export { type NavBehavior, type NavBehaviorTarget, type NavSelectContext, registerNavBehavior, getNavBehavior, } from './nav-behavior.js';
|
|
10
12
|
//# sourceMappingURL=public.d.ts.map
|
package/dist/public.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,MAAM,EACN,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,cAAc,EACd,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,GACnC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,EAC3B,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EACnC,KAAK,0BAA0B,EAC/B,KAAK,kCAAkC,EACvC,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,KAAK,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AACnH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
|
package/dist/public.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { getExtensionNameFromId, registerExtension, attach, detach, detachAll, getAssignedExtensions, registerExtensionSlot } from "./extensions.js";
|
|
2
2
|
export { renderExtension } from "./render.js";
|
|
3
3
|
export { getExtensionStore } from "./store.js";
|
|
4
|
-
export { TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, isNavEntryMeta, isNavEntryInWorkspace } from "./nav-entry.js";
|
|
4
|
+
export { TOPBAR_NAV_SLOT, TOPBAR_NAV_SLOTS, TOPBAR_LEVEL2_NAV_SLOT, NAV_ALL_WORKSPACES, isNavEntryMeta, isNavEntryInWorkspace } from "./nav-entry.js";
|
|
5
5
|
export { SHELL_RAIL_LEFT_SLOT, SHELL_RAIL_BOTTOM_SLOT, SHELL_RAIL_RIGHT_SLOT, TOOL_WINDOW_SLOTS, isToolWindowMeta, isToolWindowSlot, isSafeToolWindowIconUrl, getToolWindowMetaProblems, getToolWindowCompartment, DEFAULT_COMPARTMENT_HEIGHTS } from "./tool-window.js";
|
|
6
6
|
export { registerToolWindow } from "./tool-window-registration.js";
|
|
7
|
+
export { STAGGERED_MENU_SLOT, STAGGERED_MENU_AREAS, DEFAULT_STAGGERED_MENU_AREA, isStaggeredMenuArea, isStaggeredMenuEntryMeta, getStaggeredMenuEntryProblems, resolveStaggeredMenuEntries } from "./staggered-menu-slot.js";
|
|
8
|
+
export { registerStaggeredMenuEntry } from "./staggered-menu-registration.js";
|
|
7
9
|
export { registerNavBehavior, getNavBehavior } from "./nav-behavior.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ExtensionRegistration } from './store.js';
|
|
2
|
+
import { type StaggeredMenuEntryMeta } from './staggered-menu-slot.js';
|
|
3
|
+
export interface StaggeredMenuEntryRegistration {
|
|
4
|
+
/** Nom du module (de l'app) qui porte le composant : celui de l'importmap / de la fédération. */
|
|
5
|
+
moduleName: string;
|
|
6
|
+
/** Identifiant unique de l'entrée (nom de l'extension). */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Zone, ordre, priorité et portée de l'entrée. */
|
|
9
|
+
meta: StaggeredMenuEntryMeta;
|
|
10
|
+
/** Chargement du composant (cycles de vie single-spa), appelé quand le panneau s'ouvre pour la première fois. */
|
|
11
|
+
load: ExtensionRegistration['load'];
|
|
12
|
+
/**
|
|
13
|
+
* Slot visé. Défaut : `STAGGERED_MENU_SLOT`. À renseigner pour viser un panneau qui a son propre slot
|
|
14
|
+
* (prop `extensionSlot` de `StaggeredMenuPanel`).
|
|
15
|
+
*/
|
|
16
|
+
slot?: string;
|
|
17
|
+
privileges?: ExtensionRegistration['privileges'];
|
|
18
|
+
featureFlag?: string;
|
|
19
|
+
displayExpression?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Ajoute un composant libre au `StaggeredMenuPanel` par le code, sans `routes.json` : pour une app fédérée
|
|
23
|
+
* ou open source qui s'intègre depuis son point d'entrée. Équivalent exact d'une extension `routes.json`
|
|
24
|
+
* posée sur le slot du panneau. Retourne `false` (et avertit) si la `meta` est invalide.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerStaggeredMenuEntry(registration: StaggeredMenuEntryRegistration): boolean;
|
|
27
|
+
//# sourceMappingURL=staggered-menu-registration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staggered-menu-registration.d.ts","sourceRoot":"","sources":["../src/staggered-menu-registration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,8BAA8B;IAC7C,iGAAiG;IACjG,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,IAAI,EAAE,sBAAsB,CAAC;IAC7B,iHAAiH;IACjH,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,8BAA8B,GAAG,OAAO,CAiChG"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @module @category Extension */ import { attach, registerExtension } from "./extensions.js";
|
|
2
|
+
import { getStaggeredMenuEntryProblems, STAGGERED_MENU_SLOT } from "./staggered-menu-slot.js";
|
|
3
|
+
/**
|
|
4
|
+
* Ajoute un composant libre au `StaggeredMenuPanel` par le code, sans `routes.json` : pour une app fédérée
|
|
5
|
+
* ou open source qui s'intègre depuis son point d'entrée. Équivalent exact d'une extension `routes.json`
|
|
6
|
+
* posée sur le slot du panneau. Retourne `false` (et avertit) si la `meta` est invalide.
|
|
7
|
+
*/ export function registerStaggeredMenuEntry(registration) {
|
|
8
|
+
const { moduleName, name, meta, load, slot = STAGGERED_MENU_SLOT, privileges, featureFlag, displayExpression } = registration;
|
|
9
|
+
const problems = getStaggeredMenuEntryProblems(meta);
|
|
10
|
+
if (problems.length > 0 || !slot) {
|
|
11
|
+
console.warn(`[staggered-menu] L'entrée « ${name} » de ${moduleName} n'est pas enregistrée : ${problems.join(' ; ') || 'slot vide'}.`);
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
registerExtension({
|
|
15
|
+
name,
|
|
16
|
+
moduleName,
|
|
17
|
+
load,
|
|
18
|
+
meta,
|
|
19
|
+
privileges,
|
|
20
|
+
featureFlag,
|
|
21
|
+
displayExpression,
|
|
22
|
+
online: true,
|
|
23
|
+
offline: false
|
|
24
|
+
});
|
|
25
|
+
attach(slot, name);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/** @module @category Extension */
|
|
2
|
+
/**
|
|
3
|
+
* Extensions du `StaggeredMenuPanel`.
|
|
4
|
+
*
|
|
5
|
+
* Le panneau latéral animé du styleguide accepte des composants libres posés par les apps, de la même
|
|
6
|
+
* façon que les rails du shell (voir `tool-window.ts`) : une app déclare une **extension** sur le slot
|
|
7
|
+
* `staggered-menu-slot` et indique, dans sa `meta`, où, dans quel ordre et avec quelle priorité elle
|
|
8
|
+
* s'affiche.
|
|
9
|
+
*
|
|
10
|
+
* Déclaration dans le `routes.json` d'une app :
|
|
11
|
+
* `{ "slot": "staggered-menu-slot", "component": "monWidget", "meta": StaggeredMenuEntryMeta }`.
|
|
12
|
+
*
|
|
13
|
+
* Comme pour les rails, une entrée n'apparaît que lorsque son app est montée (une de ses pages est
|
|
14
|
+
* active), sauf si elle déclare `meta.global: true`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const STAGGERED_MENU_SLOT = "staggered-menu-slot";
|
|
17
|
+
/**
|
|
18
|
+
* Zones du panneau qui accueillent des extensions, dans l'ordre d'affichage :
|
|
19
|
+
*
|
|
20
|
+
* `top` avant la liste des liens de navigation
|
|
21
|
+
* `content` juste après la liste des liens (zone par défaut)
|
|
22
|
+
* `bottom` en pied de panneau, après le bloc de liens sociaux
|
|
23
|
+
*/
|
|
24
|
+
export declare const STAGGERED_MENU_AREAS: readonly ["top", "content", "bottom"];
|
|
25
|
+
export type StaggeredMenuArea = (typeof STAGGERED_MENU_AREAS)[number];
|
|
26
|
+
/** Zone utilisée quand `meta.area` est absent. */
|
|
27
|
+
export declare const DEFAULT_STAGGERED_MENU_AREA: StaggeredMenuArea;
|
|
28
|
+
/** Métadonnées d'une extension du panneau (titre accessible, zone, ordre, priorité, portée). */
|
|
29
|
+
export interface StaggeredMenuEntryMeta {
|
|
30
|
+
/** Titre : nom accessible de la section et, avec `showTitle`, intitulé visible au-dessus du composant. */
|
|
31
|
+
title: string;
|
|
32
|
+
/** Clé de traduction du titre (optionnelle), cherchée dans le module de l'app. */
|
|
33
|
+
titleKey?: string;
|
|
34
|
+
/** Zone du panneau où s'affiche le composant (défaut `content`). */
|
|
35
|
+
area?: StaggeredMenuArea;
|
|
36
|
+
/**
|
|
37
|
+
* Position dans la zone (ordre croissant). Absent : ordre d'enregistrement du slot. Comme pour les rails,
|
|
38
|
+
* deux entrées de même `order` sont départagées par `priority` puis par l'ordre d'enregistrement.
|
|
39
|
+
*/
|
|
40
|
+
order?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Importance de l'entrée (défaut 0, plus grand = plus important). Sert (1) à départager deux entrées de
|
|
43
|
+
* même `order` : la plus prioritaire passe devant, et (2) à choisir les entrées conservées quand le panneau
|
|
44
|
+
* limite leur nombre (`maxExtensions`) : les moins prioritaires sont écartées.
|
|
45
|
+
*/
|
|
46
|
+
priority?: number;
|
|
47
|
+
/**
|
|
48
|
+
* L'entrée reste affichée quelle que soit l'app active (comme `global` des rails). Absent : elle n'apparaît
|
|
49
|
+
* que lorsqu'une page de son app est montée.
|
|
50
|
+
*/
|
|
51
|
+
global?: boolean;
|
|
52
|
+
/** Affiche `title` comme intitulé visible au-dessus du composant (défaut : non, le composant est libre). */
|
|
53
|
+
showTitle?: boolean;
|
|
54
|
+
}
|
|
55
|
+
/** Vrai si `area` est une zone connue du panneau. */
|
|
56
|
+
export declare function isStaggeredMenuArea(area: unknown): area is StaggeredMenuArea;
|
|
57
|
+
/**
|
|
58
|
+
* Liste précise des problèmes d'une `meta` d'extension du panneau (vide = valide). Une entrée invalide
|
|
59
|
+
* n'apparaît pas : le dire clairement à l'enregistrement évite de chercher pourquoi à l'intégration d'une app.
|
|
60
|
+
*/
|
|
61
|
+
export declare function getStaggeredMenuEntryProblems(meta: unknown): string[];
|
|
62
|
+
/** Valide une `meta` d'extension : vrai si c'est une `StaggeredMenuEntryMeta` exploitable. */
|
|
63
|
+
export declare function isStaggeredMenuEntryMeta(meta: unknown): meta is StaggeredMenuEntryMeta;
|
|
64
|
+
/** Forme minimale d'une extension assignée au slot (compatible avec `AssignedExtension`). */
|
|
65
|
+
export interface StaggeredMenuAssignedExtension {
|
|
66
|
+
name: string;
|
|
67
|
+
moduleName: string;
|
|
68
|
+
meta?: unknown;
|
|
69
|
+
}
|
|
70
|
+
/** Entrée résolue : une extension valide, visible, avec sa zone, son ordre et sa priorité calculés. */
|
|
71
|
+
export interface ResolvedStaggeredMenuEntry<T extends StaggeredMenuAssignedExtension = StaggeredMenuAssignedExtension> {
|
|
72
|
+
/** Nom de l'extension : identifiant de l'entrée dans le panneau. */
|
|
73
|
+
id: string;
|
|
74
|
+
moduleName: string;
|
|
75
|
+
meta: StaggeredMenuEntryMeta;
|
|
76
|
+
area: StaggeredMenuArea;
|
|
77
|
+
order: number;
|
|
78
|
+
priority: number;
|
|
79
|
+
/** Extension d'origine (pour la retrouver dans le slot). */
|
|
80
|
+
extension: T;
|
|
81
|
+
}
|
|
82
|
+
export interface ResolveStaggeredMenuEntriesOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Nombre maximal d'entrées affichées. Au-delà, les moins prioritaires sont écartées (à priorité égale,
|
|
85
|
+
* les premières dans l'ordre d'affichage sont conservées). Absent ou invalide : aucune limite.
|
|
86
|
+
*/
|
|
87
|
+
maxEntries?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Entrées affichables du panneau, dans l'ordre d'affichage.
|
|
91
|
+
*
|
|
92
|
+
* 1. écarte les entrées dont la `meta` est invalide ;
|
|
93
|
+
* 2. écarte celles dont l'app n'est pas montée, sauf `meta.global` ;
|
|
94
|
+
* 3. si `maxEntries` est fixé, ne garde que les plus prioritaires ;
|
|
95
|
+
* 4. trie par zone (`top`, `content`, `bottom`), puis `order` croissant, puis `priority` décroissante,
|
|
96
|
+
* puis ordre d'enregistrement.
|
|
97
|
+
*/
|
|
98
|
+
export declare function resolveStaggeredMenuEntries<T extends StaggeredMenuAssignedExtension>(assigned: readonly T[], activeModules: ReadonlySet<string>, options?: ResolveStaggeredMenuEntriesOptions): ResolvedStaggeredMenuEntry<T>[];
|
|
99
|
+
//# sourceMappingURL=staggered-menu-slot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staggered-menu-slot.d.ts","sourceRoot":"","sources":["../src/staggered-menu-slot.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,uCAAwC,CAAC;AAE1E,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,kDAAkD;AAClD,eAAO,MAAM,2BAA2B,EAAE,iBAA6B,CAAC;AAExE,gGAAgG;AAChG,MAAM,WAAW,sBAAsB;IACrC,0GAA0G;IAC1G,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4GAA4G;IAC5G,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,iBAAiB,CAE5E;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAerE;AAED,8FAA8F;AAC9F,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,sBAAsB,CAEtF;AAED,6FAA6F;AAC7F,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,uGAAuG;AACvG,MAAM,WAAW,0BAA0B,CAAC,CAAC,SAAS,8BAA8B,GAAG,8BAA8B;IACnH,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,SAAS,EAAE,CAAC,CAAC;CACd;AAED,MAAM,WAAW,kCAAkC;IACjD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,8BAA8B,EAClF,QAAQ,EAAE,SAAS,CAAC,EAAE,EACtB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,EAClC,OAAO,GAAE,kCAAuC,GAC/C,0BAA0B,CAAC,CAAC,CAAC,EAAE,CAgDjC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** @module @category Extension */ /**
|
|
2
|
+
* Extensions du `StaggeredMenuPanel`.
|
|
3
|
+
*
|
|
4
|
+
* Le panneau latéral animé du styleguide accepte des composants libres posés par les apps, de la même
|
|
5
|
+
* façon que les rails du shell (voir `tool-window.ts`) : une app déclare une **extension** sur le slot
|
|
6
|
+
* `staggered-menu-slot` et indique, dans sa `meta`, où, dans quel ordre et avec quelle priorité elle
|
|
7
|
+
* s'affiche.
|
|
8
|
+
*
|
|
9
|
+
* Déclaration dans le `routes.json` d'une app :
|
|
10
|
+
* `{ "slot": "staggered-menu-slot", "component": "monWidget", "meta": StaggeredMenuEntryMeta }`.
|
|
11
|
+
*
|
|
12
|
+
* Comme pour les rails, une entrée n'apparaît que lorsque son app est montée (une de ses pages est
|
|
13
|
+
* active), sauf si elle déclare `meta.global: true`.
|
|
14
|
+
*/ export const STAGGERED_MENU_SLOT = 'staggered-menu-slot';
|
|
15
|
+
/**
|
|
16
|
+
* Zones du panneau qui accueillent des extensions, dans l'ordre d'affichage :
|
|
17
|
+
*
|
|
18
|
+
* `top` avant la liste des liens de navigation
|
|
19
|
+
* `content` juste après la liste des liens (zone par défaut)
|
|
20
|
+
* `bottom` en pied de panneau, après le bloc de liens sociaux
|
|
21
|
+
*/ export const STAGGERED_MENU_AREAS = [
|
|
22
|
+
'top',
|
|
23
|
+
'content',
|
|
24
|
+
'bottom'
|
|
25
|
+
];
|
|
26
|
+
/** Zone utilisée quand `meta.area` est absent. */ export const DEFAULT_STAGGERED_MENU_AREA = 'content';
|
|
27
|
+
/** Vrai si `area` est une zone connue du panneau. */ export function isStaggeredMenuArea(area) {
|
|
28
|
+
return typeof area === 'string' && STAGGERED_MENU_AREAS.includes(area);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Liste précise des problèmes d'une `meta` d'extension du panneau (vide = valide). Une entrée invalide
|
|
32
|
+
* n'apparaît pas : le dire clairement à l'enregistrement évite de chercher pourquoi à l'intégration d'une app.
|
|
33
|
+
*/ export function getStaggeredMenuEntryProblems(meta) {
|
|
34
|
+
if (!meta || typeof meta !== 'object') return [
|
|
35
|
+
'`meta` est absente : ajouter au moins { "title": "…" }'
|
|
36
|
+
];
|
|
37
|
+
const m = meta;
|
|
38
|
+
const problems = [];
|
|
39
|
+
if (typeof m.title !== 'string' || m.title.length === 0) problems.push('`title` doit être une chaîne non vide');
|
|
40
|
+
if (m.titleKey !== undefined && typeof m.titleKey !== 'string') problems.push('`titleKey` doit être une chaîne');
|
|
41
|
+
if (m.area !== undefined && !isStaggeredMenuArea(m.area)) problems.push(`\`area\` vaut ${STAGGERED_MENU_AREAS.map((a)=>`"${a}"`).join(', ')}`);
|
|
42
|
+
if (m.order !== undefined && (typeof m.order !== 'number' || !Number.isFinite(m.order))) problems.push('`order` doit être un nombre fini');
|
|
43
|
+
if (m.priority !== undefined && (typeof m.priority !== 'number' || !Number.isFinite(m.priority))) problems.push('`priority` doit être un nombre fini');
|
|
44
|
+
if (m.global !== undefined && typeof m.global !== 'boolean') problems.push('`global` doit être un booléen');
|
|
45
|
+
if (m.showTitle !== undefined && typeof m.showTitle !== 'boolean') problems.push('`showTitle` doit être un booléen');
|
|
46
|
+
return problems;
|
|
47
|
+
}
|
|
48
|
+
/** Valide une `meta` d'extension : vrai si c'est une `StaggeredMenuEntryMeta` exploitable. */ export function isStaggeredMenuEntryMeta(meta) {
|
|
49
|
+
return getStaggeredMenuEntryProblems(meta).length === 0;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Entrées affichables du panneau, dans l'ordre d'affichage.
|
|
53
|
+
*
|
|
54
|
+
* 1. écarte les entrées dont la `meta` est invalide ;
|
|
55
|
+
* 2. écarte celles dont l'app n'est pas montée, sauf `meta.global` ;
|
|
56
|
+
* 3. si `maxEntries` est fixé, ne garde que les plus prioritaires ;
|
|
57
|
+
* 4. trie par zone (`top`, `content`, `bottom`), puis `order` croissant, puis `priority` décroissante,
|
|
58
|
+
* puis ordre d'enregistrement.
|
|
59
|
+
*/ export function resolveStaggeredMenuEntries(assigned, activeModules, options = {}) {
|
|
60
|
+
const areaRank = (area)=>STAGGERED_MENU_AREAS.indexOf(area);
|
|
61
|
+
const visible = assigned.map((extension, index)=>({
|
|
62
|
+
extension,
|
|
63
|
+
index
|
|
64
|
+
})).filter(({ extension })=>isStaggeredMenuEntryMeta(extension.meta)).filter(({ extension })=>extension.meta.global === true || activeModules.has(extension.moduleName)).map(({ extension, index })=>{
|
|
65
|
+
const meta = extension.meta;
|
|
66
|
+
return {
|
|
67
|
+
index,
|
|
68
|
+
entry: {
|
|
69
|
+
id: extension.name,
|
|
70
|
+
moduleName: extension.moduleName,
|
|
71
|
+
meta,
|
|
72
|
+
area: meta.area ?? DEFAULT_STAGGERED_MENU_AREA,
|
|
73
|
+
order: meta.order ?? index,
|
|
74
|
+
priority: meta.priority ?? 0,
|
|
75
|
+
extension
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
const byDisplay = (a, b)=>areaRank(a.entry.area) - areaRank(b.entry.area) || a.entry.order - b.entry.order || b.entry.priority - a.entry.priority || a.index - b.index;
|
|
80
|
+
const sorted = [
|
|
81
|
+
...visible
|
|
82
|
+
].sort(byDisplay);
|
|
83
|
+
const { maxEntries } = options;
|
|
84
|
+
if (typeof maxEntries !== 'number' || !Number.isFinite(maxEntries) || maxEntries < 0 || maxEntries >= sorted.length) {
|
|
85
|
+
return sorted.map(({ entry })=>entry);
|
|
86
|
+
}
|
|
87
|
+
// Les plus prioritaires d'abord ; à priorité égale, celles qui passent en premier à l'affichage.
|
|
88
|
+
const kept = new Set(sorted.map((item, displayIndex)=>({
|
|
89
|
+
item,
|
|
90
|
+
displayIndex
|
|
91
|
+
})).sort((a, b)=>b.item.entry.priority - a.item.entry.priority || a.displayIndex - b.displayIndex).slice(0, Math.floor(maxEntries)).map(({ item })=>item));
|
|
92
|
+
return sorted.filter((item)=>kept.has(item)).map(({ entry })=>entry);
|
|
93
|
+
}
|