@datatechsolutions/ui 2.11.83 → 2.11.85

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.
Files changed (101) hide show
  1. package/dist/astrlabe/index.d.mts +3 -52
  2. package/dist/astrlabe/index.d.ts +3 -52
  3. package/dist/astrlabe/index.js +107 -107
  4. package/dist/astrlabe/index.mjs +4 -4
  5. package/dist/astrlabe/workflow-canvas.js +4 -4
  6. package/dist/astrlabe/workflow-canvas.mjs +3 -3
  7. package/dist/chunk-2URBM4LA.js +132 -0
  8. package/dist/chunk-2URBM4LA.js.map +1 -0
  9. package/dist/chunk-3T2WGL47.js +44 -0
  10. package/dist/chunk-3T2WGL47.js.map +1 -0
  11. package/dist/chunk-3YVQXDKJ.js +22 -0
  12. package/dist/chunk-3YVQXDKJ.js.map +1 -0
  13. package/dist/chunk-64G2HBRQ.mjs +481 -0
  14. package/dist/chunk-64G2HBRQ.mjs.map +1 -0
  15. package/dist/chunk-6F3IMKDZ.js +943 -0
  16. package/dist/chunk-6F3IMKDZ.js.map +1 -0
  17. package/dist/chunk-6OWYGDNW.mjs +941 -0
  18. package/dist/chunk-6OWYGDNW.mjs.map +1 -0
  19. package/dist/{chunk-J3OYJ44D.mjs → chunk-D4TESEYK.mjs} +3 -3
  20. package/dist/{chunk-J3OYJ44D.mjs.map → chunk-D4TESEYK.mjs.map} +1 -1
  21. package/dist/chunk-FAGDZEKM.js +23 -0
  22. package/dist/chunk-FAGDZEKM.js.map +1 -0
  23. package/dist/chunk-G7DZU3NM.mjs +412 -0
  24. package/dist/chunk-G7DZU3NM.mjs.map +1 -0
  25. package/dist/{chunk-UVGMKHWH.mjs → chunk-HK6J6HQP.mjs} +4 -4
  26. package/dist/{chunk-UVGMKHWH.mjs.map → chunk-HK6J6HQP.mjs.map} +1 -1
  27. package/dist/chunk-JUTOBBBI.mjs +210 -0
  28. package/dist/chunk-JUTOBBBI.mjs.map +1 -0
  29. package/dist/chunk-K26RY4EQ.js +214 -0
  30. package/dist/chunk-K26RY4EQ.js.map +1 -0
  31. package/dist/{chunk-TUEYBNWL.js → chunk-KNXAOJAK.js} +3 -3
  32. package/dist/{chunk-TUEYBNWL.js.map → chunk-KNXAOJAK.js.map} +1 -1
  33. package/dist/chunk-SV4SMITM.js +418 -0
  34. package/dist/chunk-SV4SMITM.js.map +1 -0
  35. package/dist/chunk-SYNVNTLJ.mjs +20 -0
  36. package/dist/chunk-SYNVNTLJ.mjs.map +1 -0
  37. package/dist/chunk-TLDVFFAK.mjs +20 -0
  38. package/dist/chunk-TLDVFFAK.mjs.map +1 -0
  39. package/dist/{chunk-M7P2TQ6X.js → chunk-TZ62G5WM.js} +64 -64
  40. package/dist/{chunk-M7P2TQ6X.js.map → chunk-TZ62G5WM.js.map} +1 -1
  41. package/dist/chunk-UQXVCVAN.mjs +41 -0
  42. package/dist/chunk-UQXVCVAN.mjs.map +1 -0
  43. package/dist/chunk-XOZMUCMF.mjs +128 -0
  44. package/dist/chunk-XOZMUCMF.mjs.map +1 -0
  45. package/dist/chunk-YXPHJ2BQ.js +541 -0
  46. package/dist/chunk-YXPHJ2BQ.js.map +1 -0
  47. package/dist/{chunk-JFWZHROG.js → chunk-ZHHRWC27.js} +128 -128
  48. package/dist/{chunk-JFWZHROG.js.map → chunk-ZHHRWC27.js.map} +1 -1
  49. package/dist/{chunk-LLFU42KC.mjs → chunk-ZJQ5RLGK.mjs} +3 -3
  50. package/dist/{chunk-LLFU42KC.mjs.map → chunk-ZJQ5RLGK.mjs.map} +1 -1
  51. package/dist/index.d.mts +3 -47
  52. package/dist/index.d.ts +3 -47
  53. package/dist/index.js +753 -753
  54. package/dist/index.mjs +2 -2
  55. package/dist/navigation-BiWVffAN.d.mts +49 -0
  56. package/dist/navigation-BiWVffAN.d.ts +49 -0
  57. package/dist/platform/agents-workspace.d.mts +19 -0
  58. package/dist/platform/agents-workspace.d.ts +19 -0
  59. package/dist/platform/agents-workspace.js +26 -0
  60. package/dist/platform/agents-workspace.js.map +1 -0
  61. package/dist/platform/agents-workspace.mjs +17 -0
  62. package/dist/platform/agents-workspace.mjs.map +1 -0
  63. package/dist/platform/app-shell.d.mts +58 -0
  64. package/dist/platform/app-shell.d.ts +58 -0
  65. package/dist/platform/app-shell.js +17 -0
  66. package/dist/platform/app-shell.js.map +1 -0
  67. package/dist/platform/app-shell.mjs +8 -0
  68. package/dist/platform/app-shell.mjs.map +1 -0
  69. package/dist/platform/index.d.mts +100 -3
  70. package/dist/platform/index.d.ts +100 -3
  71. package/dist/platform/index.js +499 -28
  72. package/dist/platform/index.js.map +1 -1
  73. package/dist/platform/index.mjs +472 -27
  74. package/dist/platform/index.mjs.map +1 -1
  75. package/dist/platform/pages/index.d.mts +243 -82
  76. package/dist/platform/pages/index.d.ts +243 -82
  77. package/dist/platform/pages/index.js +891 -614
  78. package/dist/platform/pages/index.js.map +1 -1
  79. package/dist/platform/pages/index.mjs +761 -511
  80. package/dist/platform/pages/index.mjs.map +1 -1
  81. package/dist/platform/utils/index.js +18 -56
  82. package/dist/platform/utils/index.js.map +1 -1
  83. package/dist/platform/utils/index.mjs +3 -53
  84. package/dist/platform/utils/index.mjs.map +1 -1
  85. package/dist/platform/workflow-api-client.d.mts +6 -0
  86. package/dist/platform/workflow-api-client.d.ts +6 -0
  87. package/dist/platform/workflow-api-client.js +246 -0
  88. package/dist/platform/workflow-api-client.js.map +1 -0
  89. package/dist/platform/workflow-api-client.mjs +5 -0
  90. package/dist/platform/workflow-api-client.mjs.map +1 -0
  91. package/dist/platform/workflow-canvas-shell.d.mts +18 -0
  92. package/dist/platform/workflow-canvas-shell.d.ts +18 -0
  93. package/dist/platform/workflow-canvas-shell.js +20 -0
  94. package/dist/platform/workflow-canvas-shell.js.map +1 -0
  95. package/dist/platform/workflow-canvas-shell.mjs +11 -0
  96. package/dist/platform/workflow-canvas-shell.mjs.map +1 -0
  97. package/dist/{rule-form-F5jBOeqk.d.mts → rule-form-BYJzyork.d.mts} +50 -1
  98. package/dist/{rule-form-F5jBOeqk.d.ts → rule-form-BYJzyork.d.ts} +50 -1
  99. package/dist/workflow-api-client-C8gPn_D1.d.mts +386 -0
  100. package/dist/workflow-api-client-Dy1Ph8W-.d.ts +386 -0
  101. package/package.json +21 -1
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ // src/platform/utils/workflow-graph-adapter.ts
3
+ function assertEntityConfig(node) {
4
+ if (node.type !== "entity") return node;
5
+ const config = node.data.config;
6
+ if (!config || config.type !== "entity") {
7
+ throw new Error(`Entity node ${node.id} is missing entity config`);
8
+ }
9
+ const entityConfig = config;
10
+ if (!entityConfig.entityMasterId || entityConfig.entityMasterId.trim().length === 0) {
11
+ throw new Error(`Entity node ${node.id} is missing required entityMasterId`);
12
+ }
13
+ return node;
14
+ }
15
+ function adaptWorkflowGraphToUi(graph) {
16
+ const nodes = graph.nodes.map((node) => assertEntityConfig(node));
17
+ return {
18
+ nodes,
19
+ edges: graph.edges,
20
+ viewport: graph.viewport
21
+ };
22
+ }
23
+
24
+ // src/platform/utils/format-duration.ts
25
+ function formatDurationMs(ms) {
26
+ if (ms === null || ms === void 0 || Number.isNaN(ms)) return "\u2014";
27
+ if (ms < 0) return "\u2014";
28
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
29
+ const totalSeconds = ms / 1e3;
30
+ if (totalSeconds < 60) return `${totalSeconds.toFixed(totalSeconds < 10 ? 2 : 1)}s`;
31
+ const minutes = Math.floor(totalSeconds / 60);
32
+ const seconds = Math.round(totalSeconds - minutes * 60);
33
+ if (minutes < 60) return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
34
+ const hours = Math.floor(minutes / 60);
35
+ const remainingMinutes = minutes - hours * 60;
36
+ return remainingMinutes === 0 ? `${hours}h` : `${hours}h ${remainingMinutes}m`;
37
+ }
38
+
39
+ export { adaptWorkflowGraphToUi, formatDurationMs };
40
+ //# sourceMappingURL=chunk-UQXVCVAN.mjs.map
41
+ //# sourceMappingURL=chunk-UQXVCVAN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platform/utils/workflow-graph-adapter.ts","../src/platform/utils/format-duration.ts"],"names":[],"mappings":";AAOA,SAAS,mBAAmB,IAAA,EAAsC;AAChE,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAEnC,EAAA,MAAM,MAAA,GAAS,KAAK,IAAA,CAAK,MAAA;AACzB,EAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,YAAA,EAAe,IAAA,CAAK,EAAE,CAAA,yBAAA,CAA2B,CAAA;AAAA,EACnE;AAEA,EAAA,MAAM,YAAA,GAAe,MAAA;AACrB,EAAA,IAAI,CAAC,aAAa,cAAA,IAAkB,YAAA,CAAa,eAAe,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AACnF,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,YAAA,EAAe,IAAA,CAAK,EAAE,CAAA,mCAAA,CAAqC,CAAA;AAAA,EAC7E;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,uBAAuB,KAAA,EAA6C;AAClF,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,kBAAA,CAAmB,IAAiC,CAAC,CAAA;AAC7F,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,UAAU,KAAA,CAAM;AAAA,GAClB;AACF;;;AC7BO,SAAS,iBAAiB,EAAA,EAAuC;AACtE,EAAA,IAAI,EAAA,KAAO,QAAQ,EAAA,KAAO,MAAA,IAAa,OAAO,KAAA,CAAM,EAAE,GAAG,OAAO,QAAA;AAChE,EAAA,IAAI,EAAA,GAAK,GAAG,OAAO,QAAA;AACnB,EAAA,IAAI,KAAK,GAAA,EAAO,OAAO,GAAG,IAAA,CAAK,KAAA,CAAM,EAAE,CAAC,CAAA,EAAA,CAAA;AAExC,EAAA,MAAM,eAAe,EAAA,GAAK,GAAA;AAC1B,EAAA,IAAI,YAAA,GAAe,EAAA,EAAI,OAAO,CAAA,EAAG,YAAA,CAAa,QAAQ,YAAA,GAAe,EAAA,GAAK,CAAA,GAAI,CAAC,CAAC,CAAA,CAAA,CAAA;AAEhF,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,EAAE,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,UAAU,EAAE,CAAA;AACtD,EAAA,IAAI,OAAA,GAAU,EAAA,EAAI,OAAO,OAAA,KAAY,CAAA,GAAI,CAAA,EAAG,OAAO,CAAA,CAAA,CAAA,GAAM,CAAA,EAAG,OAAO,CAAA,EAAA,EAAK,OAAO,CAAA,CAAA,CAAA;AAE/E,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,UAAU,KAAA,GAAQ,EAAA;AAC3C,EAAA,OAAO,gBAAA,KAAqB,IAAI,CAAA,EAAG,KAAK,MAAM,CAAA,EAAG,KAAK,KAAK,gBAAgB,CAAA,CAAA,CAAA;AAC7E","file":"chunk-UQXVCVAN.mjs","sourcesContent":["import type { WorkflowGraph as SharedWorkflowGraph } from '@datatechsolutions/shared-domain/ports/workflow'\nimport type {\n WorkflowGraph as UiWorkflowGraph,\n WorkflowNode as UiWorkflowNode,\n EntityNodeConfig as UiEntityNodeConfig,\n} from '../../astrlabe/contracts'\n\nfunction assertEntityConfig(node: UiWorkflowNode): UiWorkflowNode {\n if (node.type !== 'entity') return node\n\n const config = node.data.config\n if (!config || config.type !== 'entity') {\n throw new Error(`Entity node ${node.id} is missing entity config`)\n }\n\n const entityConfig = config as UiEntityNodeConfig\n if (!entityConfig.entityMasterId || entityConfig.entityMasterId.trim().length === 0) {\n throw new Error(`Entity node ${node.id} is missing required entityMasterId`)\n }\n\n return node\n}\n\nexport function adaptWorkflowGraphToUi(graph: SharedWorkflowGraph): UiWorkflowGraph {\n const nodes = graph.nodes.map((node) => assertEntityConfig(node as unknown as UiWorkflowNode))\n return {\n nodes,\n edges: graph.edges as UiWorkflowGraph['edges'],\n viewport: graph.viewport as UiWorkflowGraph['viewport'],\n }\n}\n","/** Formats a millisecond count as a short, human-readable duration string. */\nexport function formatDurationMs(ms: number | null | undefined): string {\n if (ms === null || ms === undefined || Number.isNaN(ms)) return '—'\n if (ms < 0) return '—'\n if (ms < 1_000) return `${Math.round(ms)}ms`\n\n const totalSeconds = ms / 1_000\n if (totalSeconds < 60) return `${totalSeconds.toFixed(totalSeconds < 10 ? 2 : 1)}s`\n\n const minutes = Math.floor(totalSeconds / 60)\n const seconds = Math.round(totalSeconds - minutes * 60)\n if (minutes < 60) return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`\n\n const hours = Math.floor(minutes / 60)\n const remainingMinutes = minutes - hours * 60\n return remainingMinutes === 0 ? `${hours}h` : `${hours}h ${remainingMinutes}m`\n}\n"]}
@@ -0,0 +1,128 @@
1
+ "use client";
2
+ import { useNotifications, PlatformShell, LOCALE_FLAGS } from './chunk-ZJQ5RLGK.mjs';
3
+ import { useTranslations, useLocale } from './chunk-7VJ7CMMT.mjs';
4
+ import { usePathname, useRouter } from './chunk-QWG2FMUN.mjs';
5
+ import { createContext, useMemo, useContext, useCallback } from 'react';
6
+ import { HomeIcon, RectangleStackIcon } from '@heroicons/react/24/outline';
7
+ import { useAuth, usePlatformPreferences } from '@datatechsolutions/windsock/client';
8
+ import { LANGUAGE_META } from '@datatechsolutions/shared-domain/i18n';
9
+ import { jsx } from 'react/jsx-runtime';
10
+
11
+ var PlatformStateContext = createContext(null);
12
+ function PlatformStateProvider({ children, normalizeRole }) {
13
+ const { user } = useAuth();
14
+ const state = useMemo(() => {
15
+ const organizationId = user?.organizationId ?? "";
16
+ const actor = user ? {
17
+ ...user,
18
+ role: normalizeRole(user.role),
19
+ organizationId
20
+ } : null;
21
+ return {
22
+ currentOrganizationId: organizationId,
23
+ actor
24
+ };
25
+ }, [user, normalizeRole]);
26
+ return /* @__PURE__ */ jsx(PlatformStateContext.Provider, { value: state, children });
27
+ }
28
+ function usePlatformState() {
29
+ const context = useContext(PlatformStateContext);
30
+ if (!context) throw new Error("usePlatformState must be used inside PlatformStateProvider");
31
+ return context;
32
+ }
33
+ function resolveFlag(locale) {
34
+ const code = locale === "pt-BR" ? "br" : locale;
35
+ return LOCALE_FLAGS?.[code];
36
+ }
37
+ function PlatformAppShell({
38
+ appName,
39
+ appGradient,
40
+ appLogo,
41
+ appIcon,
42
+ dashboardIcon,
43
+ navigationItems,
44
+ pageOrder,
45
+ modulePermissions,
46
+ hasPermission,
47
+ settingsModal,
48
+ children
49
+ }) {
50
+ const tCommon = useTranslations("common");
51
+ const { user, status, logout } = useAuth();
52
+ usePlatformState();
53
+ const { resolvedTheme, setTheme, dockPosition, dockAutoHide, dockEnabled } = usePlatformPreferences();
54
+ const pathname = usePathname();
55
+ const router = useRouter();
56
+ const { history, openHistory } = useNotifications();
57
+ const currentLocale = useLocale();
58
+ const localeMeta = LANGUAGE_META[currentLocale];
59
+ const items = useMemo(() => navigationItems.filter((item) => {
60
+ const permission = modulePermissions[item.id];
61
+ if (!permission) return true;
62
+ return hasPermission(permission);
63
+ }), [navigationItems, modulePermissions, hasPermission]);
64
+ const handleSignOut = useCallback(() => {
65
+ void logout("/login");
66
+ }, [logout]);
67
+ const handleToggleTheme = useCallback(
68
+ () => {
69
+ setTheme(resolvedTheme === "dark" ? "light" : "dark");
70
+ },
71
+ [resolvedTheme, setTheme]
72
+ );
73
+ const handleNavigate = useCallback((href) => router.push(href), [router]);
74
+ const handlePrefetch = useCallback((href) => router.prefetch(href), [router]);
75
+ const shellUser = user ? {
76
+ name: user.name ?? null,
77
+ email: user.email ?? null,
78
+ image: user.image ?? null,
79
+ role: user.role ?? null,
80
+ permissions: user.permissions,
81
+ organizationId: user.organizationId ?? null
82
+ } : null;
83
+ return /* @__PURE__ */ jsx(
84
+ PlatformShell,
85
+ {
86
+ items,
87
+ launchpadPageOrder: pageOrder,
88
+ user: shellUser,
89
+ authStatus: status,
90
+ onSignOut: handleSignOut,
91
+ dockPosition,
92
+ dockAutoHide,
93
+ dockEnabled,
94
+ resolvedTheme,
95
+ onToggleTheme: handleToggleTheme,
96
+ pathname,
97
+ onNavigate: handleNavigate,
98
+ onPrefetch: handlePrefetch,
99
+ appName,
100
+ appIcon: appIcon ?? /* @__PURE__ */ jsx(RectangleStackIcon, { className: "h-full w-full" }),
101
+ appLogo,
102
+ appGradient,
103
+ dashboardIcon: dashboardIcon ?? HomeIcon,
104
+ notificationCount: history.length,
105
+ onNotifications: openHistory,
106
+ labels: {
107
+ home: tCommon("home"),
108
+ profile: tCommon("profile"),
109
+ signOut: tCommon("signOut"),
110
+ signOutConfirmTitle: tCommon("signOutConfirmTitle"),
111
+ cancel: tCommon("cancel"),
112
+ notifications: tCommon("notifications"),
113
+ theme: tCommon("theme"),
114
+ currentTheme: resolvedTheme === "dark" ? tCommon("darkMode") : tCommon("lightMode"),
115
+ language: tCommon("language"),
116
+ currentLocale: localeMeta?.nativeName ?? currentLocale,
117
+ localeFlag: resolveFlag(currentLocale),
118
+ actions: tCommon("actions")
119
+ },
120
+ ...settingsModal ? { profileDrawer: settingsModal } : {},
121
+ children
122
+ }
123
+ );
124
+ }
125
+
126
+ export { PlatformAppShell, PlatformStateProvider, usePlatformState };
127
+ //# sourceMappingURL=chunk-XOZMUCMF.mjs.map
128
+ //# sourceMappingURL=chunk-XOZMUCMF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/platform/platform-state-provider.tsx","../src/platform/app-shell.tsx"],"names":["useAuth","useMemo","jsx"],"mappings":"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","file":"chunk-XOZMUCMF.mjs","sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport { useAuth, type AuthUser } from '@datatechsolutions/windsock/client'\n\ntype PlatformState = {\n currentOrganizationId: string\n actor: AuthUser | null\n}\n\nconst PlatformStateContext = createContext<PlatformState | null>(null)\n\nexport type PlatformStateProviderProps = {\n children: ReactNode\n /**\n * Function that converts a JWT role claim to the app's canonical role\n * union (the same `normalizePlatformRole` produced by\n * `createPlatformRbac()` in this app). Lifted out as a prop because\n * each consuming app uses its own role enum.\n */\n normalizeRole: (input: unknown) => string\n}\n\nexport function PlatformStateProvider({ children, normalizeRole }: PlatformStateProviderProps) {\n const { user } = useAuth()\n\n const state = useMemo<PlatformState>(() => {\n const organizationId = user?.organizationId ?? ''\n\n const actor: AuthUser | null = user\n ? {\n ...user,\n role: normalizeRole(user.role),\n organizationId,\n }\n : null\n\n return {\n currentOrganizationId: organizationId,\n actor,\n }\n }, [user, normalizeRole])\n\n return (\n <PlatformStateContext.Provider value={state}>\n {children}\n </PlatformStateContext.Provider>\n )\n}\n\nexport function usePlatformState() {\n const context = useContext(PlatformStateContext)\n if (!context) throw new Error('usePlatformState must be used inside PlatformStateProvider')\n return context\n}\n","import { useCallback, useMemo, type ComponentType, type ReactNode } from 'react'\nimport { RectangleStackIcon, HomeIcon } from '@heroicons/react/24/outline'\nimport { useAuth, usePlatformPreferences } from '@datatechsolutions/windsock/client'\nimport { LANGUAGE_META } from '@datatechsolutions/shared-domain/i18n'\nimport {\n PlatformShell,\n type NavigationItem,\n} from '@ui/index'\nimport { useNotifications } from '@ui/components/notifications'\nimport { useLocale, useTranslations } from '@ui/lib/i18n-context'\nimport { usePathname, useRouter } from '@ui/lib/router-context'\nimport { LOCALE_FLAGS } from '@ui/lib/locale-flags'\nimport { usePlatformState } from './platform-state-provider'\n\nfunction resolveFlag(locale: string): string | undefined {\n const code = locale === 'pt-BR' ? 'br' : locale\n return LOCALE_FLAGS?.[code as keyof typeof LOCALE_FLAGS]\n}\n\nexport type PlatformAppShellProps = {\n /** App display name (e.g. \"Astrlabe\"). */\n appName: string\n /** Tailwind gradient classes for the shell branding (e.g. \"from-sky-500 to-indigo-600\"). */\n appGradient: string\n /** Branded logo node rendered inside the flyout trigger. */\n appLogo: ReactNode\n /**\n * Optional app icon for the branded loader (defaults to the platform's\n * RectangleStackIcon if omitted).\n */\n appIcon?: ReactNode\n /**\n * Optional override for the dock dashboard icon (defaults to HomeIcon).\n */\n dashboardIcon?: ComponentType<{ className?: string }>\n\n /** App-specific navigation items already pre-translated. */\n navigationItems: NavigationItem[]\n /** Custom ordering of launchpad page tiles. */\n pageOrder: string[]\n /**\n * Map of navigation/module ID → required permission name. The shell\n * filters `navigationItems` so that any item whose ID has an entry here\n * is hidden unless `hasPermission` returns true for the listed permission.\n */\n modulePermissions: Record<string, string>\n /**\n * Permission predicate, typically `(p) => can(actor, p)` from each app's\n * `createPlatformRbac()` factory.\n */\n hasPermission: (permission: string) => boolean\n\n /**\n * Optional settings/profile drawer content (e.g. an app-specific\n * `<SettingsModal>`). Receives the open state + close handler the shell\n * manages internally so the drawer renders inside the shell chrome.\n */\n settingsModal?: (props: { open: boolean; onClose: () => void }) => ReactNode\n\n children: ReactNode\n}\n\n/**\n * Cross-app platform shell — wires `<PlatformShell>` from ui to windsock's\n * auth + preferences hooks and to ui's i18n/router contexts. Each app\n * passes its own logo, gradient, navigation, and permission predicate; the\n * rest of the chrome (header, dock, flyout, sign-out confirm modal) is\n * shared.\n */\nexport function PlatformAppShell({\n appName,\n appGradient,\n appLogo,\n appIcon,\n dashboardIcon,\n navigationItems,\n pageOrder,\n modulePermissions,\n hasPermission,\n settingsModal,\n children,\n}: PlatformAppShellProps) {\n const tCommon = useTranslations('common')\n const { user, status, logout } = useAuth()\n // Validate the platform-state provider is mounted above this shell;\n // the actor itself isn't read here, but the same provider feeds children.\n usePlatformState()\n const { resolvedTheme, setTheme, dockPosition, dockAutoHide, dockEnabled } = usePlatformPreferences()\n const pathname = usePathname()\n const router = useRouter()\n const { history, openHistory } = useNotifications()\n const currentLocale = useLocale()\n const localeMeta = LANGUAGE_META[currentLocale as keyof typeof LANGUAGE_META]\n\n const items = useMemo(() => navigationItems.filter((item) => {\n const permission = modulePermissions[item.id]\n if (!permission) return true\n return hasPermission(permission)\n }), [navigationItems, modulePermissions, hasPermission])\n\n const handleSignOut = useCallback(() => { void logout('/login') }, [logout])\n const handleToggleTheme = useCallback(\n () => { setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') },\n [resolvedTheme, setTheme],\n )\n const handleNavigate = useCallback((href: string) => router.push(href), [router])\n const handlePrefetch = useCallback((href: string) => router.prefetch(href), [router])\n\n const shellUser = user\n ? {\n name: user.name ?? null,\n email: user.email ?? null,\n image: user.image ?? null,\n role: user.role ?? null,\n permissions: user.permissions as string[] | undefined,\n organizationId: user.organizationId ?? null,\n }\n : null\n\n return (\n <PlatformShell\n items={items}\n launchpadPageOrder={pageOrder}\n user={shellUser}\n authStatus={status}\n onSignOut={handleSignOut}\n dockPosition={dockPosition}\n dockAutoHide={dockAutoHide}\n dockEnabled={dockEnabled}\n resolvedTheme={resolvedTheme}\n onToggleTheme={handleToggleTheme}\n pathname={pathname}\n onNavigate={handleNavigate}\n onPrefetch={handlePrefetch}\n appName={appName}\n appIcon={appIcon ?? <RectangleStackIcon className=\"h-full w-full\" />}\n appLogo={appLogo}\n appGradient={appGradient}\n dashboardIcon={dashboardIcon ?? HomeIcon}\n notificationCount={history.length}\n onNotifications={openHistory}\n labels={{\n home: tCommon('home'),\n profile: tCommon('profile'),\n signOut: tCommon('signOut'),\n signOutConfirmTitle: tCommon('signOutConfirmTitle'),\n cancel: tCommon('cancel'),\n notifications: tCommon('notifications'),\n theme: tCommon('theme'),\n currentTheme: resolvedTheme === 'dark' ? tCommon('darkMode') : tCommon('lightMode'),\n language: tCommon('language'),\n currentLocale: localeMeta?.nativeName ?? currentLocale,\n localeFlag: resolveFlag(currentLocale),\n actions: tCommon('actions'),\n }}\n {...(settingsModal ? { profileDrawer: settingsModal } : {})}\n >\n {children}\n </PlatformShell>\n )\n}\n"]}