@pablo2410/shared-ui 0.17.0 → 0.17.1
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/{HealthFooter-BIG3oto5.d.ts → HealthFooter-BnDhAj0x.d.ts} +1 -1
- package/dist/{chunk-FJEACO5I.js → chunk-R7B4WRSL.js} +22 -5
- package/dist/chunk-R7B4WRSL.js.map +1 -0
- package/dist/{chunk-NG6ZSZJU.js → chunk-XP2Y7YV6.js} +2 -2
- package/dist/{crossNav-BwdA3B2h.d.ts → crossNav-Bz0RXU_F.d.ts} +1 -1
- package/dist/hierarchy/core.d.ts +2 -2
- package/dist/hierarchy/index.d.ts +20 -3
- package/dist/hierarchy/index.js +3 -1
- package/dist/layout/index.d.ts +4 -4
- package/dist/layout/index.js +2 -2
- package/dist/{orgHierarchy-BVpunsrZ.d.ts → orgHierarchy-Buky69YP.d.ts} +1 -1
- package/dist/services/index.d.ts +2 -2
- package/dist/shell/index.d.ts +4 -4
- package/dist/shell/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FJEACO5I.js.map +0 -1
- /package/dist/{chunk-NG6ZSZJU.js.map → chunk-XP2Y7YV6.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React__default, { ReactNode, CSSProperties } from 'react';
|
|
3
|
-
import { C as CrossServiceLink } from './crossNav-
|
|
3
|
+
import { C as CrossServiceLink } from './crossNav-Bz0RXU_F.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* SharedSidebar — Config-driven sidebar component for all Oplytics subdomains.
|
|
@@ -284,6 +284,14 @@ function createOrgHierarchyContext(options) {
|
|
|
284
284
|
import { ChevronRight, ChevronDown, Building2, Network, MapPin, LayoutGrid, Box } from "lucide-react";
|
|
285
285
|
import { useState as useState2 } from "react";
|
|
286
286
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
287
|
+
function buildResetHandler(levels, level) {
|
|
288
|
+
const childLevels = levels.slice(levels.indexOf(level) + 1);
|
|
289
|
+
const hasSelectedChild = childLevels.some((l) => l.getSelected() !== null);
|
|
290
|
+
if (!hasSelectedChild) return void 0;
|
|
291
|
+
return () => {
|
|
292
|
+
for (const child of childLevels) child.onSelect(null);
|
|
293
|
+
};
|
|
294
|
+
}
|
|
287
295
|
function idReference(level, label, id) {
|
|
288
296
|
const short = level === "businessUnit" ? "BU" : label;
|
|
289
297
|
return `${short} #${id}`;
|
|
@@ -322,7 +330,8 @@ function BreadcrumbLevel({
|
|
|
322
330
|
compact,
|
|
323
331
|
renderDropdown,
|
|
324
332
|
selection,
|
|
325
|
-
hierarchyData
|
|
333
|
+
hierarchyData,
|
|
334
|
+
onClickReset
|
|
326
335
|
}) {
|
|
327
336
|
const nodes = config.getNodes();
|
|
328
337
|
const selected = config.getSelected();
|
|
@@ -333,13 +342,19 @@ function BreadcrumbLevel({
|
|
|
333
342
|
const code = hierarchyCodeFor(config.key, selection, selected.id, hierarchyData);
|
|
334
343
|
const refText = config.key === "enterprise" ? null : `${idReference(config.key, config.label, selected.id)}${code ? ` \xB7 ${code}` : ""}`;
|
|
335
344
|
if (!hasMultiple || !canSwitch) {
|
|
345
|
+
const isClickable = !!onClickReset && !isLast;
|
|
336
346
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
337
347
|
/* @__PURE__ */ jsxs(
|
|
338
|
-
"
|
|
348
|
+
"button",
|
|
339
349
|
{
|
|
350
|
+
type: "button",
|
|
351
|
+
onClick: isClickable ? onClickReset : void 0,
|
|
352
|
+
disabled: !isClickable,
|
|
340
353
|
className: cn(
|
|
341
|
-
"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs",
|
|
354
|
+
"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs text-left",
|
|
342
355
|
"text-[#E2E8F0]",
|
|
356
|
+
isClickable && "hover:bg-[#1E2738] hover:text-white transition-colors cursor-pointer",
|
|
357
|
+
!isClickable && "cursor-default",
|
|
343
358
|
compact && "px-1 py-0.5 text-[11px]"
|
|
344
359
|
),
|
|
345
360
|
children: [
|
|
@@ -560,7 +575,8 @@ function HierarchyNavigator({
|
|
|
560
575
|
compact,
|
|
561
576
|
renderDropdown,
|
|
562
577
|
selection: ctx.selection,
|
|
563
|
-
hierarchyData: ctx.hierarchyData
|
|
578
|
+
hierarchyData: ctx.hierarchyData,
|
|
579
|
+
onClickReset: buildResetHandler(levels, level)
|
|
564
580
|
},
|
|
565
581
|
level.key
|
|
566
582
|
)),
|
|
@@ -586,8 +602,9 @@ export {
|
|
|
586
602
|
computeHierarchyCode,
|
|
587
603
|
readActiveEnterpriseCookie,
|
|
588
604
|
createOrgHierarchyContext,
|
|
605
|
+
buildResetHandler,
|
|
589
606
|
idReference,
|
|
590
607
|
hierarchyCodeFor,
|
|
591
608
|
HierarchyNavigator
|
|
592
609
|
};
|
|
593
|
-
//# sourceMappingURL=chunk-
|
|
610
|
+
//# sourceMappingURL=chunk-R7B4WRSL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hierarchy/hierarchyCode.ts","../src/hierarchy/OrgHierarchyContext.tsx","../src/hierarchy/HierarchyNavigator.tsx"],"sourcesContent":["/**\n * @oplytics/shared-ui/hierarchy — Hierarchy Attribution Code\n *\n * A human-readable, computed-not-stored label identifying which hierarchy\n * node a piece of data belongs to: `E{enterpriseId}-B{ii}-S{ii}-A{ii}-X{iii}`.\n *\n * This is a *display/debug/attribution* label only — the permanent identity\n * of every node stays its Portal-issued `int` id. Re-parenting a node changes\n * its code (sibling index can shift) but never changes historical records,\n * since nothing stores this string as a join key. Mirrors Policy Deployment's\n * `generatePolicyCode` precedent: computed lineage, not stored structure.\n *\n * Sibling index is 1-based position when siblings are sorted by `id` —\n * deterministic and stable, since there's no reorder-hierarchy UI that could\n * change insertion order without changing the id.\n */\n\nimport type { OrgHierarchyData } from \"./orgHierarchy\";\n\nexport interface HierarchyCodeInput {\n enterpriseId: number;\n businessUnitId?: number | null;\n siteId?: number | null;\n areaId?: number | null;\n assetId?: number | null;\n}\n\nfunction siblingIndex(siblingIds: number[], targetId: number): number | null {\n const sorted = [...siblingIds].sort((a, b) => a - b);\n const position = sorted.indexOf(targetId);\n return position === -1 ? null : position + 1;\n}\n\nfunction pad(n: number, width: number): string {\n return String(n).padStart(width, \"0\");\n}\n\n/**\n * Computes a hierarchy attribution code for a node, given the full org tree.\n * Returns as much of the code as can be resolved — e.g. if `siteId` is set\n * but not found in `tree.sites`, the code stops at the last resolved segment\n * rather than throwing, since stale/cross-enterprise ids can occur during\n * migration/backfill windows.\n */\nexport function computeHierarchyCode(\n node: HierarchyCodeInput,\n tree: OrgHierarchyData\n): string {\n const segments: string[] = [`E${node.enterpriseId}`];\n\n if (node.businessUnitId == null) return segments.join(\"-\");\n const buSiblings = tree.businessUnits\n .filter((bu) => bu.enterpriseId === node.enterpriseId)\n .map((bu) => bu.id);\n const buIndex = siblingIndex(buSiblings, node.businessUnitId);\n if (buIndex == null) return segments.join(\"-\");\n segments.push(`B${pad(buIndex, 2)}`);\n\n if (node.siteId == null) return segments.join(\"-\");\n const siteSiblings = tree.sites\n .filter((s) => s.businessUnitId === node.businessUnitId)\n .map((s) => s.id);\n const siteIndex = siblingIndex(siteSiblings, node.siteId);\n if (siteIndex == null) return segments.join(\"-\");\n segments.push(`S${pad(siteIndex, 2)}`);\n\n if (node.areaId == null) return segments.join(\"-\");\n const areaSiblings = tree.areas\n .filter((a) => a.siteId === node.siteId)\n .map((a) => a.id);\n const areaIndex = siblingIndex(areaSiblings, node.areaId);\n if (areaIndex == null) return segments.join(\"-\");\n segments.push(`A${pad(areaIndex, 2)}`);\n\n if (node.assetId == null) return segments.join(\"-\");\n const assetSiblings = tree.assets\n .filter((a) => a.areaId === node.areaId)\n .map((a) => a.id);\n const assetIndex = siblingIndex(assetSiblings, node.assetId);\n if (assetIndex == null) return segments.join(\"-\");\n segments.push(`X${pad(assetIndex, 3)}`);\n\n return segments.join(\"-\");\n}\n","/**\n * OrgHierarchyContext — shared React context factory for the Organisational Hierarchy.\n *\n * Usage:\n * const { OrgHierarchyProvider, useOrgHierarchy } = createOrgHierarchyContext({\n * storageKey: \"oplytics-portal-org-hierarchy\",\n * useHierarchyData: () => {\n * const { data, isLoading } = trpc.hierarchy.flat.useQuery(...);\n * return { data: data ?? null, isLoading };\n * },\n * });\n *\n * All selection state, cascade setters, breadcrumbs, and session persistence\n * are handled here — no per-subdomain duplication.\n */\nimport {\n createContext,\n useContext,\n useCallback,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n} from \"react\";\nimport type {\n OrgHierarchyData,\n OrgHierarchyNode,\n OrgHierarchySelection,\n OrgHierarchyContextValue,\n} from \"./orgHierarchy\";\nimport { ORG_HIERARCHY_EMPTY } from \"./orgHierarchy\";\nimport { ACTIVE_ENTERPRISE_COOKIE } from \"./enterpriseOverride\";\nimport {\n readSelectionParamFromLocation,\n stripSelectionParamFromLocation,\n resolveSelectionFromIds,\n type OrgSelectionIds,\n} from \"./selectionParams\";\n\n/* ── Active-enterprise cookie (the single cross-subdomain channel) ── */\n\n/**\n * Read the Portal-set active-enterprise cookie on the client. This is the only\n * signal a subdomain has that the platform admin switched enterprise; the value\n * is the active enterprise id (or null if unset). Server-side, the same cookie\n * drives applyEnterpriseOverride + scopeHierarchyToEnterprise, so the fetched\n * hierarchy is already scoped to it — the client only needs to react to changes.\n */\nexport function readActiveEnterpriseCookie(): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\";\")\n .map((c) => c.trim())\n .find((c) => c.startsWith(`${ACTIVE_ENTERPRISE_COOKIE}=`));\n if (!match) return null;\n const value = decodeURIComponent(match.slice(ACTIVE_ENTERPRISE_COOKIE.length + 1));\n return value.length ? value : null;\n}\n\n/* ── Factory options ── */\n\nexport interface CreateOrgHierarchyContextOptions {\n /**\n * Unique sessionStorage key for this subdomain's selection persistence.\n * e.g. \"oplytics-portal-org-hierarchy\", \"oplytics-sqdcp-org-hierarchy\"\n */\n storageKey: string;\n\n /**\n * React hook that fetches the flat hierarchy data.\n * Must return { data, isLoading } where data is OrgHierarchyData | null.\n */\n useHierarchyData: () => {\n data: OrgHierarchyData | null;\n isLoading: boolean;\n };\n}\n\n/* ── Factory ── */\n\nexport function createOrgHierarchyContext(options: CreateOrgHierarchyContextOptions) {\n const { storageKey, useHierarchyData } = options;\n\n const OrgHierarchyCtx = createContext<OrgHierarchyContextValue>({\n selection: ORG_HIERARCHY_EMPTY,\n enterprises: [],\n businessUnits: [],\n sites: [],\n areas: [],\n assets: [],\n selectEnterprise: () => {},\n selectBusinessUnit: () => {},\n selectSite: () => {},\n selectArea: () => {},\n selectAsset: () => {},\n canSwitchEnterprise: false,\n loading: true,\n breadcrumbs: [],\n hierarchyData: null,\n });\n\n function OrgHierarchyProvider({\n children,\n canSwitchEnterprise = false,\n onEnterpriseSwitched,\n }: {\n children: ReactNode;\n canSwitchEnterprise?: boolean;\n /**\n * Callback fired when a platform_admin switches enterprise.\n * Used to persist the switch to the backend (e.g. via auth.switchEnterprise mutation).\n * Only called when canSwitchEnterprise is true and the user explicitly changes enterprise.\n */\n onEnterpriseSwitched?: (enterpriseId: number | null) => void;\n }) {\n // Single source of truth = the server-scoped hierarchy. We deliberately do\n // NOT restore a persisted selection on load — that is exactly what let one\n // tab/subdomain show a different enterprise than another. We always\n // re-derive from the server (which is scoped to the active enterprise).\n const [selection, setSelection] = useState<OrgHierarchySelection>(ORG_HIERARCHY_EMPTY);\n\n // Inbound cross-service deep link (?oh=ent.bu.site.area.asset). Captured\n // once with a pure lazy initializer (StrictMode-safe); applied against the\n // server-scoped hierarchy after it loads, then cleared. The URL param\n // itself is stripped in the mount effect below.\n const [pendingIds, setPendingIds] = useState<OrgSelectionIds | null>(() =>\n readSelectionParamFromLocation(),\n );\n\n // On mount: drop any legacy persisted selection, and hard-reload if the\n // active enterprise changes under us (i.e. the Portal admin switched).\n // Reloading lets the server re-scope this app to the new enterprise — the\n // single, identical propagation path for every subdomain. Cookies emit no\n // change event, so we re-check whenever the tab regains focus/visibility.\n useEffect(() => {\n try {\n sessionStorage.removeItem(storageKey);\n } catch {\n // ignore storage errors\n }\n\n // Clean the address bar immediately — the captured pendingIds state\n // survives independently of the URL.\n stripSelectionParamFromLocation();\n\n const activeAtMount = readActiveEnterpriseCookie();\n const reloadIfEnterpriseChanged = () => {\n if (typeof window !== \"undefined\" && readActiveEnterpriseCookie() !== activeAtMount) {\n window.location.reload();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"focus\", reloadIfEnterpriseChanged);\n document.addEventListener(\"visibilitychange\", reloadIfEnterpriseChanged);\n return () => {\n window.removeEventListener(\"focus\", reloadIfEnterpriseChanged);\n document.removeEventListener(\"visibilitychange\", reloadIfEnterpriseChanged);\n };\n }\n return undefined;\n // storageKey is stable for the lifetime of a factory instance.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Fetch hierarchy data via the provided hook\n const { data: hierarchy, isLoading } = useHierarchyData();\n\n // ── Derive filtered lists from flat data ──\n\n const enterprises = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.enterprises) return [];\n return hierarchy.enterprises.map((e) => ({\n id: e.id,\n name: e.name,\n code: e.code,\n }));\n }, [hierarchy]);\n\n const businessUnits = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.businessUnits || !selection.enterprise) return [];\n return hierarchy.businessUnits\n .filter((bu) => bu.enterpriseId === selection.enterprise!.id)\n .map((bu) => ({ id: bu.id, name: bu.name, code: bu.code }));\n }, [hierarchy, selection.enterprise]);\n\n const sites = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.sites || !selection.enterprise) return [];\n let filtered = hierarchy.sites.filter(\n (s) => s.enterpriseId === selection.enterprise!.id\n );\n if (selection.businessUnit) {\n filtered = filtered.filter(\n (s) => s.businessUnitId === selection.businessUnit!.id\n );\n }\n return filtered.map((s) => ({ id: s.id, name: s.name, code: s.code }));\n }, [hierarchy, selection.enterprise, selection.businessUnit]);\n\n const areas = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.areas || !selection.site) return [];\n return hierarchy.areas\n .filter((a) => a.siteId === selection.site!.id)\n .map((a) => ({ id: a.id, name: a.name, code: a.code }));\n }, [hierarchy, selection.site]);\n\n const assets = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.assets || !selection.area) return [];\n return hierarchy.assets\n .filter((a) => a.areaId === selection.area!.id)\n .map((a) => ({ id: a.id, name: a.name, code: a.code }));\n }, [hierarchy, selection.area]);\n\n // Apply an inbound cross-service deep link once the scoped hierarchy is\n // available. Resolution validates ids + parent links and keeps the deepest\n // valid prefix; a selection that doesn't resolve to an enterprise falls\n // through to the auto-select default below (re-triggered by clearing\n // pendingIds). Uses setSelection directly — deliberately NOT\n // selectEnterprise — so onEnterpriseSwitched is never fired by a deep link.\n useEffect(() => {\n if (!pendingIds || isLoading || !hierarchy) return;\n const resolved = resolveSelectionFromIds(pendingIds, hierarchy);\n if (resolved.enterprise) {\n setSelection(resolved);\n }\n setPendingIds(null);\n }, [pendingIds, isLoading, hierarchy]);\n\n // Auto-select an enterprise on load.\n // - Non-platform_admin (or platform_admin with only one visible\n // enterprise): always the first/only one, matching their access.\n // - platform_admin with multiple enterprises: restore whichever\n // enterprise they last switched to, via the same\n // oplytics-active-enterprise cookie switchEnterprise already sets for\n // cross-subdomain propagation. Falls through to leaving it unselected\n // if the cookie is unset or names an enterprise no longer in the list.\n useEffect(() => {\n // A pending deep link owns the initial selection; this effect re-runs\n // as the fallback when pendingIds clears.\n if (pendingIds) return;\n if (isLoading || enterprises.length === 0) return;\n if (!selection.enterprise) {\n if (!canSwitchEnterprise || enterprises.length === 1) {\n setSelection((prev) => ({ ...prev, enterprise: enterprises[0] }));\n } else {\n const cookieId = readActiveEnterpriseCookie();\n const restored = cookieId\n ? enterprises.find((e) => String(e.id) === cookieId)\n : undefined;\n if (restored) {\n setSelection((prev) => ({ ...prev, enterprise: restored }));\n }\n }\n }\n }, [pendingIds, isLoading, enterprises, selection.enterprise, canSwitchEnterprise]);\n\n // ── Cascade setters ──\n\n const selectEnterprise = useCallback((node: OrgHierarchyNode | null) => {\n setSelection({\n enterprise: node,\n businessUnit: null,\n site: null,\n area: null,\n asset: null,\n });\n // Notify backend of enterprise switch (platform_admin only)\n if (canSwitchEnterprise && onEnterpriseSwitched) {\n onEnterpriseSwitched(node?.id ?? null);\n }\n }, [canSwitchEnterprise, onEnterpriseSwitched]);\n\n const selectBusinessUnit = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n businessUnit: node,\n site: null,\n area: null,\n asset: null,\n }));\n }, []);\n\n const selectSite = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n site: node,\n area: null,\n asset: null,\n }));\n }, []);\n\n const selectArea = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n area: node,\n asset: null,\n }));\n }, []);\n\n const selectAsset = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n asset: node,\n }));\n }, []);\n\n // ── Breadcrumbs ──\n\n const breadcrumbs = useMemo(() => {\n const crumbs: { level: string; node: OrgHierarchyNode }[] = [];\n if (selection.enterprise)\n crumbs.push({ level: \"Enterprise\", node: selection.enterprise });\n if (selection.businessUnit)\n crumbs.push({ level: \"Business Unit\", node: selection.businessUnit });\n if (selection.site)\n crumbs.push({ level: \"Site\", node: selection.site });\n if (selection.area)\n crumbs.push({ level: \"Area\", node: selection.area });\n if (selection.asset)\n crumbs.push({ level: \"Asset\", node: selection.asset });\n return crumbs;\n }, [selection]);\n\n // ── Context value ──\n\n const value = useMemo<OrgHierarchyContextValue>(\n () => ({\n selection,\n enterprises,\n businessUnits,\n sites,\n areas,\n assets,\n selectEnterprise,\n selectBusinessUnit,\n selectSite,\n selectArea,\n selectAsset,\n canSwitchEnterprise,\n loading: isLoading,\n breadcrumbs,\n hierarchyData: hierarchy ?? null,\n }),\n [\n selection,\n enterprises,\n businessUnits,\n sites,\n areas,\n assets,\n selectEnterprise,\n selectBusinessUnit,\n selectSite,\n selectArea,\n selectAsset,\n canSwitchEnterprise,\n isLoading,\n breadcrumbs,\n hierarchy,\n ]\n );\n\n return (\n <OrgHierarchyCtx.Provider value={value}>\n {children}\n </OrgHierarchyCtx.Provider>\n );\n }\n\n function useOrgHierarchy(): OrgHierarchyContextValue {\n return useContext(OrgHierarchyCtx);\n }\n\n return { OrgHierarchyProvider, useOrgHierarchy };\n}\n\n/* ── Re-export types for convenience ── */\nexport type {\n OrgHierarchyNode,\n OrgHierarchyData,\n OrgHierarchySelection,\n OrgHierarchyContextValue,\n} from \"./orgHierarchy\";\n","/**\n * HierarchyNavigator — breadcrumb-style hierarchy switcher.\n *\n * Displays: Enterprise / BU / Site / Area / Asset\n * Each level is a clickable dropdown to switch context.\n * Platform admins can switch enterprises; others see their scoped enterprise.\n *\n * NOTE: This component requires the consuming app to provide:\n * - A hierarchy context via useHierarchy prop\n * - shadcn/ui DropdownMenu components via the renderDropdown prop\n *\n * For apps using the createOrgHierarchyContext factory, pass the useOrgHierarchy hook.\n *\n * Oplytics dark theme: #0A0E1A bg, #8C34E9 accent, #E2E8F0 text, #8890A0 muted\n */\nimport { cn } from \"../utils/cn\";\nimport type { OrgHierarchyNode, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchyLevel } from \"./orgHierarchy\";\nimport { computeHierarchyCode } from \"./hierarchyCode\";\nimport { ChevronRight, ChevronDown, Building2, Network, MapPin, LayoutGrid, Box } from \"lucide-react\";\nimport { useState, type ReactNode } from \"react\";\nimport { Tooltip, TooltipTrigger, TooltipContent } from \"../primitives\";\n\n/* ── Level config ── */\n\nexport interface LevelConfig {\n key: OrgHierarchyLevel;\n label: string;\n icon: React.ElementType;\n getNodes: () => OrgHierarchyNode[];\n getSelected: () => OrgHierarchyNode | null;\n onSelect: (node: OrgHierarchyNode | null) => void;\n canSwitch?: boolean;\n}\n\n/**\n * Builds the \"clear everything below this level\" handler for a breadcrumb\n * crumb — e.g. clicking \"Testa\" with a Site selected drops back to\n * enterprise-wide. Returns undefined when there's nothing selected below\n * `level` to clear, so callers can tell \"clickable\" from \"inert\" without\n * re-deriving the child slice themselves.\n */\nexport function buildResetHandler(\n levels: LevelConfig[],\n level: LevelConfig\n): (() => void) | undefined {\n const childLevels = levels.slice(levels.indexOf(level) + 1);\n const hasSelectedChild = childLevels.some((l) => l.getSelected() !== null);\n if (!hasSelectedChild) return undefined;\n return () => {\n for (const child of childLevels) child.onSelect(null);\n };\n}\n\n/**\n * \"Site #30002\" style reference text shown in small print under a selected\n * breadcrumb level — the raw id disambiguated by level, since ids aren't\n * unique across levels (a BU and a Site can share the same numeric id).\n */\nexport function idReference(level: OrgHierarchyLevel, label: string, id: number): string {\n const short = level === \"businessUnit\" ? \"BU\" : label;\n return `${short} #${id}`;\n}\n\n/**\n * Computes the E/B/S/A/X hierarchy attribution code for a selected node,\n * given the full unfiltered tree. Returns null when the tree isn't loaded\n * yet or the node can't be resolved (e.g. stale id mid-refetch) — callers\n * should just omit the sub-text rather than show a broken code.\n */\nexport function hierarchyCodeFor(\n level: OrgHierarchyLevel,\n selection: OrgHierarchyContextValue[\"selection\"],\n selectedId: number,\n tree: OrgHierarchyData | null\n): string | null {\n if (!tree || !selection.enterprise) return null;\n const enterpriseId = selection.enterprise.id;\n const input = {\n enterpriseId,\n businessUnitId: level === \"businessUnit\" ? selectedId : selection.businessUnit?.id,\n siteId: level === \"site\" ? selectedId : selection.site?.id,\n areaId: level === \"area\" ? selectedId : selection.area?.id,\n assetId: level === \"asset\" ? selectedId : selection.asset?.id,\n };\n const code = computeHierarchyCode(input, tree);\n // computeHierarchyCode returns as much as it could resolve — only show it\n // when it actually reached the level being rendered (same segment count\n // check used implicitly by prefix length: E, B, S, A, X).\n const expectedSegments = { enterprise: 1, businessUnit: 2, site: 3, area: 4, asset: 5 }[level];\n if (code.split(\"-\").length < expectedSegments) return null;\n return code;\n}\n\n/* ── Dropdown render prop types ── */\n\nexport interface DropdownRenderProps {\n trigger: ReactNode;\n items: Array<{\n key: number;\n label: string;\n code?: string;\n icon: React.ElementType;\n isActive: boolean;\n onClick: () => void;\n }>;\n align?: \"start\" | \"end\";\n}\n\n/* ── Single breadcrumb level ── */\n\n/**\n * Tiny muted reference line: raw id (disambiguated by level) plus the\n * computed hierarchy code, e.g. \"BU #30002 · E90011-B01\". Sits directly\n * under a breadcrumb segment's name — small enough not to compete with it,\n * but present for cross-checking against a support ticket or log line.\n */\nfunction LevelReference({ text, compact }: { text: string | null; compact?: boolean }) {\n if (!text) return null;\n return (\n <span\n className={cn(\n \"block leading-none text-[8px] text-[#596475] truncate max-w-[110px]\",\n compact && \"text-[7px]\"\n )}\n >\n {text}\n </span>\n );\n}\n\nfunction BreadcrumbLevel({\n config,\n isLast,\n compact,\n renderDropdown,\n selection,\n hierarchyData,\n onClickReset,\n}: {\n config: LevelConfig;\n isLast: boolean;\n compact?: boolean;\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n selection: OrgHierarchyContextValue[\"selection\"];\n hierarchyData: OrgHierarchyData | null;\n /**\n * Clears every level below this one, re-anchoring the view here — e.g.\n * clicking \"Testa\" with a Site selected drops back to enterprise-wide.\n * Only wired up when there's something below this level to clear; `isLast`\n * (nothing below) always renders inert regardless.\n */\n onClickReset?: () => void;\n}) {\n const nodes = config.getNodes();\n const selected = config.getSelected();\n const Icon = config.icon;\n const canSwitch = config.canSwitch !== false;\n const hasMultiple = nodes.length > 1;\n\n if (!selected) return null;\n\n const code = hierarchyCodeFor(config.key, selection, selected.id, hierarchyData);\n const refText =\n config.key === \"enterprise\"\n ? null // enterprise id alone is never ambiguous with another level\n : `${idReference(config.key, config.label, selected.id)}${code ? ` · ${code}` : \"\"}`;\n\n // If only one option or can't switch, there's nothing to pick between —\n // but clicking still clears any selected levels below (unless this is the\n // last/deepest crumb, where there's nothing below to clear).\n if (!hasMultiple || !canSwitch) {\n const isClickable = !!onClickReset && !isLast;\n return (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={isClickable ? onClickReset : undefined}\n disabled={!isClickable}\n className={cn(\n \"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs text-left\",\n \"text-[#E2E8F0]\",\n isClickable && \"hover:bg-[#1E2738] hover:text-white transition-colors cursor-pointer\",\n !isClickable && \"cursor-default\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <span className=\"flex items-center gap-1\">\n <Icon className={cn(\"shrink-0 text-[#8890A0]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n <span className=\"truncate max-w-[110px]\">{selected.name}</span>\n </span>\n <LevelReference text={refText} compact={compact} />\n </button>\n {!isLast && (\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n )}\n </div>\n );\n }\n\n // Multiple options — use renderDropdown if provided, otherwise basic button\n const trigger = (\n <button\n className={cn(\n \"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#E2E8F0] hover:bg-[#1E2738] hover:text-white\",\n \"transition-colors cursor-pointer outline-none\",\n \"focus-visible:ring-1 focus-visible:ring-[#8C34E9]\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <span className=\"flex items-center gap-1\">\n <Icon className={cn(\"shrink-0 text-[#8890A0]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n <span className=\"truncate max-w-[110px]\">{selected.name}</span>\n <ChevronDown className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n </span>\n <LevelReference text={refText} compact={compact} />\n </button>\n );\n\n const items = nodes.map((node) => ({\n key: node.id,\n label: node.name,\n code: node.code,\n icon: Icon,\n isActive: selected.id === node.id,\n onClick: () => config.onSelect(node),\n }));\n\n return (\n <div className=\"flex items-center gap-1\">\n {renderDropdown ? (\n renderDropdown({ trigger, items, align: \"start\" })\n ) : (\n // Fallback: simple select-style rendering\n <div className=\"relative group\">\n {trigger}\n </div>\n )}\n {!isLast && (\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n )}\n </div>\n );\n}\n\n/* ── Drill-down prompt ── */\n\nfunction DrillDownPrompt({\n label,\n icon: Icon,\n nodes,\n onSelect,\n compact,\n renderDropdown,\n canSwitch = true,\n}: {\n label: string;\n icon: React.ElementType;\n nodes: OrgHierarchyNode[];\n onSelect: (node: OrgHierarchyNode) => void;\n compact?: boolean;\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n canSwitch?: boolean;\n}) {\n const [showLockedHint, setShowLockedHint] = useState(false);\n\n if (nodes.length === 0) return null;\n\n // Locked: nothing is selected yet, but this level can't be changed from\n // here. Render static prompt text — clicking surfaces a brief explanation\n // instead of opening the picker.\n if (!canSwitch) {\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <Tooltip open={showLockedHint} onOpenChange={setShowLockedHint}>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setShowLockedHint((v) => !v)}\n onBlur={() => setShowLockedHint(false)}\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] cursor-not-allowed\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">Select {label}</span>\n </button>\n </TooltipTrigger>\n <TooltipContent>{label} can't be changed from this page</TooltipContent>\n </Tooltip>\n </div>\n );\n }\n\n // Auto-select if only one option\n if (nodes.length === 1) {\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <button\n onClick={() => onSelect(nodes[0])}\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] hover:bg-[#1E2738] hover:text-[#8890A0]\",\n \"transition-colors cursor-pointer\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">{nodes[0].name}</span>\n </button>\n </div>\n );\n }\n\n const trigger = (\n <button\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] hover:bg-[#1E2738] hover:text-[#8890A0]\",\n \"transition-colors cursor-pointer outline-none\",\n \"border border-dashed border-[#2A2A3E] hover:border-[#596475]\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">Select {label}</span>\n <ChevronDown className={cn(\"shrink-0\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n </button>\n );\n\n const items = nodes.map((node) => ({\n key: node.id,\n label: node.name,\n code: node.code,\n icon: Icon,\n isActive: false,\n onClick: () => onSelect(node),\n }));\n\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n {renderDropdown ? (\n renderDropdown({ trigger, items, align: \"start\" })\n ) : (\n <div className=\"relative group\">\n {trigger}\n </div>\n )}\n </div>\n );\n}\n\n/* ── Main component ── */\n\nexport interface HierarchyNavigatorProps {\n /** The hierarchy context value — pass from useOrgHierarchy() */\n hierarchy: OrgHierarchyContextValue;\n /** Show in compact mode (smaller text, tighter spacing) */\n compact?: boolean;\n /** Maximum depth to show (default: all 5 levels) */\n maxDepth?: number;\n /** CSS class for the container */\n className?: string;\n /**\n * Render prop for dropdown menus. If not provided, dropdowns won't open.\n * Consuming apps should pass a function that renders their shadcn/ui DropdownMenu.\n */\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n}\n\nexport function HierarchyNavigator({\n hierarchy: ctx,\n compact = false,\n maxDepth = 5,\n className,\n renderDropdown,\n}: HierarchyNavigatorProps) {\n if (ctx.loading) {\n return (\n <div className={cn(\"flex items-center gap-2 animate-pulse\", className)}>\n <div className=\"h-6 w-24 rounded bg-[#1E2738]\" />\n <ChevronRight className=\"h-3.5 w-3.5 text-[#596475]\" />\n <div className=\"h-6 w-20 rounded bg-[#1E2738]\" />\n </div>\n );\n }\n\n // Build the level configs\n const allLevels: LevelConfig[] = [\n {\n key: \"enterprise\",\n label: \"Enterprise\",\n icon: Building2,\n getNodes: () => ctx.enterprises,\n getSelected: () => ctx.selection.enterprise,\n onSelect: ctx.selectEnterprise,\n canSwitch: ctx.canSwitchEnterprise,\n },\n {\n key: \"businessUnit\",\n label: \"Business Unit\",\n icon: Network,\n getNodes: () => ctx.businessUnits,\n getSelected: () => ctx.selection.businessUnit,\n onSelect: ctx.selectBusinessUnit,\n },\n {\n key: \"site\",\n label: \"Site\",\n icon: MapPin,\n getNodes: () => ctx.sites,\n getSelected: () => ctx.selection.site,\n onSelect: ctx.selectSite,\n },\n {\n key: \"area\",\n label: \"Area\",\n icon: LayoutGrid,\n getNodes: () => ctx.areas,\n getSelected: () => ctx.selection.area,\n onSelect: ctx.selectArea,\n },\n {\n key: \"asset\",\n label: \"Asset\",\n icon: Box,\n getNodes: () => ctx.assets,\n getSelected: () => ctx.selection.asset,\n onSelect: ctx.selectAsset,\n },\n ];\n const levels = allLevels.slice(0, maxDepth);\n\n // Determine which levels are selected and which is the next drill-down\n const selectedLevels = levels.filter((l) => l.getSelected() !== null);\n const nextLevel = levels.find((l) => l.getSelected() === null && l.getNodes().length > 0);\n\n return (\n <nav\n className={cn(\"flex items-center flex-wrap gap-0.5\", className)}\n aria-label=\"Hierarchy navigation\"\n >\n {selectedLevels.map((level, idx) => (\n <BreadcrumbLevel\n key={level.key}\n config={level}\n isLast={idx === selectedLevels.length - 1 && !nextLevel}\n compact={compact}\n renderDropdown={renderDropdown}\n selection={ctx.selection}\n hierarchyData={ctx.hierarchyData}\n onClickReset={buildResetHandler(levels, level)}\n />\n ))}\n {nextLevel && (\n <DrillDownPrompt\n label={nextLevel.label}\n icon={nextLevel.icon}\n nodes={nextLevel.getNodes()}\n onSelect={nextLevel.onSelect}\n compact={compact}\n renderDropdown={renderDropdown}\n canSwitch={nextLevel.canSwitch !== false}\n />\n )}\n {selectedLevels.length === 0 && !nextLevel && (\n <span className=\"text-sm text-[#596475] italic\">No hierarchy data available</span>\n )}\n </nav>\n );\n}\n"],"mappings":"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","names":["useState","jsx","useState"]}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-4QJMLQSH.js";
|
|
5
5
|
import {
|
|
6
6
|
readActiveEnterpriseCookie
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R7B4WRSL.js";
|
|
8
8
|
import {
|
|
9
9
|
Avatar,
|
|
10
10
|
AvatarFallback,
|
|
@@ -1097,4 +1097,4 @@ export {
|
|
|
1097
1097
|
policyDeploymentConfig,
|
|
1098
1098
|
SERVICE_CONFIGS
|
|
1099
1099
|
};
|
|
1100
|
-
//# sourceMappingURL=chunk-
|
|
1100
|
+
//# sourceMappingURL=chunk-XP2Y7YV6.js.map
|
package/dist/hierarchy/core.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as OrgHierarchyData } from '../orgHierarchy-
|
|
2
|
-
export {
|
|
1
|
+
import { a as OrgHierarchyData } from '../orgHierarchy-Buky69YP.js';
|
|
2
|
+
export { e as ORG_HIERARCHY_DATA_EMPTY, f as ORG_HIERARCHY_EMPTY, g as ORG_HIERARCHY_LABELS, h as ORG_HIERARCHY_LEVELS, i as OrgHierarchyArea, j as OrgHierarchyAsset, k as OrgHierarchyBusinessUnit, b as OrgHierarchyContextValue, l as OrgHierarchyEnterprise, c as OrgHierarchyLevel, d as OrgHierarchyNode, O as OrgHierarchySelection, m as OrgHierarchySite } from '../orgHierarchy-Buky69YP.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Enterprise Override — shared helper for platform_admin enterprise switching.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as OrgHierarchyData, O as OrgHierarchySelection, b as OrgHierarchyContextValue, c as OrgHierarchyLevel } from '../orgHierarchy-
|
|
2
|
-
export {
|
|
1
|
+
import { a as OrgHierarchyData, O as OrgHierarchySelection, b as OrgHierarchyContextValue, c as OrgHierarchyLevel, d as OrgHierarchyNode } from '../orgHierarchy-Buky69YP.js';
|
|
2
|
+
export { e as ORG_HIERARCHY_DATA_EMPTY, f as ORG_HIERARCHY_EMPTY, g as ORG_HIERARCHY_LABELS, h as ORG_HIERARCHY_LEVELS, i as OrgHierarchyArea, j as OrgHierarchyAsset, k as OrgHierarchyBusinessUnit, l as OrgHierarchyEnterprise, m as OrgHierarchySite } from '../orgHierarchy-Buky69YP.js';
|
|
3
3
|
export { ACTIVE_ENTERPRISE_COOKIE, applyEnterpriseOverride, scopeHierarchyToEnterprise } from './core.js';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { ReactNode } from 'react';
|
|
@@ -128,6 +128,23 @@ declare function createOrgHierarchyContext(options: CreateOrgHierarchyContextOpt
|
|
|
128
128
|
useOrgHierarchy: () => OrgHierarchyContextValue;
|
|
129
129
|
};
|
|
130
130
|
|
|
131
|
+
interface LevelConfig {
|
|
132
|
+
key: OrgHierarchyLevel;
|
|
133
|
+
label: string;
|
|
134
|
+
icon: React.ElementType;
|
|
135
|
+
getNodes: () => OrgHierarchyNode[];
|
|
136
|
+
getSelected: () => OrgHierarchyNode | null;
|
|
137
|
+
onSelect: (node: OrgHierarchyNode | null) => void;
|
|
138
|
+
canSwitch?: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Builds the "clear everything below this level" handler for a breadcrumb
|
|
142
|
+
* crumb — e.g. clicking "Testa" with a Site selected drops back to
|
|
143
|
+
* enterprise-wide. Returns undefined when there's nothing selected below
|
|
144
|
+
* `level` to clear, so callers can tell "clickable" from "inert" without
|
|
145
|
+
* re-deriving the child slice themselves.
|
|
146
|
+
*/
|
|
147
|
+
declare function buildResetHandler(levels: LevelConfig[], level: LevelConfig): (() => void) | undefined;
|
|
131
148
|
/**
|
|
132
149
|
* "Site #30002" style reference text shown in small print under a selected
|
|
133
150
|
* breadcrumb level — the raw id disambiguated by level, since ids aren't
|
|
@@ -170,4 +187,4 @@ interface HierarchyNavigatorProps {
|
|
|
170
187
|
}
|
|
171
188
|
declare function HierarchyNavigator({ hierarchy: ctx, compact, maxDepth, className, renderDropdown, }: HierarchyNavigatorProps): react_jsx_runtime.JSX.Element;
|
|
172
189
|
|
|
173
|
-
export { type CreateOrgHierarchyContextOptions, type DropdownRenderProps, type HierarchyCodeInput, HierarchyNavigator, type HierarchyNavigatorProps, ORG_HIERARCHY_PARAM, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchyLevel, OrgHierarchySelection, type OrgSelectionIds, appendSelectionParam, computeHierarchyCode, createOrgHierarchyContext, hierarchyCodeFor, idReference, parseSelectionParam, readActiveEnterpriseCookie, readSelectionParamFromLocation, resolveSelectionFromIds, serializeSelectionParam, stripSelectionParamFromLocation };
|
|
190
|
+
export { type CreateOrgHierarchyContextOptions, type DropdownRenderProps, type HierarchyCodeInput, HierarchyNavigator, type HierarchyNavigatorProps, type LevelConfig, ORG_HIERARCHY_PARAM, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchyLevel, OrgHierarchyNode, OrgHierarchySelection, type OrgSelectionIds, appendSelectionParam, buildResetHandler, computeHierarchyCode, createOrgHierarchyContext, hierarchyCodeFor, idReference, parseSelectionParam, readActiveEnterpriseCookie, readSelectionParamFromLocation, resolveSelectionFromIds, serializeSelectionParam, stripSelectionParamFromLocation };
|
package/dist/hierarchy/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HierarchyNavigator,
|
|
3
|
+
buildResetHandler,
|
|
3
4
|
computeHierarchyCode,
|
|
4
5
|
createOrgHierarchyContext,
|
|
5
6
|
hierarchyCodeFor,
|
|
6
7
|
idReference,
|
|
7
8
|
readActiveEnterpriseCookie
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-R7B4WRSL.js";
|
|
9
10
|
import {
|
|
10
11
|
ORG_HIERARCHY_PARAM,
|
|
11
12
|
appendSelectionParam,
|
|
@@ -39,6 +40,7 @@ export {
|
|
|
39
40
|
ORG_HIERARCHY_PARAM,
|
|
40
41
|
appendSelectionParam,
|
|
41
42
|
applyEnterpriseOverride,
|
|
43
|
+
buildResetHandler,
|
|
42
44
|
computeHierarchyCode,
|
|
43
45
|
createOrgHierarchyContext,
|
|
44
46
|
hierarchyCodeFor,
|
package/dist/layout/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { S as SharedSidebarConfig } from '../HealthFooter-
|
|
2
|
-
export { C as CrossServiceNav, d as CrossServiceNavProps, D as DashboardLayout, a as DashboardLayoutEnterprise, b as DashboardLayoutProps, c as DashboardLayoutUser, H as HealthFooter, e as HealthFooterEnterprise, f as HealthFooterProps, g as HealthFooterUser, M as MenuItem, h as MenuSection, i as SharedSidebarProps, j as getInitials, k as isAdminRole, l as isMenuItemActive, u as useSidebarResize } from '../HealthFooter-
|
|
1
|
+
import { S as SharedSidebarConfig } from '../HealthFooter-BnDhAj0x.js';
|
|
2
|
+
export { C as CrossServiceNav, d as CrossServiceNavProps, D as DashboardLayout, a as DashboardLayoutEnterprise, b as DashboardLayoutProps, c as DashboardLayoutUser, H as HealthFooter, e as HealthFooterEnterprise, f as HealthFooterProps, g as HealthFooterUser, M as MenuItem, h as MenuSection, i as SharedSidebarProps, j as getInitials, k as isAdminRole, l as isMenuItemActive, u as useSidebarResize } from '../HealthFooter-BnDhAj0x.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
|
-
import '../crossNav-
|
|
6
|
-
import '../orgHierarchy-
|
|
5
|
+
import '../crossNav-Bz0RXU_F.js';
|
|
6
|
+
import '../orgHierarchy-Buky69YP.js';
|
|
7
7
|
|
|
8
8
|
interface DashboardLayoutSkeletonProps {
|
|
9
9
|
className?: string;
|
package/dist/layout/index.js
CHANGED
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
policyDeploymentConfig,
|
|
20
20
|
sqdcpConfig,
|
|
21
21
|
useSidebarResize
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-XP2Y7YV6.js";
|
|
23
23
|
import "../chunk-4QJMLQSH.js";
|
|
24
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-R7B4WRSL.js";
|
|
25
25
|
import "../chunk-IEBZGU6X.js";
|
|
26
26
|
import "../chunk-3G43UG63.js";
|
|
27
27
|
import "../chunk-HLMIR5UV.js";
|
|
@@ -95,4 +95,4 @@ type OrgHierarchyLevel = (typeof ORG_HIERARCHY_LEVELS)[number];
|
|
|
95
95
|
/** Human-readable labels for each level */
|
|
96
96
|
declare const ORG_HIERARCHY_LABELS: Record<OrgHierarchyLevel, string>;
|
|
97
97
|
|
|
98
|
-
export { type OrgHierarchySelection as O, type OrgHierarchyData as a, type OrgHierarchyContextValue as b, type OrgHierarchyLevel as c,
|
|
98
|
+
export { type OrgHierarchySelection as O, type OrgHierarchyData as a, type OrgHierarchyContextValue as b, type OrgHierarchyLevel as c, type OrgHierarchyNode as d, ORG_HIERARCHY_DATA_EMPTY as e, ORG_HIERARCHY_EMPTY as f, ORG_HIERARCHY_LABELS as g, ORG_HIERARCHY_LEVELS as h, type OrgHierarchyArea as i, type OrgHierarchyAsset as j, type OrgHierarchyBusinessUnit as k, type OrgHierarchyEnterprise as l, type OrgHierarchySite as m };
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as ADMIN_SEE_ALL_ROLES, B as BuildCrossServiceLinksOptions, C as CrossServiceLink, S as SLUG_ALIASES, b as buildCrossServiceLinks, n as normalizeServiceSlug } from '../crossNav-
|
|
2
|
-
import '../orgHierarchy-
|
|
1
|
+
export { A as ADMIN_SEE_ALL_ROLES, B as BuildCrossServiceLinksOptions, C as CrossServiceLink, S as SLUG_ALIASES, b as buildCrossServiceLinks, n as normalizeServiceSlug } from '../crossNav-Bz0RXU_F.js';
|
|
2
|
+
import '../orgHierarchy-Buky69YP.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Platform domain resolution — single source of truth for building
|
package/dist/shell/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { D as DashboardLayout, a as DashboardLayoutEnterprise, b as DashboardLayoutProps, c as DashboardLayoutUser } from '../HealthFooter-
|
|
2
|
-
export { C as CrossServiceNav, d as CrossServiceNavProps, H as HealthFooter, e as HealthFooterEnterprise, f as HealthFooterProps, g as HealthFooterUser, M as MenuItem, h as MenuSection } from '../HealthFooter-
|
|
3
|
-
export { C as CrossServiceLink, b as buildCrossServiceLinks } from '../crossNav-
|
|
1
|
+
import { D as DashboardLayout, a as DashboardLayoutEnterprise, b as DashboardLayoutProps, c as DashboardLayoutUser } from '../HealthFooter-BnDhAj0x.js';
|
|
2
|
+
export { C as CrossServiceNav, d as CrossServiceNavProps, H as HealthFooter, e as HealthFooterEnterprise, f as HealthFooterProps, g as HealthFooterUser, M as MenuItem, h as MenuSection } from '../HealthFooter-BnDhAj0x.js';
|
|
3
|
+
export { C as CrossServiceLink, b as buildCrossServiceLinks } from '../crossNav-Bz0RXU_F.js';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import 'react';
|
|
6
|
-
import '../orgHierarchy-
|
|
6
|
+
import '../orgHierarchy-Buky69YP.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @pablo2410/shared-ui/shell — Oplytics Service Shell
|
package/dist/shell/index.js
CHANGED
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
CrossServiceNav,
|
|
6
6
|
DashboardLayout,
|
|
7
7
|
HealthFooter
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-XP2Y7YV6.js";
|
|
9
9
|
import "../chunk-4QJMLQSH.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-R7B4WRSL.js";
|
|
11
11
|
import "../chunk-IEBZGU6X.js";
|
|
12
12
|
import "../chunk-3G43UG63.js";
|
|
13
13
|
import "../chunk-HLMIR5UV.js";
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hierarchy/hierarchyCode.ts","../src/hierarchy/OrgHierarchyContext.tsx","../src/hierarchy/HierarchyNavigator.tsx"],"sourcesContent":["/**\n * @oplytics/shared-ui/hierarchy — Hierarchy Attribution Code\n *\n * A human-readable, computed-not-stored label identifying which hierarchy\n * node a piece of data belongs to: `E{enterpriseId}-B{ii}-S{ii}-A{ii}-X{iii}`.\n *\n * This is a *display/debug/attribution* label only — the permanent identity\n * of every node stays its Portal-issued `int` id. Re-parenting a node changes\n * its code (sibling index can shift) but never changes historical records,\n * since nothing stores this string as a join key. Mirrors Policy Deployment's\n * `generatePolicyCode` precedent: computed lineage, not stored structure.\n *\n * Sibling index is 1-based position when siblings are sorted by `id` —\n * deterministic and stable, since there's no reorder-hierarchy UI that could\n * change insertion order without changing the id.\n */\n\nimport type { OrgHierarchyData } from \"./orgHierarchy\";\n\nexport interface HierarchyCodeInput {\n enterpriseId: number;\n businessUnitId?: number | null;\n siteId?: number | null;\n areaId?: number | null;\n assetId?: number | null;\n}\n\nfunction siblingIndex(siblingIds: number[], targetId: number): number | null {\n const sorted = [...siblingIds].sort((a, b) => a - b);\n const position = sorted.indexOf(targetId);\n return position === -1 ? null : position + 1;\n}\n\nfunction pad(n: number, width: number): string {\n return String(n).padStart(width, \"0\");\n}\n\n/**\n * Computes a hierarchy attribution code for a node, given the full org tree.\n * Returns as much of the code as can be resolved — e.g. if `siteId` is set\n * but not found in `tree.sites`, the code stops at the last resolved segment\n * rather than throwing, since stale/cross-enterprise ids can occur during\n * migration/backfill windows.\n */\nexport function computeHierarchyCode(\n node: HierarchyCodeInput,\n tree: OrgHierarchyData\n): string {\n const segments: string[] = [`E${node.enterpriseId}`];\n\n if (node.businessUnitId == null) return segments.join(\"-\");\n const buSiblings = tree.businessUnits\n .filter((bu) => bu.enterpriseId === node.enterpriseId)\n .map((bu) => bu.id);\n const buIndex = siblingIndex(buSiblings, node.businessUnitId);\n if (buIndex == null) return segments.join(\"-\");\n segments.push(`B${pad(buIndex, 2)}`);\n\n if (node.siteId == null) return segments.join(\"-\");\n const siteSiblings = tree.sites\n .filter((s) => s.businessUnitId === node.businessUnitId)\n .map((s) => s.id);\n const siteIndex = siblingIndex(siteSiblings, node.siteId);\n if (siteIndex == null) return segments.join(\"-\");\n segments.push(`S${pad(siteIndex, 2)}`);\n\n if (node.areaId == null) return segments.join(\"-\");\n const areaSiblings = tree.areas\n .filter((a) => a.siteId === node.siteId)\n .map((a) => a.id);\n const areaIndex = siblingIndex(areaSiblings, node.areaId);\n if (areaIndex == null) return segments.join(\"-\");\n segments.push(`A${pad(areaIndex, 2)}`);\n\n if (node.assetId == null) return segments.join(\"-\");\n const assetSiblings = tree.assets\n .filter((a) => a.areaId === node.areaId)\n .map((a) => a.id);\n const assetIndex = siblingIndex(assetSiblings, node.assetId);\n if (assetIndex == null) return segments.join(\"-\");\n segments.push(`X${pad(assetIndex, 3)}`);\n\n return segments.join(\"-\");\n}\n","/**\n * OrgHierarchyContext — shared React context factory for the Organisational Hierarchy.\n *\n * Usage:\n * const { OrgHierarchyProvider, useOrgHierarchy } = createOrgHierarchyContext({\n * storageKey: \"oplytics-portal-org-hierarchy\",\n * useHierarchyData: () => {\n * const { data, isLoading } = trpc.hierarchy.flat.useQuery(...);\n * return { data: data ?? null, isLoading };\n * },\n * });\n *\n * All selection state, cascade setters, breadcrumbs, and session persistence\n * are handled here — no per-subdomain duplication.\n */\nimport {\n createContext,\n useContext,\n useCallback,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n} from \"react\";\nimport type {\n OrgHierarchyData,\n OrgHierarchyNode,\n OrgHierarchySelection,\n OrgHierarchyContextValue,\n} from \"./orgHierarchy\";\nimport { ORG_HIERARCHY_EMPTY } from \"./orgHierarchy\";\nimport { ACTIVE_ENTERPRISE_COOKIE } from \"./enterpriseOverride\";\nimport {\n readSelectionParamFromLocation,\n stripSelectionParamFromLocation,\n resolveSelectionFromIds,\n type OrgSelectionIds,\n} from \"./selectionParams\";\n\n/* ── Active-enterprise cookie (the single cross-subdomain channel) ── */\n\n/**\n * Read the Portal-set active-enterprise cookie on the client. This is the only\n * signal a subdomain has that the platform admin switched enterprise; the value\n * is the active enterprise id (or null if unset). Server-side, the same cookie\n * drives applyEnterpriseOverride + scopeHierarchyToEnterprise, so the fetched\n * hierarchy is already scoped to it — the client only needs to react to changes.\n */\nexport function readActiveEnterpriseCookie(): string | null {\n if (typeof document === \"undefined\") return null;\n const match = document.cookie\n .split(\";\")\n .map((c) => c.trim())\n .find((c) => c.startsWith(`${ACTIVE_ENTERPRISE_COOKIE}=`));\n if (!match) return null;\n const value = decodeURIComponent(match.slice(ACTIVE_ENTERPRISE_COOKIE.length + 1));\n return value.length ? value : null;\n}\n\n/* ── Factory options ── */\n\nexport interface CreateOrgHierarchyContextOptions {\n /**\n * Unique sessionStorage key for this subdomain's selection persistence.\n * e.g. \"oplytics-portal-org-hierarchy\", \"oplytics-sqdcp-org-hierarchy\"\n */\n storageKey: string;\n\n /**\n * React hook that fetches the flat hierarchy data.\n * Must return { data, isLoading } where data is OrgHierarchyData | null.\n */\n useHierarchyData: () => {\n data: OrgHierarchyData | null;\n isLoading: boolean;\n };\n}\n\n/* ── Factory ── */\n\nexport function createOrgHierarchyContext(options: CreateOrgHierarchyContextOptions) {\n const { storageKey, useHierarchyData } = options;\n\n const OrgHierarchyCtx = createContext<OrgHierarchyContextValue>({\n selection: ORG_HIERARCHY_EMPTY,\n enterprises: [],\n businessUnits: [],\n sites: [],\n areas: [],\n assets: [],\n selectEnterprise: () => {},\n selectBusinessUnit: () => {},\n selectSite: () => {},\n selectArea: () => {},\n selectAsset: () => {},\n canSwitchEnterprise: false,\n loading: true,\n breadcrumbs: [],\n hierarchyData: null,\n });\n\n function OrgHierarchyProvider({\n children,\n canSwitchEnterprise = false,\n onEnterpriseSwitched,\n }: {\n children: ReactNode;\n canSwitchEnterprise?: boolean;\n /**\n * Callback fired when a platform_admin switches enterprise.\n * Used to persist the switch to the backend (e.g. via auth.switchEnterprise mutation).\n * Only called when canSwitchEnterprise is true and the user explicitly changes enterprise.\n */\n onEnterpriseSwitched?: (enterpriseId: number | null) => void;\n }) {\n // Single source of truth = the server-scoped hierarchy. We deliberately do\n // NOT restore a persisted selection on load — that is exactly what let one\n // tab/subdomain show a different enterprise than another. We always\n // re-derive from the server (which is scoped to the active enterprise).\n const [selection, setSelection] = useState<OrgHierarchySelection>(ORG_HIERARCHY_EMPTY);\n\n // Inbound cross-service deep link (?oh=ent.bu.site.area.asset). Captured\n // once with a pure lazy initializer (StrictMode-safe); applied against the\n // server-scoped hierarchy after it loads, then cleared. The URL param\n // itself is stripped in the mount effect below.\n const [pendingIds, setPendingIds] = useState<OrgSelectionIds | null>(() =>\n readSelectionParamFromLocation(),\n );\n\n // On mount: drop any legacy persisted selection, and hard-reload if the\n // active enterprise changes under us (i.e. the Portal admin switched).\n // Reloading lets the server re-scope this app to the new enterprise — the\n // single, identical propagation path for every subdomain. Cookies emit no\n // change event, so we re-check whenever the tab regains focus/visibility.\n useEffect(() => {\n try {\n sessionStorage.removeItem(storageKey);\n } catch {\n // ignore storage errors\n }\n\n // Clean the address bar immediately — the captured pendingIds state\n // survives independently of the URL.\n stripSelectionParamFromLocation();\n\n const activeAtMount = readActiveEnterpriseCookie();\n const reloadIfEnterpriseChanged = () => {\n if (typeof window !== \"undefined\" && readActiveEnterpriseCookie() !== activeAtMount) {\n window.location.reload();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"focus\", reloadIfEnterpriseChanged);\n document.addEventListener(\"visibilitychange\", reloadIfEnterpriseChanged);\n return () => {\n window.removeEventListener(\"focus\", reloadIfEnterpriseChanged);\n document.removeEventListener(\"visibilitychange\", reloadIfEnterpriseChanged);\n };\n }\n return undefined;\n // storageKey is stable for the lifetime of a factory instance.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Fetch hierarchy data via the provided hook\n const { data: hierarchy, isLoading } = useHierarchyData();\n\n // ── Derive filtered lists from flat data ──\n\n const enterprises = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.enterprises) return [];\n return hierarchy.enterprises.map((e) => ({\n id: e.id,\n name: e.name,\n code: e.code,\n }));\n }, [hierarchy]);\n\n const businessUnits = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.businessUnits || !selection.enterprise) return [];\n return hierarchy.businessUnits\n .filter((bu) => bu.enterpriseId === selection.enterprise!.id)\n .map((bu) => ({ id: bu.id, name: bu.name, code: bu.code }));\n }, [hierarchy, selection.enterprise]);\n\n const sites = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.sites || !selection.enterprise) return [];\n let filtered = hierarchy.sites.filter(\n (s) => s.enterpriseId === selection.enterprise!.id\n );\n if (selection.businessUnit) {\n filtered = filtered.filter(\n (s) => s.businessUnitId === selection.businessUnit!.id\n );\n }\n return filtered.map((s) => ({ id: s.id, name: s.name, code: s.code }));\n }, [hierarchy, selection.enterprise, selection.businessUnit]);\n\n const areas = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.areas || !selection.site) return [];\n return hierarchy.areas\n .filter((a) => a.siteId === selection.site!.id)\n .map((a) => ({ id: a.id, name: a.name, code: a.code }));\n }, [hierarchy, selection.site]);\n\n const assets = useMemo<OrgHierarchyNode[]>(() => {\n if (!hierarchy?.assets || !selection.area) return [];\n return hierarchy.assets\n .filter((a) => a.areaId === selection.area!.id)\n .map((a) => ({ id: a.id, name: a.name, code: a.code }));\n }, [hierarchy, selection.area]);\n\n // Apply an inbound cross-service deep link once the scoped hierarchy is\n // available. Resolution validates ids + parent links and keeps the deepest\n // valid prefix; a selection that doesn't resolve to an enterprise falls\n // through to the auto-select default below (re-triggered by clearing\n // pendingIds). Uses setSelection directly — deliberately NOT\n // selectEnterprise — so onEnterpriseSwitched is never fired by a deep link.\n useEffect(() => {\n if (!pendingIds || isLoading || !hierarchy) return;\n const resolved = resolveSelectionFromIds(pendingIds, hierarchy);\n if (resolved.enterprise) {\n setSelection(resolved);\n }\n setPendingIds(null);\n }, [pendingIds, isLoading, hierarchy]);\n\n // Auto-select an enterprise on load.\n // - Non-platform_admin (or platform_admin with only one visible\n // enterprise): always the first/only one, matching their access.\n // - platform_admin with multiple enterprises: restore whichever\n // enterprise they last switched to, via the same\n // oplytics-active-enterprise cookie switchEnterprise already sets for\n // cross-subdomain propagation. Falls through to leaving it unselected\n // if the cookie is unset or names an enterprise no longer in the list.\n useEffect(() => {\n // A pending deep link owns the initial selection; this effect re-runs\n // as the fallback when pendingIds clears.\n if (pendingIds) return;\n if (isLoading || enterprises.length === 0) return;\n if (!selection.enterprise) {\n if (!canSwitchEnterprise || enterprises.length === 1) {\n setSelection((prev) => ({ ...prev, enterprise: enterprises[0] }));\n } else {\n const cookieId = readActiveEnterpriseCookie();\n const restored = cookieId\n ? enterprises.find((e) => String(e.id) === cookieId)\n : undefined;\n if (restored) {\n setSelection((prev) => ({ ...prev, enterprise: restored }));\n }\n }\n }\n }, [pendingIds, isLoading, enterprises, selection.enterprise, canSwitchEnterprise]);\n\n // ── Cascade setters ──\n\n const selectEnterprise = useCallback((node: OrgHierarchyNode | null) => {\n setSelection({\n enterprise: node,\n businessUnit: null,\n site: null,\n area: null,\n asset: null,\n });\n // Notify backend of enterprise switch (platform_admin only)\n if (canSwitchEnterprise && onEnterpriseSwitched) {\n onEnterpriseSwitched(node?.id ?? null);\n }\n }, [canSwitchEnterprise, onEnterpriseSwitched]);\n\n const selectBusinessUnit = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n businessUnit: node,\n site: null,\n area: null,\n asset: null,\n }));\n }, []);\n\n const selectSite = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n site: node,\n area: null,\n asset: null,\n }));\n }, []);\n\n const selectArea = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n area: node,\n asset: null,\n }));\n }, []);\n\n const selectAsset = useCallback((node: OrgHierarchyNode | null) => {\n setSelection((prev) => ({\n ...prev,\n asset: node,\n }));\n }, []);\n\n // ── Breadcrumbs ──\n\n const breadcrumbs = useMemo(() => {\n const crumbs: { level: string; node: OrgHierarchyNode }[] = [];\n if (selection.enterprise)\n crumbs.push({ level: \"Enterprise\", node: selection.enterprise });\n if (selection.businessUnit)\n crumbs.push({ level: \"Business Unit\", node: selection.businessUnit });\n if (selection.site)\n crumbs.push({ level: \"Site\", node: selection.site });\n if (selection.area)\n crumbs.push({ level: \"Area\", node: selection.area });\n if (selection.asset)\n crumbs.push({ level: \"Asset\", node: selection.asset });\n return crumbs;\n }, [selection]);\n\n // ── Context value ──\n\n const value = useMemo<OrgHierarchyContextValue>(\n () => ({\n selection,\n enterprises,\n businessUnits,\n sites,\n areas,\n assets,\n selectEnterprise,\n selectBusinessUnit,\n selectSite,\n selectArea,\n selectAsset,\n canSwitchEnterprise,\n loading: isLoading,\n breadcrumbs,\n hierarchyData: hierarchy ?? null,\n }),\n [\n selection,\n enterprises,\n businessUnits,\n sites,\n areas,\n assets,\n selectEnterprise,\n selectBusinessUnit,\n selectSite,\n selectArea,\n selectAsset,\n canSwitchEnterprise,\n isLoading,\n breadcrumbs,\n hierarchy,\n ]\n );\n\n return (\n <OrgHierarchyCtx.Provider value={value}>\n {children}\n </OrgHierarchyCtx.Provider>\n );\n }\n\n function useOrgHierarchy(): OrgHierarchyContextValue {\n return useContext(OrgHierarchyCtx);\n }\n\n return { OrgHierarchyProvider, useOrgHierarchy };\n}\n\n/* ── Re-export types for convenience ── */\nexport type {\n OrgHierarchyNode,\n OrgHierarchyData,\n OrgHierarchySelection,\n OrgHierarchyContextValue,\n} from \"./orgHierarchy\";\n","/**\n * HierarchyNavigator — breadcrumb-style hierarchy switcher.\n *\n * Displays: Enterprise / BU / Site / Area / Asset\n * Each level is a clickable dropdown to switch context.\n * Platform admins can switch enterprises; others see their scoped enterprise.\n *\n * NOTE: This component requires the consuming app to provide:\n * - A hierarchy context via useHierarchy prop\n * - shadcn/ui DropdownMenu components via the renderDropdown prop\n *\n * For apps using the createOrgHierarchyContext factory, pass the useOrgHierarchy hook.\n *\n * Oplytics dark theme: #0A0E1A bg, #8C34E9 accent, #E2E8F0 text, #8890A0 muted\n */\nimport { cn } from \"../utils/cn\";\nimport type { OrgHierarchyNode, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchyLevel } from \"./orgHierarchy\";\nimport { computeHierarchyCode } from \"./hierarchyCode\";\nimport { ChevronRight, ChevronDown, Building2, Network, MapPin, LayoutGrid, Box } from \"lucide-react\";\nimport { useState, type ReactNode } from \"react\";\nimport { Tooltip, TooltipTrigger, TooltipContent } from \"../primitives\";\n\n/* ── Level config ── */\n\ninterface LevelConfig {\n key: OrgHierarchyLevel;\n label: string;\n icon: React.ElementType;\n getNodes: () => OrgHierarchyNode[];\n getSelected: () => OrgHierarchyNode | null;\n onSelect: (node: OrgHierarchyNode | null) => void;\n canSwitch?: boolean;\n}\n\n/**\n * \"Site #30002\" style reference text shown in small print under a selected\n * breadcrumb level — the raw id disambiguated by level, since ids aren't\n * unique across levels (a BU and a Site can share the same numeric id).\n */\nexport function idReference(level: OrgHierarchyLevel, label: string, id: number): string {\n const short = level === \"businessUnit\" ? \"BU\" : label;\n return `${short} #${id}`;\n}\n\n/**\n * Computes the E/B/S/A/X hierarchy attribution code for a selected node,\n * given the full unfiltered tree. Returns null when the tree isn't loaded\n * yet or the node can't be resolved (e.g. stale id mid-refetch) — callers\n * should just omit the sub-text rather than show a broken code.\n */\nexport function hierarchyCodeFor(\n level: OrgHierarchyLevel,\n selection: OrgHierarchyContextValue[\"selection\"],\n selectedId: number,\n tree: OrgHierarchyData | null\n): string | null {\n if (!tree || !selection.enterprise) return null;\n const enterpriseId = selection.enterprise.id;\n const input = {\n enterpriseId,\n businessUnitId: level === \"businessUnit\" ? selectedId : selection.businessUnit?.id,\n siteId: level === \"site\" ? selectedId : selection.site?.id,\n areaId: level === \"area\" ? selectedId : selection.area?.id,\n assetId: level === \"asset\" ? selectedId : selection.asset?.id,\n };\n const code = computeHierarchyCode(input, tree);\n // computeHierarchyCode returns as much as it could resolve — only show it\n // when it actually reached the level being rendered (same segment count\n // check used implicitly by prefix length: E, B, S, A, X).\n const expectedSegments = { enterprise: 1, businessUnit: 2, site: 3, area: 4, asset: 5 }[level];\n if (code.split(\"-\").length < expectedSegments) return null;\n return code;\n}\n\n/* ── Dropdown render prop types ── */\n\nexport interface DropdownRenderProps {\n trigger: ReactNode;\n items: Array<{\n key: number;\n label: string;\n code?: string;\n icon: React.ElementType;\n isActive: boolean;\n onClick: () => void;\n }>;\n align?: \"start\" | \"end\";\n}\n\n/* ── Single breadcrumb level ── */\n\n/**\n * Tiny muted reference line: raw id (disambiguated by level) plus the\n * computed hierarchy code, e.g. \"BU #30002 · E90011-B01\". Sits directly\n * under a breadcrumb segment's name — small enough not to compete with it,\n * but present for cross-checking against a support ticket or log line.\n */\nfunction LevelReference({ text, compact }: { text: string | null; compact?: boolean }) {\n if (!text) return null;\n return (\n <span\n className={cn(\n \"block leading-none text-[8px] text-[#596475] truncate max-w-[110px]\",\n compact && \"text-[7px]\"\n )}\n >\n {text}\n </span>\n );\n}\n\nfunction BreadcrumbLevel({\n config,\n isLast,\n compact,\n renderDropdown,\n selection,\n hierarchyData,\n}: {\n config: LevelConfig;\n isLast: boolean;\n compact?: boolean;\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n selection: OrgHierarchyContextValue[\"selection\"];\n hierarchyData: OrgHierarchyData | null;\n}) {\n const nodes = config.getNodes();\n const selected = config.getSelected();\n const Icon = config.icon;\n const canSwitch = config.canSwitch !== false;\n const hasMultiple = nodes.length > 1;\n\n if (!selected) return null;\n\n const code = hierarchyCodeFor(config.key, selection, selected.id, hierarchyData);\n const refText =\n config.key === \"enterprise\"\n ? null // enterprise id alone is never ambiguous with another level\n : `${idReference(config.key, config.label, selected.id)}${code ? ` · ${code}` : \"\"}`;\n\n // If only one option or can't switch, show as static text\n if (!hasMultiple || !canSwitch) {\n return (\n <div className=\"flex items-center gap-1\">\n <div\n className={cn(\n \"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#E2E8F0]\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <span className=\"flex items-center gap-1\">\n <Icon className={cn(\"shrink-0 text-[#8890A0]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n <span className=\"truncate max-w-[110px]\">{selected.name}</span>\n </span>\n <LevelReference text={refText} compact={compact} />\n </div>\n {!isLast && (\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n )}\n </div>\n );\n }\n\n // Multiple options — use renderDropdown if provided, otherwise basic button\n const trigger = (\n <button\n className={cn(\n \"flex flex-col justify-center px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#E2E8F0] hover:bg-[#1E2738] hover:text-white\",\n \"transition-colors cursor-pointer outline-none\",\n \"focus-visible:ring-1 focus-visible:ring-[#8C34E9]\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <span className=\"flex items-center gap-1\">\n <Icon className={cn(\"shrink-0 text-[#8890A0]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n <span className=\"truncate max-w-[110px]\">{selected.name}</span>\n <ChevronDown className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n </span>\n <LevelReference text={refText} compact={compact} />\n </button>\n );\n\n const items = nodes.map((node) => ({\n key: node.id,\n label: node.name,\n code: node.code,\n icon: Icon,\n isActive: selected.id === node.id,\n onClick: () => config.onSelect(node),\n }));\n\n return (\n <div className=\"flex items-center gap-1\">\n {renderDropdown ? (\n renderDropdown({ trigger, items, align: \"start\" })\n ) : (\n // Fallback: simple select-style rendering\n <div className=\"relative group\">\n {trigger}\n </div>\n )}\n {!isLast && (\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n )}\n </div>\n );\n}\n\n/* ── Drill-down prompt ── */\n\nfunction DrillDownPrompt({\n label,\n icon: Icon,\n nodes,\n onSelect,\n compact,\n renderDropdown,\n canSwitch = true,\n}: {\n label: string;\n icon: React.ElementType;\n nodes: OrgHierarchyNode[];\n onSelect: (node: OrgHierarchyNode) => void;\n compact?: boolean;\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n canSwitch?: boolean;\n}) {\n const [showLockedHint, setShowLockedHint] = useState(false);\n\n if (nodes.length === 0) return null;\n\n // Locked: nothing is selected yet, but this level can't be changed from\n // here. Render static prompt text — clicking surfaces a brief explanation\n // instead of opening the picker.\n if (!canSwitch) {\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <Tooltip open={showLockedHint} onOpenChange={setShowLockedHint}>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setShowLockedHint((v) => !v)}\n onBlur={() => setShowLockedHint(false)}\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] cursor-not-allowed\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">Select {label}</span>\n </button>\n </TooltipTrigger>\n <TooltipContent>{label} can't be changed from this page</TooltipContent>\n </Tooltip>\n </div>\n );\n }\n\n // Auto-select if only one option\n if (nodes.length === 1) {\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <button\n onClick={() => onSelect(nodes[0])}\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] hover:bg-[#1E2738] hover:text-[#8890A0]\",\n \"transition-colors cursor-pointer\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">{nodes[0].name}</span>\n </button>\n </div>\n );\n }\n\n const trigger = (\n <button\n className={cn(\n \"flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs\",\n \"text-[#596475] hover:bg-[#1E2738] hover:text-[#8890A0]\",\n \"transition-colors cursor-pointer outline-none\",\n \"border border-dashed border-[#2A2A3E] hover:border-[#596475]\",\n compact && \"px-1 py-0.5 text-[11px]\"\n )}\n >\n <Icon className={cn(\"shrink-0\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n <span className=\"truncate\">Select {label}</span>\n <ChevronDown className={cn(\"shrink-0\", compact ? \"h-2.5 w-2.5\" : \"h-3 w-3\")} />\n </button>\n );\n\n const items = nodes.map((node) => ({\n key: node.id,\n label: node.name,\n code: node.code,\n icon: Icon,\n isActive: false,\n onClick: () => onSelect(node),\n }));\n\n return (\n <div className=\"flex items-center gap-1\">\n <ChevronRight className={cn(\"shrink-0 text-[#596475]\", compact ? \"h-3 w-3\" : \"h-3.5 w-3.5\")} />\n {renderDropdown ? (\n renderDropdown({ trigger, items, align: \"start\" })\n ) : (\n <div className=\"relative group\">\n {trigger}\n </div>\n )}\n </div>\n );\n}\n\n/* ── Main component ── */\n\nexport interface HierarchyNavigatorProps {\n /** The hierarchy context value — pass from useOrgHierarchy() */\n hierarchy: OrgHierarchyContextValue;\n /** Show in compact mode (smaller text, tighter spacing) */\n compact?: boolean;\n /** Maximum depth to show (default: all 5 levels) */\n maxDepth?: number;\n /** CSS class for the container */\n className?: string;\n /**\n * Render prop for dropdown menus. If not provided, dropdowns won't open.\n * Consuming apps should pass a function that renders their shadcn/ui DropdownMenu.\n */\n renderDropdown?: (props: DropdownRenderProps) => ReactNode;\n}\n\nexport function HierarchyNavigator({\n hierarchy: ctx,\n compact = false,\n maxDepth = 5,\n className,\n renderDropdown,\n}: HierarchyNavigatorProps) {\n if (ctx.loading) {\n return (\n <div className={cn(\"flex items-center gap-2 animate-pulse\", className)}>\n <div className=\"h-6 w-24 rounded bg-[#1E2738]\" />\n <ChevronRight className=\"h-3.5 w-3.5 text-[#596475]\" />\n <div className=\"h-6 w-20 rounded bg-[#1E2738]\" />\n </div>\n );\n }\n\n // Build the level configs\n const allLevels: LevelConfig[] = [\n {\n key: \"enterprise\",\n label: \"Enterprise\",\n icon: Building2,\n getNodes: () => ctx.enterprises,\n getSelected: () => ctx.selection.enterprise,\n onSelect: ctx.selectEnterprise,\n canSwitch: ctx.canSwitchEnterprise,\n },\n {\n key: \"businessUnit\",\n label: \"Business Unit\",\n icon: Network,\n getNodes: () => ctx.businessUnits,\n getSelected: () => ctx.selection.businessUnit,\n onSelect: ctx.selectBusinessUnit,\n },\n {\n key: \"site\",\n label: \"Site\",\n icon: MapPin,\n getNodes: () => ctx.sites,\n getSelected: () => ctx.selection.site,\n onSelect: ctx.selectSite,\n },\n {\n key: \"area\",\n label: \"Area\",\n icon: LayoutGrid,\n getNodes: () => ctx.areas,\n getSelected: () => ctx.selection.area,\n onSelect: ctx.selectArea,\n },\n {\n key: \"asset\",\n label: \"Asset\",\n icon: Box,\n getNodes: () => ctx.assets,\n getSelected: () => ctx.selection.asset,\n onSelect: ctx.selectAsset,\n },\n ];\n const levels = allLevels.slice(0, maxDepth);\n\n // Determine which levels are selected and which is the next drill-down\n const selectedLevels = levels.filter((l) => l.getSelected() !== null);\n const nextLevel = levels.find((l) => l.getSelected() === null && l.getNodes().length > 0);\n\n return (\n <nav\n className={cn(\"flex items-center flex-wrap gap-0.5\", className)}\n aria-label=\"Hierarchy navigation\"\n >\n {selectedLevels.map((level, idx) => (\n <BreadcrumbLevel\n key={level.key}\n config={level}\n isLast={idx === selectedLevels.length - 1 && !nextLevel}\n compact={compact}\n renderDropdown={renderDropdown}\n selection={ctx.selection}\n hierarchyData={ctx.hierarchyData}\n />\n ))}\n {nextLevel && (\n <DrillDownPrompt\n label={nextLevel.label}\n icon={nextLevel.icon}\n nodes={nextLevel.getNodes()}\n onSelect={nextLevel.onSelect}\n compact={compact}\n renderDropdown={renderDropdown}\n canSwitch={nextLevel.canSwitch !== false}\n />\n )}\n {selectedLevels.length === 0 && !nextLevel && (\n <span className=\"text-sm text-[#596475] italic\">No hierarchy data available</span>\n )}\n </nav>\n );\n}\n"],"mappings":"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","names":["useState","jsx","useState"]}
|
|
File without changes
|