@hgdc/ui 0.53.0 → 0.55.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/dist/addresses.d.ts +3 -2
- package/dist/addresses.js +3 -2
- package/dist/avatar.js +2 -12
- package/dist/family-svg.d.ts +1 -1
- package/dist/family-svg.js +3 -0
- package/dist/initials.d.ts +7 -0
- package/dist/initials.js +14 -0
- package/dist/org-switcher.d.ts +8 -2
- package/dist/org-switcher.js +13 -9
- package/dist/product-badge.js +1 -0
- package/dist/products.js +2 -0
- package/dist/shell-memory.d.ts +5 -0
- package/dist/shell-memory.js +18 -2
- package/email-icons/manager.png +0 -0
- package/family/app/manager/apple-touch-icon.png +0 -0
- package/family/app/manager/favicon.ico +0 -0
- package/family/app/manager/favicon.svg +1 -0
- package/family/app/manager/icon-192.png +0 -0
- package/family/app/manager/icon-512.png +0 -0
- package/family/app/manager/icon-maskable-512.png +0 -0
- package/family/manager-dark.svg +1 -0
- package/family/manager.svg +1 -0
- package/family/tile/manager.svg +1 -0
- package/package.json +1 -1
- package/styles.css +8 -4
package/dist/addresses.d.ts
CHANGED
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
export declare const APP_ORIGIN = "https://app.hgdc.ch";
|
|
12
12
|
/**
|
|
13
13
|
* Produits servis sous `https://app.hgdc.ch/<mot>` (consoles relayées par la passerelle, ADR 0005).
|
|
14
|
-
* Account (fournisseur d'identité)
|
|
14
|
+
* Account et ID (fournisseur d'identité) gardent leur hôte ; Manager (organisations, ex-Account) a son backend dans
|
|
15
|
+
* l'instance `account`, mais sa console est relayée comme les autres (ADR 0015 de la famille). Status : la
|
|
15
16
|
* console seule, `status.hgdc.ch` garde les pages publiques et la console de secours. Vérifiée contre
|
|
16
17
|
* le manifeste privé de la famille (`famille check`) : un produit relayé s'ajoute ici et là.
|
|
17
18
|
*/
|
|
18
|
-
export declare const APP_PRODUCTS: readonly ["analytics", "mail", "host", "docs", "status", "iassistant", "portal"];
|
|
19
|
+
export declare const APP_PRODUCTS: readonly ["analytics", "mail", "host", "docs", "status", "iassistant", "portal", "manager"];
|
|
19
20
|
/** Vrai si le produit est servi sous `app.hgdc.ch`. */
|
|
20
21
|
export declare function isAppProduct(product: string): boolean;
|
|
21
22
|
/**
|
package/dist/addresses.js
CHANGED
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
export const APP_ORIGIN = "https://app.hgdc.ch";
|
|
12
12
|
/**
|
|
13
13
|
* Produits servis sous `https://app.hgdc.ch/<mot>` (consoles relayées par la passerelle, ADR 0005).
|
|
14
|
-
* Account (fournisseur d'identité)
|
|
14
|
+
* Account et ID (fournisseur d'identité) gardent leur hôte ; Manager (organisations, ex-Account) a son backend dans
|
|
15
|
+
* l'instance `account`, mais sa console est relayée comme les autres (ADR 0015 de la famille). Status : la
|
|
15
16
|
* console seule, `status.hgdc.ch` garde les pages publiques et la console de secours. Vérifiée contre
|
|
16
17
|
* le manifeste privé de la famille (`famille check`) : un produit relayé s'ajoute ici et là.
|
|
17
18
|
*/
|
|
18
|
-
export const APP_PRODUCTS = ["analytics", "mail", "host", "docs", "status", "iassistant", "portal"];
|
|
19
|
+
export const APP_PRODUCTS = ["analytics", "mail", "host", "docs", "status", "iassistant", "portal", "manager"];
|
|
19
20
|
/** Vrai si le produit est servi sous `app.hgdc.ch`. */
|
|
20
21
|
export function isAppProduct(product) {
|
|
21
22
|
return APP_PRODUCTS.includes(product.toLowerCase());
|
package/dist/avatar.js
CHANGED
|
@@ -2,23 +2,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { cn } from "./cn.js";
|
|
5
|
-
import { avatarTone } from "./initials.js";
|
|
5
|
+
import { AVATAR_TONE_CLASSES, avatarTone } from "./initials.js";
|
|
6
6
|
function Avatar({ className, size = "default", ...props }) {
|
|
7
7
|
return (_jsx(AvatarPrimitive.Root, { "data-slot": "avatar", "data-size": size, className: cn("group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className), ...props }));
|
|
8
8
|
}
|
|
9
9
|
function AvatarImage({ className, ...props }) {
|
|
10
10
|
return (_jsx(AvatarPrimitive.Image, { "data-slot": "avatar-image", className: cn("aspect-square size-full rounded-full object-cover", className), ...props }));
|
|
11
11
|
}
|
|
12
|
-
/** Lavis et encre de chaque teinte (`--avatar-<n>`, `styles.css`), à 4,5:1 en clair et en sombre. */
|
|
13
|
-
const TONE_CLASSES = {
|
|
14
|
-
1: "bg-avatar-1 text-avatar-1-ink",
|
|
15
|
-
2: "bg-avatar-2 text-avatar-2-ink",
|
|
16
|
-
3: "bg-avatar-3 text-avatar-3-ink",
|
|
17
|
-
4: "bg-avatar-4 text-avatar-4-ink",
|
|
18
|
-
5: "bg-avatar-5 text-avatar-5-ink",
|
|
19
|
-
6: "bg-avatar-6 text-avatar-6-ink",
|
|
20
|
-
7: "bg-avatar-7 text-avatar-7-ink",
|
|
21
|
-
};
|
|
22
12
|
/**
|
|
23
13
|
* Ce qui s'affiche sans photo (la photo, `AvatarImage`, reste prioritaire). Des initiales en
|
|
24
14
|
* texte prennent une teinte de la marque, stable : celle de `colorKey` (identifiant ou adresse
|
|
@@ -28,7 +18,7 @@ const TONE_CLASSES = {
|
|
|
28
18
|
function AvatarFallback({ className, colorKey, children, ...props }) {
|
|
29
19
|
const key = colorKey === undefined ? (typeof children === "string" ? children : "") : (colorKey ?? "");
|
|
30
20
|
const tone = key.trim() ? avatarTone(key) : null;
|
|
31
|
-
return (_jsx(AvatarPrimitive.Fallback, { "data-slot": "avatar-fallback", "data-tone": tone ?? undefined, className: cn("flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs", tone ? cn("font-semibold",
|
|
21
|
+
return (_jsx(AvatarPrimitive.Fallback, { "data-slot": "avatar-fallback", "data-tone": tone ?? undefined, className: cn("flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs", tone ? cn("font-semibold", AVATAR_TONE_CLASSES[tone]) : "bg-muted text-muted-foreground", className), ...props, children: children }));
|
|
32
22
|
}
|
|
33
23
|
function AvatarBadge({ className, ...props }) {
|
|
34
24
|
return (_jsx("span", { "data-slot": "avatar-badge", className: cn("absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className), ...props }));
|
package/dist/family-svg.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Les produits de la H Collection qui ont une icône, par leur mot en minuscules. */
|
|
2
|
-
export declare const FAMILY_PRODUCTS: readonly ["account", "host", "mail", "portal", "status", "analytics", "docs", "iassistant", "id"];
|
|
2
|
+
export declare const FAMILY_PRODUCTS: readonly ["account", "host", "mail", "portal", "status", "analytics", "docs", "iassistant", "id", "manager"];
|
|
3
3
|
export type FamilyProduct = (typeof FAMILY_PRODUCTS)[number];
|
|
4
4
|
/** Vrai si le mot en minuscules (« host ») désigne un produit qui a une icône. */
|
|
5
5
|
export declare function isFamilyProduct(word: string): word is FamilyProduct;
|
package/dist/family-svg.js
CHANGED
|
@@ -10,6 +10,7 @@ export const FAMILY_PRODUCTS = [
|
|
|
10
10
|
"docs",
|
|
11
11
|
"iassistant",
|
|
12
12
|
"id",
|
|
13
|
+
"manager",
|
|
13
14
|
];
|
|
14
15
|
/** Vrai si le mot en minuscules (« host ») désigne un produit qui a une icône. */
|
|
15
16
|
export function isFamilyProduct(word) {
|
|
@@ -29,6 +30,7 @@ export const PRODUCT_BADGE_SVG = {
|
|
|
29
30
|
docs: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><svg x="0" y="0" width="64" height="64" viewBox="14 13 36 36"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0ec1dc"/><stop offset="1" stop-color="#0aa3c1"/></linearGradient></defs><path d="M26 13H46A3 3 0 0 1 49 16V43A3 3 0 0 1 46 46H26A3 3 0 0 1 23 43V16A3 3 0 0 1 26 13Z" fill="url(#g)" fill-opacity="0.22" fill-rule="evenodd"/><path d="M18 18H32V24.5A2.5 2.5 0 0 0 34.5 27H41V46A3 3 0 0 1 38 49H18A3 3 0 0 1 15 46V21A3 3 0 0 1 18 18ZM21.3 33H34.7A1.3 1.3 0 0 1 36 34.3V34.300000000000004A1.3 1.3 0 0 1 34.7 35.6H21.3A1.3 1.3 0 0 1 20 34.300000000000004V34.3A1.3 1.3 0 0 1 21.3 33ZM21.3 39H29.7A1.3 1.3 0 0 1 31 40.3V40.300000000000004A1.3 1.3 0 0 1 29.7 41.6H21.3A1.3 1.3 0 0 1 20 40.300000000000004V40.3A1.3 1.3 0 0 1 21.3 39Z" fill="url(#g)" fill-rule="evenodd"/><path d="M32 18L41 27H34.5A2.5 2.5 0 0 1 32 24.5Z" fill="url(#g)" fill-opacity="0.45" fill-rule="evenodd"/></svg></svg>',
|
|
30
31
|
iassistant: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><svg x="0" y="0" width="64" height="64" viewBox="16 18 34 34"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#d946ef"/><stop offset="1" stop-color="#c026d3"/></linearGradient></defs><path d="M24 18H38A6 6 0 0 1 44 24V32A6 6 0 0 1 38 38H27L21 43V37.2A6 6 0 0 1 18 32V24A6 6 0 0 1 24 18Z" fill="url(#g)" fill-opacity="0.4" fill-rule="evenodd"/><path d="M29 27H43A6 6 0 0 1 49 33V41A6 6 0 0 1 43 47V51.5L37.5 47H29A6 6 0 0 1 23 41V33A6 6 0 0 1 29 27ZM28.1 37A1.9 1.9 0 1 0 31.9 37A1.9 1.9 0 1 0 28.1 37ZM34.1 37A1.9 1.9 0 1 0 37.9 37A1.9 1.9 0 1 0 34.1 37ZM40.1 37A1.9 1.9 0 1 0 43.9 37A1.9 1.9 0 1 0 40.1 37Z" fill="url(#g)" fill-rule="evenodd"/></svg></svg>',
|
|
31
32
|
id: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><svg x="0" y="0" width="64" height="64" viewBox="18 18 48 48"><defs><linearGradient id="g" x1="18" y1="18" x2="66" y2="66" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff2a2a"/><stop offset="1" stop-color="#e60000"/></linearGradient></defs><path d="M28.5 18H55.5A10.5 10.5 0 0 1 66 28.5V55.5A10.5 10.5 0 0 1 55.5 66H28.5A10.5 10.5 0 0 1 18 55.5V28.5A10.5 10.5 0 0 1 28.5 18Z" fill="url(#g)"/><path d="M37.8 28L46.2 28L46.2 37.8L56 37.8L56 46.2L46.2 46.2L46.2 56L37.8 56L37.8 46.2L28 46.2L28 37.8L37.8 37.8Z" transform="translate(1.9 1.9)" fill="#fff" fill-opacity="0.4"/><path d="M37.8 28L46.2 28L46.2 37.8L56 37.8L56 46.2L46.2 46.2L46.2 56L37.8 56L37.8 46.2L28 46.2L28 37.8L37.8 37.8Z" transform="translate(-1.9 -1.9)" fill="#fff"/></svg></svg>',
|
|
33
|
+
manager: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><svg x="0" y="0" width="64" height="64" viewBox="14 16.5 36 36"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff6a3d"/><stop offset="1" stop-color="#fc582e"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#g)" fill-opacity="0.45" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#g)" fill-rule="evenodd"/></svg></svg>',
|
|
32
34
|
};
|
|
33
35
|
/**
|
|
34
36
|
* Empreinte de chaque icône d'e-mail (`email-icons/<mot>.png`), ajoutée à son adresse : un client
|
|
@@ -44,6 +46,7 @@ export const EMAIL_ICON_VERSION = {
|
|
|
44
46
|
docs: "77f11f0b",
|
|
45
47
|
iassistant: "2b9ed0e0",
|
|
46
48
|
id: "4c663fa1",
|
|
49
|
+
manager: "0923b87a",
|
|
47
50
|
};
|
|
48
51
|
/** SVG du H « Double », la marque de la H Collection, sans fond (`family/hcollection-icon(-dark).svg`). */
|
|
49
52
|
export const FAMILY_MARK_SVG = {
|
package/dist/initials.d.ts
CHANGED
|
@@ -15,3 +15,10 @@ export type AvatarTone = 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
|
15
15
|
* toujours la même teinte, dans tous les produits. FNV-1a 32 bits, puis modulo 7.
|
|
16
16
|
*/
|
|
17
17
|
export declare function avatarTone(key: string): AvatarTone;
|
|
18
|
+
/** Lavis et encre de chaque teinte (`--avatar-<n>`, `styles.css`), à 4,5:1 en clair et en sombre. */
|
|
19
|
+
export declare const AVATAR_TONE_CLASSES: Readonly<Record<AvatarTone, string>>;
|
|
20
|
+
/** Teinte de la marque d'une organisation (`OrgMark`, mémoire de la coque) : celle de son identifiant, sinon de son nom. */
|
|
21
|
+
export declare function orgTone(org: {
|
|
22
|
+
id?: string | undefined;
|
|
23
|
+
name: string;
|
|
24
|
+
}): AvatarTone;
|
package/dist/initials.js
CHANGED
|
@@ -36,3 +36,17 @@ export function avatarTone(key) {
|
|
|
36
36
|
}
|
|
37
37
|
return ((hash % AVATAR_TONES) + 1);
|
|
38
38
|
}
|
|
39
|
+
/** Lavis et encre de chaque teinte (`--avatar-<n>`, `styles.css`), à 4,5:1 en clair et en sombre. */
|
|
40
|
+
export const AVATAR_TONE_CLASSES = {
|
|
41
|
+
1: "bg-avatar-1 text-avatar-1-ink",
|
|
42
|
+
2: "bg-avatar-2 text-avatar-2-ink",
|
|
43
|
+
3: "bg-avatar-3 text-avatar-3-ink",
|
|
44
|
+
4: "bg-avatar-4 text-avatar-4-ink",
|
|
45
|
+
5: "bg-avatar-5 text-avatar-5-ink",
|
|
46
|
+
6: "bg-avatar-6 text-avatar-6-ink",
|
|
47
|
+
7: "bg-avatar-7 text-avatar-7-ink",
|
|
48
|
+
};
|
|
49
|
+
/** Teinte de la marque d'une organisation (`OrgMark`, mémoire de la coque) : celle de son identifiant, sinon de son nom. */
|
|
50
|
+
export function orgTone(org) {
|
|
51
|
+
return avatarTone(org.id?.trim() ? org.id : org.name);
|
|
52
|
+
}
|
package/dist/org-switcher.d.ts
CHANGED
|
@@ -19,9 +19,15 @@ export type Organization = {
|
|
|
19
19
|
};
|
|
20
20
|
/** Un lien dans un menu, à l'allure d'un `DropdownMenuItem`. */
|
|
21
21
|
export declare const MENU_LINK_ITEM: string;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Marque d'une organisation : son logo, ou ses initiales (`initials`) sur un carré arrondi, dans la teinte de
|
|
24
|
+
* son identifiant (`avatarTone`) : deux organisations aux mêmes initiales ne se confondent pas. Sans `id`, la
|
|
25
|
+
* teinte du nom.
|
|
26
|
+
*/
|
|
23
27
|
export declare function OrgMark({ org, className, }: {
|
|
24
|
-
org: Pick<Organization, "name" | "logo"
|
|
28
|
+
org: Pick<Organization, "name" | "logo"> & {
|
|
29
|
+
id?: string;
|
|
30
|
+
};
|
|
25
31
|
className?: string;
|
|
26
32
|
}): React.JSX.Element;
|
|
27
33
|
/**
|
package/dist/org-switcher.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
|
7
7
|
import { useEffect } from "react";
|
|
8
8
|
import { Badge } from "./badge.js";
|
|
9
9
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "./dropdown-menu.js";
|
|
10
|
-
import { initials } from "./initials.js";
|
|
10
|
+
import { AVATAR_TONE_CLASSES, initials, orgTone } from "./initials.js";
|
|
11
11
|
import { rememberShellOrganization } from "./shell-memory.js";
|
|
12
12
|
import { useShellPlacement } from "./shell-placement.js";
|
|
13
13
|
import { cn } from "./cn.js";
|
|
@@ -25,11 +25,15 @@ export function RoleBadge({ orgRole: role, title, className, }) {
|
|
|
25
25
|
}
|
|
26
26
|
/** Un lien dans un menu, à l'allure d'un `DropdownMenuItem`. */
|
|
27
27
|
export const MENU_LINK_ITEM = "relative flex cursor-default items-center gap-2.5 rounded-xl px-3 py-2 text-sm font-medium outline-hidden select-none focus:bg-muted focus:text-foreground data-highlighted:bg-muted max-lg:min-h-11 coarse:min-h-11 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Marque d'une organisation : son logo, ou ses initiales (`initials`) sur un carré arrondi, dans la teinte de
|
|
30
|
+
* son identifiant (`avatarTone`) : deux organisations aux mêmes initiales ne se confondent pas. Sans `id`, la
|
|
31
|
+
* teinte du nom.
|
|
32
|
+
*/
|
|
29
33
|
export function OrgMark({ org, className, }) {
|
|
30
34
|
if (org.logo)
|
|
31
35
|
return _jsx("img", { src: org.logo, alt: "", className: cn("size-8 shrink-0 rounded-lg object-cover", className) });
|
|
32
|
-
return (_jsx("span", { "aria-hidden": true, className: cn("grid size-8 shrink-0 place-items-center rounded-lg
|
|
36
|
+
return (_jsx("span", { "aria-hidden": true, className: cn("grid size-8 shrink-0 place-items-center rounded-lg text-xs font-semibold uppercase", AVATAR_TONE_CLASSES[orgTone(org)], className), children: initials(org.name) }));
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
35
39
|
* L'organisation active, et le menu pour en changer ou en créer une. En haut de la barre des
|
|
@@ -46,17 +50,17 @@ export function OrgSwitcher({ organizations, activeId, onSelect, createHref, onC
|
|
|
46
50
|
const activeLogo = active?.logo;
|
|
47
51
|
useEffect(() => {
|
|
48
52
|
if (activeName !== undefined)
|
|
49
|
-
rememberShellOrganization({ name: activeName, logo: activeLogo });
|
|
50
|
-
}, [activeName, activeLogo]);
|
|
53
|
+
rememberShellOrganization({ id: activeId, name: activeName, logo: activeLogo });
|
|
54
|
+
}, [activeId, activeName, activeLogo]);
|
|
51
55
|
if (!active)
|
|
52
56
|
return null;
|
|
53
57
|
// En haut de la barre des produits : la marque seule dans 40 px, le nom quand la barre s'élargit.
|
|
54
58
|
const inRail = placement === "product-rail";
|
|
55
|
-
return (_jsxs(DropdownMenu, { children: [_jsxs(DropdownMenuTrigger, { render: _jsx("button", { type: "button", "aria-label": `Organisation ${active.name}, changer d'organisation`, className: cn("flex h-10 w-full min-w-0 items-center gap-2.5 rounded-xl px-1.5 text-left coarse:h-11 outline-none transition-colors duration-(--duration-fast) ease-out hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring/50 aria-expanded:bg-muted", inRail
|
|
56
|
-
? "shrink-0 gap-3 px-1 hover:bg-shell-hover aria-expanded:bg-shell-hover"
|
|
59
|
+
return (_jsxs(DropdownMenu, { children: [_jsxs(DropdownMenuTrigger, { render: _jsx("button", { type: "button", "aria-label": `Organisation ${active.name}, changer d'organisation`, title: active.name, className: cn("flex min-h-10 w-full min-w-0 items-center gap-2.5 rounded-xl px-1.5 py-1 text-left coarse:min-h-11 outline-none transition-colors duration-(--duration-fast) ease-out hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring/50 aria-expanded:bg-muted", inRail
|
|
60
|
+
? "h-10 shrink-0 gap-3 px-1 py-0 hover:bg-shell-hover aria-expanded:bg-shell-hover coarse:h-11"
|
|
57
61
|
: "lg:hover:bg-shell-hover lg:aria-expanded:bg-shell-hover lg:rail:w-auto lg:rail:justify-center lg:rail:px-1", className) }), children: [_jsx(OrgMark, { org: active }), _jsxs("span", { className: cn("min-w-0 flex-1", inRail
|
|
58
62
|
? "opacity-0 transition-opacity duration-(--duration-fast) ease-out group-data-expanded/rail:opacity-100 motion-reduce:transition-none"
|
|
59
|
-
: "lg:rail:hidden"), children: [_jsx("span", { className: "block
|
|
63
|
+
: "lg:rail:hidden"), children: [_jsx("span", { className: cn("block text-sm font-medium", inRail ? "truncate" : "line-clamp-2 break-words"), children: active.name }), active.role ? (_jsx("span", { className: "block truncate text-xs text-muted-foreground lg:text-shell-muted", children: ORG_ROLE_LABEL[active.role] })) : null] }), _jsx(HugeiconsIcon, { icon: UnfoldMoreIcon, "aria-hidden": true, className: cn("size-4 shrink-0 text-muted-foreground lg:text-shell-muted", inRail
|
|
60
64
|
? "opacity-0 transition-opacity duration-(--duration-fast) group-data-expanded/rail:opacity-100"
|
|
61
|
-
: "lg:rail:hidden") })] }), _jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [_jsxs(DropdownMenuGroup, { children: [_jsx(DropdownMenuLabel, { children: "Organisations" }), organizations.map((org) => (_jsxs(DropdownMenuItem, { onClick: () => onSelect(org.id), children: [_jsx(OrgMark, { org: org, className: "size-6 rounded-md
|
|
65
|
+
: "lg:rail:hidden") })] }), _jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [_jsxs(DropdownMenuGroup, { children: [_jsx(DropdownMenuLabel, { children: "Organisations" }), organizations.map((org) => (_jsxs(DropdownMenuItem, { onClick: () => onSelect(org.id), children: [_jsx(OrgMark, { org: org, className: "size-6 rounded-md text-[10px]" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: org.name }), org.id === activeId ? (_jsx(HugeiconsIcon, { icon: Tick02Icon, "aria-label": "Organisation active", className: "size-4" })) : org.role ? (_jsx("span", { className: "text-xs font-normal text-muted-foreground", children: ORG_ROLE_LABEL[org.role] })) : null] }, org.id)))] }), createHref !== undefined ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(MenuPrimitive.LinkItem, { href: createHref, className: MENU_LINK_ITEM, children: [_jsx(HugeiconsIcon, { icon: PlusSignIcon, "aria-hidden": true }), "Cr\u00E9er une organisation"] })] })) : onCreate !== undefined ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuItem, { onClick: onCreate, children: [_jsx(HugeiconsIcon, { icon: PlusSignIcon, "aria-hidden": true }), "Cr\u00E9er une organisation"] })] })) : null] })] }));
|
|
62
66
|
}
|
package/dist/product-badge.js
CHANGED
|
@@ -16,6 +16,7 @@ export const PRODUCT_GRADIENT = {
|
|
|
16
16
|
docs: { from: "#0ec1dc", to: "#0aa3c1" },
|
|
17
17
|
iassistant: { from: "#d946ef", to: "#c026d3" },
|
|
18
18
|
id: { from: "#ff2a2a", to: "#e60000" },
|
|
19
|
+
manager: { from: "#ff6a3d", to: "#fc582e" },
|
|
19
20
|
};
|
|
20
21
|
// En image plutôt qu'en SVG en ligne : chaque icône garde ses identifiants de dégradé pour elle,
|
|
21
22
|
// plusieurs icônes dans une même page ne se marchent pas dessus.
|
package/dist/products.js
CHANGED
|
@@ -5,6 +5,7 @@ import BubbleChatIcon from "@hugeicons/core-free-icons/BubbleChatIcon";
|
|
|
5
5
|
import Briefcase01Icon from "@hugeicons/core-free-icons/Briefcase01Icon";
|
|
6
6
|
import Mail01Icon from "@hugeicons/core-free-icons/Mail01Icon";
|
|
7
7
|
import Rocket01Icon from "@hugeicons/core-free-icons/Rocket01Icon";
|
|
8
|
+
import UserGroupIcon from "@hugeicons/core-free-icons/UserGroupIcon";
|
|
8
9
|
import UserCircleIcon from "@hugeicons/core-free-icons/UserCircleIcon";
|
|
9
10
|
import { APP_ORIGIN, APP_PRODUCTS, isAppProduct, soloOrigin } from "./addresses.js";
|
|
10
11
|
import { HGDC_EMAIL_ACCENT } from "./email-palette.js";
|
|
@@ -79,6 +80,7 @@ export const HGDC_PRODUCTS = [
|
|
|
79
80
|
product("Docs", "Ta documentation en ligne, avec un assistant qui y répond.", BookOpen01Icon, "live"),
|
|
80
81
|
product("IAssistant", "Une bulle de chat IA sur ton site, qui répond à tes visiteurs.", BubbleChatIcon, "preview"),
|
|
81
82
|
id(),
|
|
83
|
+
product("Manager", "Tes organisations, leurs membres et leurs rôles.", UserGroupIcon, "live"),
|
|
82
84
|
];
|
|
83
85
|
/** ID, le compte de connexion ouvert aux applications tierces : pas d'entrée `/auth/hgdc`, sa racine. */
|
|
84
86
|
function id() {
|
package/dist/shell-memory.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const SHELL_SWITCH_MAX_AGE_MS = 10000;
|
|
|
9
9
|
export type ShellOrganization = {
|
|
10
10
|
initials: string;
|
|
11
11
|
logo?: string;
|
|
12
|
+
tone?: number;
|
|
12
13
|
};
|
|
13
14
|
export type ShellBootConfig = {
|
|
14
15
|
/** Clé du rail de la barre latérale (`sidebar`), valeur `rail`. */
|
|
@@ -21,6 +22,8 @@ export type ShellBootConfig = {
|
|
|
21
22
|
origins: ReadonlyArray<readonly [string, string, string]>;
|
|
22
23
|
/** Domaine des produits sur leur sous-domaine (`hgdc.ch` : `mail.hgdc.ch` est Mail). */
|
|
23
24
|
domain: string;
|
|
25
|
+
/** Nombre de teintes d'avatar (`AVATAR_TONES`) : la teinte retenue de l'organisation est un entier de 1 à `tones`. */
|
|
26
|
+
tones: number;
|
|
24
27
|
};
|
|
25
28
|
type BootWindow = {
|
|
26
29
|
document: {
|
|
@@ -46,11 +49,13 @@ export declare const SHELL_BOOT_CONFIG: ShellBootConfig;
|
|
|
46
49
|
export declare function shellBootScript(config?: ShellBootConfig): string;
|
|
47
50
|
/** Ce que la coque retient d'une organisation : ses initiales et son logo (`https:` seulement). */
|
|
48
51
|
export declare function shellOrganization(org: {
|
|
52
|
+
id?: string | undefined;
|
|
49
53
|
name: string;
|
|
50
54
|
logo?: string | undefined;
|
|
51
55
|
}): ShellOrganization;
|
|
52
56
|
/** Retient l'organisation affichée (`OrgSwitcher` le fait) et l'applique à la page. */
|
|
53
57
|
export declare function rememberShellOrganization(org: {
|
|
58
|
+
id?: string | undefined;
|
|
54
59
|
name: string;
|
|
55
60
|
logo?: string | undefined;
|
|
56
61
|
}): void;
|
package/dist/shell-memory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { initials } from "./initials.js";
|
|
1
|
+
import { AVATAR_TONES, initials, orgTone } from "./initials.js";
|
|
2
2
|
import { FAMILY_PRODUCTS } from "./family-svg.js";
|
|
3
3
|
import { PRODUCT_ORIGINS } from "./products.js";
|
|
4
4
|
/*
|
|
@@ -77,11 +77,26 @@ export function shellBoot(config, win) {
|
|
|
77
77
|
root.style.setProperty("--hgdc-org-logo", `url("${logo}")`);
|
|
78
78
|
else
|
|
79
79
|
root.style.removeProperty("--hgdc-org-logo");
|
|
80
|
+
// Teinte d'OrgMark (`--avatar-<n>`), un entier de 1 à 7 seulement.
|
|
81
|
+
const tone = org && Number.isInteger(org.tone) && Number(org.tone) >= 1 && Number(org.tone) <= config.tones
|
|
82
|
+
? Number(org.tone)
|
|
83
|
+
: 0;
|
|
84
|
+
if (tone) {
|
|
85
|
+
const token = `--avatar-${tone}`;
|
|
86
|
+
root.style.setProperty("--hgdc-org-bg", `var(${token})`);
|
|
87
|
+
root.style.setProperty("--hgdc-org-ink", `var(${token}-ink)`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
root.style.removeProperty("--hgdc-org-bg");
|
|
91
|
+
root.style.removeProperty("--hgdc-org-ink");
|
|
92
|
+
}
|
|
80
93
|
}
|
|
81
94
|
else {
|
|
82
95
|
delete root.dataset.hgdcOrg;
|
|
83
96
|
root.style.removeProperty("--hgdc-org-initials");
|
|
84
97
|
root.style.removeProperty("--hgdc-org-logo");
|
|
98
|
+
root.style.removeProperty("--hgdc-org-bg");
|
|
99
|
+
root.style.removeProperty("--hgdc-org-ink");
|
|
85
100
|
}
|
|
86
101
|
let height = 0;
|
|
87
102
|
try {
|
|
@@ -101,6 +116,7 @@ export const SHELL_BOOT_CONFIG = {
|
|
|
101
116
|
products: FAMILY_PRODUCTS,
|
|
102
117
|
origins: Object.entries(PRODUCT_ORIGINS).map(([word, { origin, basePath }]) => [word, origin, basePath]),
|
|
103
118
|
domain: "hgdc.ch",
|
|
119
|
+
tones: AVATAR_TONES,
|
|
104
120
|
};
|
|
105
121
|
/** Le script en ligne du `<head>` : `shellBoot` et sa configuration, sans dépendance. */
|
|
106
122
|
export function shellBootScript(config = SHELL_BOOT_CONFIG) {
|
|
@@ -122,7 +138,7 @@ function storageSet(storage, key, value) {
|
|
|
122
138
|
}
|
|
123
139
|
/** Ce que la coque retient d'une organisation : ses initiales et son logo (`https:` seulement). */
|
|
124
140
|
export function shellOrganization(org) {
|
|
125
|
-
return { initials: initials(org.name), ...(org.logo ? { logo: org.logo } : {}) };
|
|
141
|
+
return { initials: initials(org.name), ...(org.logo ? { logo: org.logo } : { tone: orgTone(org) }) };
|
|
126
142
|
}
|
|
127
143
|
/** Retient l'organisation affichée (`OrgSwitcher` le fait) et l'applique à la page. */
|
|
128
144
|
export function rememberShellOrganization(org) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><style>.d{display:none}@media (prefers-color-scheme:dark){.l{display:none}.d{display:inline}}</style><g class="l"><svg x="2.56" y="2.56" width="58.88" height="58.88" viewBox="14 16.5 36 36"><defs><linearGradient id="lg" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff6a3d"/><stop offset="1" stop-color="#fc582e"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#lg)" fill-opacity="0.45" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#lg)" fill-rule="evenodd"/></svg></g><g class="d"><svg x="2.56" y="2.56" width="58.88" height="58.88" viewBox="14 16.5 36 36"><defs><linearGradient id="dg" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff9777"/><stop offset="1" stop-color="#ff6a3d"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#dg)" fill-opacity="0.64" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#dg)" fill-rule="evenodd"/></svg></g></svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="11 11 42 42"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff9777"/><stop offset="1" stop-color="#ff6a3d"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#g)" fill-opacity="0.64" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#g)" fill-rule="evenodd"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="11 11 42 42"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff6a3d"/><stop offset="1" stop-color="#fc582e"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#g)" fill-opacity="0.45" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#g)" fill-rule="evenodd"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><svg x="0" y="0" width="64" height="64" viewBox="14 16.5 36 36"><defs><linearGradient id="g" x1="14" y1="14" x2="50" y2="50" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#ff6a3d"/><stop offset="1" stop-color="#fc582e"/></linearGradient></defs><path d="M17.2 27.5A3.8 3.8 0 1 0 24.8 27.5A3.8 3.8 0 1 0 17.2 27.5ZM14 44.5C14 39.5 17 36 21 36C25 36 28 39.5 28 44.5ZM39.2 27.5A3.8 3.8 0 1 0 46.8 27.5A3.8 3.8 0 1 0 39.2 27.5ZM36 44.5C36 39.5 39 36 43 36C47 36 50 39.5 50 44.5Z" fill="url(#g)" fill-opacity="0.45" fill-rule="evenodd"/><path d="M26.5 25A5.5 5.5 0 1 0 37.5 25A5.5 5.5 0 1 0 26.5 25ZM21 47.5C21 40.5 26 35.5 32 35.5C38 35.5 43 40.5 43 47.5A2.5 2.5 0 0 1 40.5 50H23.5A2.5 2.5 0 0 1 21 47.5Z" fill="url(#g)" fill-rule="evenodd"/></svg></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hgdc/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.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",
|
package/styles.css
CHANGED
|
@@ -299,6 +299,8 @@
|
|
|
299
299
|
--product-iassistant-to: #c026d3;
|
|
300
300
|
--product-id-from: #ff2a2a;
|
|
301
301
|
--product-id-to: #e60000;
|
|
302
|
+
--product-manager-from: #ff6a3d;
|
|
303
|
+
--product-manager-to: #fc582e;
|
|
302
304
|
--glow-blue: #2c78fd;
|
|
303
305
|
--glow-violet: #7343fe;
|
|
304
306
|
--glow-pink: #fe5292;
|
|
@@ -865,7 +867,8 @@
|
|
|
865
867
|
:root[data-hgdc-product="analytics"] [data-slot="shell-frame"] [data-product="analytics"],
|
|
866
868
|
:root[data-hgdc-product="docs"] [data-slot="shell-frame"] [data-product="docs"],
|
|
867
869
|
:root[data-hgdc-product="iassistant"] [data-slot="shell-frame"] [data-product="iassistant"],
|
|
868
|
-
:root[data-hgdc-product="id"] [data-slot="shell-frame"] [data-product="id"]
|
|
870
|
+
:root[data-hgdc-product="id"] [data-slot="shell-frame"] [data-product="id"],
|
|
871
|
+
:root[data-hgdc-product="manager"] [data-slot="shell-frame"] [data-product="manager"] {
|
|
869
872
|
display: contents;
|
|
870
873
|
}
|
|
871
874
|
:root[data-hgdc-product="account"] [data-slot="shell-frame-rail"] [data-product="account"],
|
|
@@ -876,7 +879,8 @@
|
|
|
876
879
|
:root[data-hgdc-product="analytics"] [data-slot="shell-frame-rail"] [data-product="analytics"],
|
|
877
880
|
:root[data-hgdc-product="docs"] [data-slot="shell-frame-rail"] [data-product="docs"],
|
|
878
881
|
:root[data-hgdc-product="iassistant"] [data-slot="shell-frame-rail"] [data-product="iassistant"],
|
|
879
|
-
:root[data-hgdc-product="id"] [data-slot="shell-frame-rail"] [data-product="id"]
|
|
882
|
+
:root[data-hgdc-product="id"] [data-slot="shell-frame-rail"] [data-product="id"],
|
|
883
|
+
:root[data-hgdc-product="manager"] [data-slot="shell-frame-rail"] [data-product="manager"] {
|
|
880
884
|
display: flex;
|
|
881
885
|
background: var(--shell-active);
|
|
882
886
|
color: var(--shell-foreground);
|
|
@@ -892,8 +896,8 @@
|
|
|
892
896
|
background: var(--shell-hover);
|
|
893
897
|
}
|
|
894
898
|
:root[data-hgdc-org] [data-slot="org-placeholder-mark"] {
|
|
895
|
-
background: var(--hgdc-org-logo, var(--foreground)) center / cover no-repeat;
|
|
896
|
-
color: var(--background);
|
|
899
|
+
background: var(--hgdc-org-logo, var(--hgdc-org-bg, var(--foreground))) center / cover no-repeat;
|
|
900
|
+
color: var(--hgdc-org-ink, var(--background));
|
|
897
901
|
}
|
|
898
902
|
:root[data-hgdc-org] [data-slot="org-placeholder-mark"]::before {
|
|
899
903
|
content: var(--hgdc-org-initials, "");
|