@hgdc/ui 0.58.0 → 0.60.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/README.md CHANGED
@@ -112,7 +112,7 @@ Couleurs pleines ; pour éclaircir, mélanger au blanc `color-mix(in oklab, …)
112
112
  - produit : `"build": "hgdc-brand sync mail && vite build"` (et en tête de `dev`), les six fichiers de `family/app/<mot>/` dans `public/`, listés dans le `.gitignore` ; `--email-as <fichier>` y ajoute l'icône d'e-mail du produit sous un ancien nom ;
113
113
  - site hgdc.ch : `hgdc-brand emails public/email`, les `<mot>.png` servis à `EMAIL_ICON_BASE`.
114
114
 
115
- Sur ordinateur, la coque ouvre sur la barre des produits (ADR 0011) : organisation en haut, pastilles des produits ouverts, Account en bas, chacun par son entrée `/auth/hgdc?next=/`, le produit courant en teinte. Au survol (150 ms d'intention) ou au focus clavier, elle s'élargit par-dessus la page et écrit les noms. `productRail={false}` la coupe ; `accountHref` pointe vers un Account local. La barre latérale porte la marque du produit et se réduit en rail (`Ctrl+B`, mémorisé) : poser `sidebarInitScript` dans le `<head>`. En rail, la pastille du produit devient le bouton « Déplier » au survol. Le kit ne connaît ni routeur ni authentification : liens par `render={<Link />}`, actions par callbacks. Rôles d'organisation : `owner`, `admin`, `member` (Propriétaire, Admin, Membre).
115
+ Sur ordinateur, la coque ouvre sur la barre des produits (ADR 0011) : organisation en haut, Manager en tête puis pastilles des produits ouverts, chacun par son entrée `/auth/hgdc?next=/`, le produit courant en teinte. Au survol (150 ms d'intention) ou au focus clavier, elle s'élargit par-dessus la page et écrit les noms. `productRail={false}` la coupe ; `accountHref` pointe vers un Manager local. La barre latérale porte la marque du produit et se réduit en rail (`Ctrl+B`, mémorisé) : poser `sidebarInitScript` dans le `<head>`. En rail, la pastille du produit devient le bouton « Déplier » au survol. Le kit ne connaît ni routeur ni authentification : liens par `render={<Link />}`, actions par callbacks. Rôles d'organisation : `owner`, `admin`, `member` (Propriétaire, Admin, Membre).
116
116
 
117
117
  ## Contenu et données
118
118
 
package/dist/app-shell.js CHANGED
@@ -16,7 +16,7 @@ import { AssistantButton, AssistantPanel, ASSISTANT_SIDE_BY_SIDE, useAssistantSh
16
16
  import { ShellContext } from "./shell-context.js";
17
17
  import { familyProductName } from "./shell-frame.js";
18
18
  import { OtherViewLink, ShellCommonLinks } from "./shell-links.js";
19
- import { rememberShellNavHeight } from "./shell-memory.js";
19
+ import { rememberLastProduct, rememberShellNavHeight } from "./shell-memory.js";
20
20
  import { ProductRailShownContext, ShellLeaveContext, StatusPageContext } from "./shell-placement.js";
21
21
  import { SidebarHead } from "./sidebar-head.js";
22
22
  import { useToggleShortcut } from "./sidebar-rail.js";
@@ -73,6 +73,7 @@ export function AppShell({ product, organization, productRail: productRailOption
73
73
  // barre latérale à la prochaine arrivée sur ce produit.
74
74
  useIsomorphicLayoutEffect(() => {
75
75
  document.documentElement.dataset.hgdcProduct = product;
76
+ rememberLastProduct(product);
76
77
  }, [product]);
77
78
  const navHeight = useRef(0);
78
79
  useEffect(() => {
@@ -73,6 +73,8 @@ export declare function productEntryHref(word: string, origins?: Readonly<Record
73
73
  */
74
74
  export declare const PRODUCT_ENTRY_REFRESH_QUERY = "refresh=background&next=/";
75
75
  export declare const HGDC_ACCOUNT: HgdcCatalogProduct;
76
+ /** Manager : les organisations, leurs membres et leurs rôles. En tête du menu et de la barre des produits. */
77
+ export declare const HGDC_MANAGER: HgdcCatalogProduct;
76
78
  /** Les produits de la famille, dans leur ordre d'affichage. Account n'en fait pas partie (`HGDC_ACCOUNT`). */
77
79
  export declare const HGDC_PRODUCTS: ReadonlyArray<HgdcCatalogProduct>;
78
80
  /** Vrai si le produit répond déjà (en service ou en préversion). */
@@ -90,9 +92,9 @@ export type ProductMenuEntry = {
90
92
  hint?: string;
91
93
  };
92
94
  /**
93
- * Les entrées du menu du compte : Account d'abord, puis les produits ouverts. `current` est le
94
- * mot du produit affiché (« Mail ») : il est coché. `accountHref` remplace l'adresse d'Account
95
- * (un Account local en développement). Chaque produit pointe vers son entrée (`entryHref`) :
95
+ * Les entrées du menu du compte : Manager d'abord, puis les autres produits ouverts. `current` est le
96
+ * mot du produit affiché (« Mail ») : il est coché. `accountHref` remplace l'adresse de Manager
97
+ * (un Manager local en développement). Chaque produit pointe vers son entrée (`entryHref`) :
96
98
  * un clic ouvre l'app avec la session HGDC, pas la page d'accueil publique.
97
99
  */
98
100
  export declare function productMenuEntries(options?: {
@@ -121,10 +123,10 @@ export type ProductRailEntry = {
121
123
  sameOrigin?: boolean;
122
124
  };
123
125
  /**
124
- * Les entrées de la barre des produits : les produits ouverts du catalogue et Account, affiché en
125
- * tête (le compte commun, pas un produit). Chaque produit pointe vers son entrée
126
- * `/auth/hgdc?refresh=background&next=/` (ADR 0010, 0013, 0016), Account vers sa racine (`accountHref` en
127
- * développement). Le produit courant pointe vers sa racine, sans détour par l'entrée.
126
+ * Les entrées de la barre des produits : Manager, affiché en tête, puis les autres produits ouverts du
127
+ * catalogue. Chaque produit pointe vers son entrée
128
+ * `/auth/hgdc?refresh=background&next=/` (ADR 0010, 0013, 0016), Manager aussi, ou vers `accountHref` en
129
+ * développement. Le produit courant pointe vers sa racine, sans détour par l'entrée.
128
130
  *
129
131
  * `pageOrigin` (`location.origin`, absent au rendu serveur) : un produit servi sous cette origine
130
132
  * (`PRODUCT_ORIGINS`, `app.hgdc.ch/<produit>`) reçoit un lien relatif et `sameOrigin` (ADR 0020),
package/dist/products.js CHANGED
@@ -70,6 +70,8 @@ function product(word, pitch, icon, stage) {
70
70
  /** HGDC Account : le compte commun (profil, sécurité, organisations), hors du catalogue des produits. */
71
71
  const account = product("Account", "Ton compte : profil, sécurité et organisations, pour tous les produits de la famille.", UserCircleIcon, "live");
72
72
  export const HGDC_ACCOUNT = { ...account, entryHref: account.href };
73
+ /** Manager : les organisations, leurs membres et leurs rôles. En tête du menu et de la barre des produits. */
74
+ export const HGDC_MANAGER = product("Manager", "Tes organisations, leurs membres et leurs rôles.", UserGroupIcon, "live");
73
75
  /** Les produits de la famille, dans leur ordre d'affichage. Account n'en fait pas partie (`HGDC_ACCOUNT`). */
74
76
  export const HGDC_PRODUCTS = [
75
77
  product("Host", "Ton site en ligne, déployé à chaque modification.", Rocket01Icon, "live"),
@@ -80,7 +82,7 @@ export const HGDC_PRODUCTS = [
80
82
  product("Docs", "Ta documentation en ligne, avec un assistant qui y répond.", BookOpen01Icon, "live"),
81
83
  product("IAssistant", "Une bulle de chat IA sur ton site, qui répond à tes visiteurs.", BubbleChatIcon, "preview"),
82
84
  id(),
83
- product("Manager", "Tes organisations, leurs membres et leurs rôles.", UserGroupIcon, "live"),
85
+ HGDC_MANAGER,
84
86
  ];
85
87
  /** ID, le compte de connexion ouvert aux applications tierces : pas d'entrée `/auth/hgdc`, sa racine. */
86
88
  function id() {
@@ -92,16 +94,16 @@ export function isProductOpen(item) {
92
94
  return item.stage !== "soon";
93
95
  }
94
96
  /**
95
- * Les entrées du menu du compte : Account d'abord, puis les produits ouverts. `current` est le
96
- * mot du produit affiché (« Mail ») : il est coché. `accountHref` remplace l'adresse d'Account
97
- * (un Account local en développement). Chaque produit pointe vers son entrée (`entryHref`) :
97
+ * Les entrées du menu du compte : Manager d'abord, puis les autres produits ouverts. `current` est le
98
+ * mot du produit affiché (« Mail ») : il est coché. `accountHref` remplace l'adresse de Manager
99
+ * (un Manager local en développement). Chaque produit pointe vers son entrée (`entryHref`) :
98
100
  * un clic ouvre l'app avec la session HGDC, pas la page d'accueil publique.
99
101
  */
100
102
  export function productMenuEntries(options = {}) {
101
103
  const current = options.current?.toLowerCase();
102
- const accountHref = options.accountHref ?? HGDC_ACCOUNT.entryHref;
103
- const account = { ...HGDC_ACCOUNT, href: accountHref, entryHref: accountHref };
104
- return [account, ...(options.catalog ?? HGDC_PRODUCTS).filter(isProductOpen)].map((item) => ({
104
+ const { manager, others } = managerFirst(options.catalog ?? HGDC_PRODUCTS);
105
+ const head = manager && options.accountHref ? { ...manager, entryHref: options.accountHref } : manager;
106
+ return [...(head ? [head] : []), ...others.filter(isProductOpen)].map((item) => ({
105
107
  name: item.name,
106
108
  href: item.entryHref,
107
109
  badge: item.badge,
@@ -126,10 +128,10 @@ export function sameOriginPath(href, pageOrigin) {
126
128
  }
127
129
  }
128
130
  /**
129
- * Les entrées de la barre des produits : les produits ouverts du catalogue et Account, affiché en
130
- * tête (le compte commun, pas un produit). Chaque produit pointe vers son entrée
131
- * `/auth/hgdc?refresh=background&next=/` (ADR 0010, 0013, 0016), Account vers sa racine (`accountHref` en
132
- * développement). Le produit courant pointe vers sa racine, sans détour par l'entrée.
131
+ * Les entrées de la barre des produits : Manager, affiché en tête, puis les autres produits ouverts du
132
+ * catalogue. Chaque produit pointe vers son entrée
133
+ * `/auth/hgdc?refresh=background&next=/` (ADR 0010, 0013, 0016), Manager aussi, ou vers `accountHref` en
134
+ * développement. Le produit courant pointe vers sa racine, sans détour par l'entrée.
133
135
  *
134
136
  * `pageOrigin` (`location.origin`, absent au rendu serveur) : un produit servi sous cette origine
135
137
  * (`PRODUCT_ORIGINS`, `app.hgdc.ch/<produit>`) reçoit un lien relatif et `sameOrigin` (ADR 0020),
@@ -151,11 +153,18 @@ export function productRailEntries(options = {}) {
151
153
  const path = product ? sameOriginPath(href, pageOrigin) : null;
152
154
  return path === null ? { ...base, href } : { ...base, href: path, sameOrigin: true };
153
155
  };
156
+ const { manager, others } = managerFirst(options.catalog ?? HGDC_PRODUCTS);
157
+ const head = manager ?? HGDC_MANAGER;
154
158
  return {
155
- products: (options.catalog ?? HGDC_PRODUCTS).filter(isProductOpen).map((item) => entry(item, item.entryHref, true)),
156
- account: entry(HGDC_ACCOUNT, options.accountHref ?? HGDC_ACCOUNT.entryHref, false),
159
+ products: others.filter(isProductOpen).map((item) => entry(item, item.entryHref, true)),
160
+ account: entry(head, options.accountHref ?? head.entryHref, options.accountHref === undefined),
157
161
  };
158
162
  }
163
+ /** Manager du catalogue, s'il y est, sorti des autres produits : il prend la place d'Account en tête. */
164
+ function managerFirst(catalog) {
165
+ const manager = catalog.find((item) => item.badge === "manager" && isProductOpen(item));
166
+ return { manager, others: catalog.filter((item) => item !== manager) };
167
+ }
159
168
  /**
160
169
  * Lien vers l'autre vue du même produit (ADR 0014) : depuis `app.hgdc.ch/<mot>`, « Ouvrir seul » vers
161
170
  * `<mot>.hgdc.ch` ; depuis `<mot>.hgdc.ch`, « Ouvrir dans app.hgdc.ch ». Passe par l'entrée
@@ -2,6 +2,8 @@
2
2
  export declare const SHELL_ORG_KEY = "hgdc-shell:org";
3
3
  /** Hauteur en pixels de la navigation d'un produit : `hgdc-shell:nav:<produit>`. */
4
4
  export declare const SHELL_NAV_KEY_PREFIX = "hgdc-shell:nav:";
5
+ /** Dernier produit ouvert (son mot), en `localStorage` : l'accueil d'`app.hgdc.ch` y renvoie. */
6
+ export declare const SHELL_LAST_PRODUCT_KEY = "hgdc-shell:last";
5
7
  /** Passage d'un produit à l'autre (horodatage), en `sessionStorage`. */
6
8
  export declare const SHELL_SWITCH_KEY = "hgdc-shell:switch";
7
9
  /** Au-delà, un passage noté n'est plus celui qu'on vit (onglet laissé, retour bien plus tard). */
@@ -63,6 +65,8 @@ export declare function rememberShellOrganization(org: {
63
65
  export declare function forgetShellOrganization(): void;
64
66
  /** Retient la hauteur de la navigation d'un produit (`AppShell` le fait après l'affichage). */
65
67
  export declare function rememberShellNavHeight(product: string, height: number): void;
68
+ /** Retient le produit affiché (`AppShell` le fait), pour que l'accueil d'`app.hgdc.ch` y renvoie. */
69
+ export declare function rememberLastProduct(product: string): void;
66
70
  /** Note le départ vers un autre produit (clic dans la barre des produits). */
67
71
  export declare function markProductSwitch(now?: number): void;
68
72
  /** Lit et efface la note : vrai si la page vient d'un passage depuis la barre, il y a peu. */
@@ -18,6 +18,8 @@ import { PRODUCT_ORIGINS } from "./products.js";
18
18
  export const SHELL_ORG_KEY = "hgdc-shell:org";
19
19
  /** Hauteur en pixels de la navigation d'un produit : `hgdc-shell:nav:<produit>`. */
20
20
  export const SHELL_NAV_KEY_PREFIX = "hgdc-shell:nav:";
21
+ /** Dernier produit ouvert (son mot), en `localStorage` : l'accueil d'`app.hgdc.ch` y renvoie. */
22
+ export const SHELL_LAST_PRODUCT_KEY = "hgdc-shell:last";
21
23
  /** Passage d'un produit à l'autre (horodatage), en `sessionStorage`. */
22
24
  export const SHELL_SWITCH_KEY = "hgdc-shell:switch";
23
25
  /** Au-delà, un passage noté n'est plus celui qu'on vit (onglet laissé, retour bien plus tard). */
@@ -162,6 +164,12 @@ export function rememberShellNavHeight(product, height) {
162
164
  return;
163
165
  storageSet("localStorage", SHELL_NAV_KEY_PREFIX + product, String(Math.round(height)));
164
166
  }
167
+ /** Retient le produit affiché (`AppShell` le fait), pour que l'accueil d'`app.hgdc.ch` y renvoie. */
168
+ export function rememberLastProduct(product) {
169
+ if (!browser())
170
+ return;
171
+ storageSet("localStorage", SHELL_LAST_PRODUCT_KEY, product);
172
+ }
165
173
  /** Note le départ vers un autre produit (clic dans la barre des produits). */
166
174
  export function markProductSwitch(now = Date.now()) {
167
175
  if (!browser())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hgdc/ui",
3
- "version": "0.58.0",
3
+ "version": "0.60.0",
4
4
  "description": "Interface de la H Collection : jetons de la DA, thèmes, polices et composants.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://github.com/hugogebel-boop/hgdc-kit/tree/main/packages/ui#readme",