@elevasis/ui 2.40.0 → 2.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/app/index.d.ts +108 -0
  2. package/dist/app/index.js +8 -9
  3. package/dist/auth/index.js +3 -4
  4. package/dist/charts/index.js +3 -4
  5. package/dist/{chunk-7MTWRSUZ.js → chunk-56O7QQE7.js} +1 -2
  6. package/dist/{chunk-SHZT7ULK.js → chunk-66U7JOWV.js} +1 -1
  7. package/dist/{chunk-NKEXXL4O.js → chunk-A2XN6PR2.js} +3 -4
  8. package/dist/{chunk-K7GKKETO.js → chunk-FIMGOWOT.js} +1073 -586
  9. package/dist/{chunk-EEG6ALQR.js → chunk-JAN2ZXN5.js} +106 -24
  10. package/dist/{chunk-LJDYY3XB.js → chunk-JHVEA5NE.js} +1 -1
  11. package/dist/{chunk-A7IG36LB.js → chunk-L7GXUSCV.js} +1 -1
  12. package/dist/{chunk-DA6I5VEY.js → chunk-QVQMOQXB.js} +9 -3
  13. package/dist/{chunk-IUQAP4IO.js → chunk-S4R2ZQS7.js} +1 -1
  14. package/dist/{chunk-7PHY5ONQ.js → chunk-VAAU2Z3S.js} +1 -1
  15. package/dist/{chunk-LY3YTQC6.js → chunk-YPWN2WQ3.js} +2 -2
  16. package/dist/components/index.js +10 -11
  17. package/dist/components/navigation/index.js +2 -3
  18. package/dist/features/auth/index.js +32 -17
  19. package/dist/features/clients/index.js +10 -11
  20. package/dist/features/crm/index.js +10 -11
  21. package/dist/features/dashboard/index.js +10 -11
  22. package/dist/features/delivery/index.js +10 -11
  23. package/dist/features/knowledge/index.js +2 -3
  24. package/dist/features/lead-gen/index.d.ts +81 -0
  25. package/dist/features/lead-gen/index.js +10 -11
  26. package/dist/features/monitoring/index.js +10 -11
  27. package/dist/features/monitoring/requests/index.d.ts +69 -7
  28. package/dist/features/monitoring/requests/index.js +138 -17
  29. package/dist/features/operations/index.d.ts +79 -0
  30. package/dist/features/operations/index.js +10 -11
  31. package/dist/features/settings/index.js +10 -11
  32. package/dist/hooks/access/index.js +2 -3
  33. package/dist/hooks/delivery/index.js +10 -11
  34. package/dist/hooks/index.d.ts +18 -6
  35. package/dist/hooks/index.js +10 -11
  36. package/dist/hooks/published.d.ts +18 -6
  37. package/dist/hooks/published.js +10 -11
  38. package/dist/index.d.ts +151 -7
  39. package/dist/index.js +10 -11
  40. package/dist/knowledge/index.d.ts +81 -0
  41. package/dist/knowledge/index.js +6 -6
  42. package/dist/layout/index.d.ts +18 -2
  43. package/dist/layout/index.js +4 -2
  44. package/dist/organization/index.js +10 -11
  45. package/dist/provider/index.d.ts +120 -1
  46. package/dist/provider/index.js +6 -7
  47. package/dist/provider/published.d.ts +121 -2
  48. package/dist/provider/published.js +5 -6
  49. package/package.json +3 -3
  50. package/dist/chunk-J3FLIZY4.js +0 -423
@@ -4,6 +4,7 @@ import { QueryClient } from '@tanstack/react-query';
4
4
  import * as z from 'zod';
5
5
  import { z as z$1, ZodType } from 'zod';
6
6
  import { EventSourceMessage } from '@microsoft/fetch-event-source';
7
+ import { IconBrain } from '@tabler/icons-react';
7
8
 
8
9
  /** Framework-agnostic theme overrides bundled with a preset (fonts, radius, component styles). */
9
10
  interface FrameworkThemeOverrides {
@@ -3799,6 +3800,84 @@ declare const OrganizationModelSchema: z$1.ZodObject<{
3799
3800
  primary: z$1.ZodDefault<z$1.ZodRecord<z$1.ZodString, z$1.ZodType<SidebarNode, unknown, z$1.core.$ZodTypeInternals<SidebarNode, unknown>>>>;
3800
3801
  bottom: z$1.ZodDefault<z$1.ZodRecord<z$1.ZodString, z$1.ZodType<SidebarNode, unknown, z$1.core.$ZodTypeInternals<SidebarNode, unknown>>>>;
3801
3802
  }, z$1.core.$strip>>;
3803
+ topbar: z$1.ZodDefault<z$1.ZodRecord<z$1.ZodString, z$1.ZodObject<{
3804
+ id: z$1.ZodString;
3805
+ label: z$1.ZodString;
3806
+ tooltip: z$1.ZodOptional<z$1.ZodString>;
3807
+ icon: z$1.ZodOptional<z$1.ZodUnion<readonly [z$1.ZodEnum<{
3808
+ message: "message";
3809
+ error: "error";
3810
+ agent: "agent";
3811
+ workflow: "workflow";
3812
+ "google-sheets": "google-sheets";
3813
+ dashboard: "dashboard";
3814
+ calendar: "calendar";
3815
+ sales: "sales";
3816
+ crm: "crm";
3817
+ "lead-gen": "lead-gen";
3818
+ projects: "projects";
3819
+ clients: "clients";
3820
+ operations: "operations";
3821
+ monitoring: "monitoring";
3822
+ knowledge: "knowledge";
3823
+ settings: "settings";
3824
+ admin: "admin";
3825
+ archive: "archive";
3826
+ business: "business";
3827
+ finance: "finance";
3828
+ platform: "platform";
3829
+ seo: "seo";
3830
+ playbook: "playbook";
3831
+ strategy: "strategy";
3832
+ reference: "reference";
3833
+ integration: "integration";
3834
+ database: "database";
3835
+ user: "user";
3836
+ team: "team";
3837
+ gmail: "gmail";
3838
+ attio: "attio";
3839
+ overview: "overview";
3840
+ "command-view": "command-view";
3841
+ "command-queue": "command-queue";
3842
+ pipeline: "pipeline";
3843
+ lists: "lists";
3844
+ resources: "resources";
3845
+ approve: "approve";
3846
+ reject: "reject";
3847
+ retry: "retry";
3848
+ edit: "edit";
3849
+ view: "view";
3850
+ launch: "launch";
3851
+ "message-plus": "message-plus";
3852
+ escalate: "escalate";
3853
+ promote: "promote";
3854
+ submit: "submit";
3855
+ email: "email";
3856
+ success: "success";
3857
+ warning: "warning";
3858
+ info: "info";
3859
+ pending: "pending";
3860
+ bolt: "bolt";
3861
+ building: "building";
3862
+ briefcase: "briefcase";
3863
+ apps: "apps";
3864
+ graph: "graph";
3865
+ shield: "shield";
3866
+ users: "users";
3867
+ "chart-bar": "chart-bar";
3868
+ search: "search";
3869
+ }>, z$1.ZodString]>>;
3870
+ order: z$1.ZodOptional<z$1.ZodNumber>;
3871
+ enabled: z$1.ZodDefault<z$1.ZodBoolean>;
3872
+ devOnly: z$1.ZodOptional<z$1.ZodBoolean>;
3873
+ requiresAdmin: z$1.ZodOptional<z$1.ZodBoolean>;
3874
+ targets: z$1.ZodOptional<z$1.ZodDefault<z$1.ZodObject<{
3875
+ systems: z$1.ZodOptional<z$1.ZodDefault<z$1.ZodArray<z$1.ZodString>>>;
3876
+ entities: z$1.ZodOptional<z$1.ZodDefault<z$1.ZodArray<z$1.ZodString>>>;
3877
+ resources: z$1.ZodOptional<z$1.ZodDefault<z$1.ZodArray<z$1.ZodString>>>;
3878
+ actions: z$1.ZodOptional<z$1.ZodDefault<z$1.ZodArray<z$1.ZodString>>>;
3879
+ }, z$1.core.$strip>>>;
3880
+ }, z$1.core.$strip>>>;
3802
3881
  }, z$1.core.$strip>>;
3803
3882
  identity: z$1.ZodDefault<z$1.ZodObject<{
3804
3883
  mission: z$1.ZodDefault<z$1.ZodString>;
@@ -4467,6 +4546,7 @@ declare const OrganizationModelSchema: z$1.ZodObject<{
4467
4546
  edit: "edit";
4468
4547
  view: "view";
4469
4548
  launch: "launch";
4549
+ "message-plus": "message-plus";
4470
4550
  escalate: "escalate";
4471
4551
  promote: "promote";
4472
4552
  submit: "submit";
@@ -4832,6 +4912,8 @@ interface SSEConnectionManagerLike {
4832
4912
  }>;
4833
4913
  }
4834
4914
 
4915
+ type TablerIconComponent = typeof IconBrain;
4916
+
4835
4917
  type ElevasisOrganizationModel = Omit<OrganizationModel, 'knowledge'> & {
4836
4918
  knowledge?: OrganizationModel['knowledge'];
4837
4919
  };
@@ -4915,6 +4997,39 @@ interface ResolvedShellRouteMatch {
4915
4997
  interface ShellRuntime {
4916
4998
  resolveRoute: (path: string) => ResolvedShellRouteMatch;
4917
4999
  }
5000
+ /**
5001
+ * A resolved topbar action — the OM node after gating/filtering, with icon resolved
5002
+ * from the semantic icon registry. Passed to `TopbarActionModule.render`.
5003
+ */
5004
+ interface ResolvedTopbarAction {
5005
+ id: string;
5006
+ label: string;
5007
+ tooltip?: string;
5008
+ icon: TablerIconComponent;
5009
+ order: number;
5010
+ }
5011
+ /**
5012
+ * A topbar action module — binds a registry key to UI behavior (a render callback).
5013
+ * The key must match `navigation.topbar[id]`. The OM supplies data + visibility;
5014
+ * the module supplies behavior.
5015
+ */
5016
+ interface TopbarActionModule {
5017
+ /** Stable key that matches the `id` of a `navigation.topbar` node. */
5018
+ key: string;
5019
+ /** Render the topbar action. Receives the resolved OM node (icon pre-resolved). */
5020
+ render: (ctx: {
5021
+ node: ResolvedTopbarAction;
5022
+ }) => ReactNode;
5023
+ }
5024
+ /** A joined entry emitted by `getTopbarActions`: resolved OM node + module behavior. */
5025
+ interface ResolvedTopbarActionEntry {
5026
+ node: ResolvedTopbarAction;
5027
+ render: TopbarActionModule['render'];
5028
+ }
5029
+ interface TopbarActionsProjectionOptions {
5030
+ isPlatformAdmin?: boolean;
5031
+ isDev?: boolean;
5032
+ }
4918
5033
  interface OrganizationGraphSystemBridge {
4919
5034
  systemId?: string;
4920
5035
  }
@@ -4925,6 +5040,8 @@ interface OrganizationGraphContextValue {
4925
5040
  }
4926
5041
  interface ElevasisSystemsProviderProps {
4927
5042
  systems?: SystemModule[];
5043
+ /** Registered topbar action modules. OM node presence controls visibility; module supplies behavior. */
5044
+ topbarActions?: TopbarActionModule[];
4928
5045
  organizationModel?: ElevasisOrganizationModel;
4929
5046
  timeRange?: TimeRange;
4930
5047
  operationsApiUrl?: string;
@@ -4938,6 +5055,8 @@ interface ElevasisSystemsContextValue {
4938
5055
  shellModel: ResolvedShellModel;
4939
5056
  shellRuntime: ShellRuntime;
4940
5057
  getSidebarLinks: (options?: ShellSidebarProjectionOptions) => ShellSidebarLinkGroup[];
5058
+ /** Returns the list of topbar actions visible to the current user, in order. */
5059
+ getTopbarActions: (options?: TopbarActionsProjectionOptions) => ResolvedTopbarActionEntry[];
4941
5060
  enabledResolvedSystems: ResolvedSystemModule[];
4942
5061
  resolvedSystems: ResolvedSystemModule[];
4943
5062
  organizationGraph: OrganizationGraphContextValue;
@@ -4954,7 +5073,7 @@ interface ElevasisSystemsContextValue {
4954
5073
 
4955
5074
  declare function useElevasisSystems(): ElevasisSystemsContextValue;
4956
5075
  declare function useOptionalElevasisSystems(): ElevasisSystemsContextValue | null;
4957
- declare function ElevasisSystemsProvider({ systems, organizationModel, timeRange, operationsApiUrl, operationsSSEManager, deliveryApiUrl, deliverySSEManager, disabledSubsectionPaths, children }: ElevasisSystemsProviderProps): react_jsx_runtime.JSX.Element;
5076
+ declare function ElevasisSystemsProvider({ systems, topbarActions, organizationModel, timeRange, operationsApiUrl, operationsSSEManager, deliveryApiUrl, deliverySSEManager, disabledSubsectionPaths, children }: ElevasisSystemsProviderProps): react_jsx_runtime.JSX.Element;
4958
5077
 
4959
5078
  declare function SystemShell({ children }: {
4960
5079
  children: ReactNode;
@@ -5003,4 +5122,4 @@ declare function useElevasisServices(): ElevasisServiceContextValue;
5003
5122
  declare function ElevasisServiceProvider({ apiRequest, organizationId, workOSOrganizationId, isReady, children }: ElevasisServiceProviderProps): react_jsx_runtime.JSX.Element;
5004
5123
 
5005
5124
  export { AppearanceProvider, ElevasisCoreProvider, ElevasisServiceProvider, ElevasisSystemsProvider, NotificationProvider, SystemShell, useAppearance, useElevasisServices, useElevasisSystems, useNotificationAdapter, useOptionalElevasisSystems };
5006
- export type { ApiKeyConfig, AppearanceConfig, AuthConfig, AuthKitConfig, ElevasisCoreProviderProps, ElevasisCoreThemeConfig, ElevasisServiceContextValue, ElevasisServiceProviderProps, ElevasisSystemsContextValue, ElevasisSystemsProviderProps, ElevasisTokenOverrides, NotificationAdapter, OrganizationGraphContextValue, OrganizationGraphSystemBridge, ResolvedShellModel, ResolvedShellRouteMatch, ResolvedShellSystem, ResolvedSystemAccess, ResolvedSystemModule, ResolvedSystemSemantics, ShellRouteMatchStatus, ShellRuntime, ShellSidebarLinkGroup, ShellSidebarLinkItem, ShellSidebarProjectionOptions, SystemIconComponent, SystemModule, SystemSidebarComponent, WithSchemes };
5125
+ export type { ApiKeyConfig, AppearanceConfig, AuthConfig, AuthKitConfig, ElevasisCoreProviderProps, ElevasisCoreThemeConfig, ElevasisServiceContextValue, ElevasisServiceProviderProps, ElevasisSystemsContextValue, ElevasisSystemsProviderProps, ElevasisTokenOverrides, NotificationAdapter, OrganizationGraphContextValue, OrganizationGraphSystemBridge, ResolvedShellModel, ResolvedShellRouteMatch, ResolvedShellSystem, ResolvedSystemAccess, ResolvedSystemModule, ResolvedSystemSemantics, ResolvedTopbarAction, ResolvedTopbarActionEntry, ShellRouteMatchStatus, ShellRuntime, ShellSidebarLinkGroup, ShellSidebarLinkItem, ShellSidebarProjectionOptions, SystemIconComponent, SystemModule, SystemSidebarComponent, TopbarActionModule, TopbarActionsProjectionOptions, WithSchemes };
@@ -1,8 +1,8 @@
1
- export { ElevasisCoreProvider, NotificationProvider, SystemShell, useNotificationAdapter } from '../chunk-LY3YTQC6.js';
1
+ export { ElevasisCoreProvider, NotificationProvider, SystemShell, useNotificationAdapter } from '../chunk-YPWN2WQ3.js';
2
2
  import '../chunk-CTJBPF3Z.js';
3
3
  import '../chunk-3KMDHCAR.js';
4
4
  import '../chunk-S3XR4II4.js';
5
- export { AppearanceProvider, useAppearance } from '../chunk-A7IG36LB.js';
5
+ export { AppearanceProvider, useAppearance } from '../chunk-L7GXUSCV.js';
6
6
  import '../chunk-NYBEU5TE.js';
7
7
  import '../chunk-TE4P6OSJ.js';
8
8
  import '../chunk-DT3QYZVU.js';
@@ -10,11 +10,10 @@ import '../chunk-2IFYDILW.js';
10
10
  import '../chunk-Q7DJKLEN.js';
11
11
  import '../chunk-RXH4D6TY.js';
12
12
  import '../chunk-KRWALB24.js';
13
- import '../chunk-LJDYY3XB.js';
14
- import '../chunk-7MTWRSUZ.js';
15
- export { ElevasisSystemsProvider, useElevasisSystems, useOptionalElevasisSystems } from '../chunk-J3FLIZY4.js';
13
+ import '../chunk-JHVEA5NE.js';
14
+ import '../chunk-56O7QQE7.js';
16
15
  import '../chunk-6DO4PE3O.js';
17
- import '../chunk-K7GKKETO.js';
16
+ export { ElevasisSystemsProvider, useElevasisSystems, useOptionalElevasisSystems } from '../chunk-FIMGOWOT.js';
18
17
  import '../chunk-DD3CCMCZ.js';
19
18
  import '../chunk-W2SFTXMT.js';
20
19
  import '../chunk-6ROXVZ3L.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/ui",
3
- "version": "2.40.0",
3
+ "version": "2.41.0",
4
4
  "description": "UI components and platform-aware hooks for building custom frontends on the Elevasis platform",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -270,9 +270,9 @@
270
270
  "vite": "^7.0.0",
271
271
  "vitest": "^3.2.4",
272
272
  "@elevasis/sdk": "1.29.0",
273
- "@repo/core": "0.36.0",
274
- "@repo/typescript-config": "0.0.0",
275
273
  "@repo/elevasis-core": "1.0.0",
274
+ "@repo/core": "0.37.0",
275
+ "@repo/typescript-config": "0.0.0",
276
276
  "@repo/eslint-config": "0.0.0"
277
277
  },
278
278
  "dependencies": {
@@ -1,423 +0,0 @@
1
- import { getSortedSidebarEntries, getSemanticIconComponent } from './chunk-K7GKKETO.js';
2
- import { devOnlyFor, requiresAdminFor, topLevel, parentOf, ancestorsOf, childrenOf, findById, findByPath, listAllSystems, defaultPathFor } from './chunk-RH5VWWSC.js';
3
- import { createContext, useContext, useMemo, useCallback } from 'react';
4
- import { jsx } from 'react/jsx-runtime';
5
-
6
- // src/provider/resolvers/RouteResolver.ts
7
- function normalizeRoutePath(path) {
8
- const trimmedPath = path.trim();
9
- if (!trimmedPath || trimmedPath === "/") {
10
- return "/";
11
- }
12
- return trimmedPath.replace(/\/+$/, "") || "/";
13
- }
14
- function isRouteMatch(currentPath, route) {
15
- const normalizedCurrentPath = normalizeRoutePath(currentPath);
16
- const normalizedRoute = normalizeRoutePath(route);
17
- return normalizedCurrentPath === normalizedRoute || normalizedCurrentPath.startsWith(`${normalizedRoute}/`);
18
- }
19
-
20
- // src/provider/resolvers/NavResolver.ts
21
- function uniqueIds(ids) {
22
- return ids ? [...new Set(ids)] : [];
23
- }
24
-
25
- // src/provider/validateManifests.ts
26
- function listSystemRefs(systems) {
27
- const refs = [];
28
- function walk(map, prefix = "") {
29
- for (const [key, system] of Object.entries(map)) {
30
- const path = prefix ? `${prefix}.${key}` : key;
31
- refs.push(path, system.id);
32
- const subsystems = system.subsystems;
33
- if (subsystems) {
34
- walk(subsystems, path);
35
- }
36
- }
37
- }
38
- walk(systems);
39
- return refs;
40
- }
41
- function validateManifests(manifests, organizationModel) {
42
- if (!organizationModel) {
43
- return;
44
- }
45
- const validSystemIds = /* @__PURE__ */ new Set([
46
- ...Object.keys(organizationModel.systems ?? {}),
47
- ...listSystemRefs(organizationModel.systems ?? {})
48
- ]);
49
- const errors = [];
50
- for (const manifest of manifests) {
51
- const key = manifest.key;
52
- const systemId = manifest.systemId;
53
- if (!systemId) {
54
- continue;
55
- }
56
- if (!validSystemIds.has(systemId)) {
57
- errors.push(
58
- `Manifest "${key}": systemId "${systemId}" is not a known system id. Valid values: ${[...validSystemIds].sort().join(", ")}`
59
- );
60
- }
61
- }
62
- if (errors.length > 0) {
63
- throw new Error(
64
- `System manifest validation failed with ${errors.length} error(s):
65
- ` + errors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")
66
- );
67
- }
68
- }
69
- var ElevasisSystemsContext = createContext(null);
70
-
71
- // src/provider/sidebarProjection.ts
72
- function isLifecycleEnabled(system) {
73
- if (system.enabled === false) return false;
74
- return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
75
- }
76
- function isSystemAccessible(systemId, context) {
77
- const system = context.shellModel.findById(systemId);
78
- if (!system || !isLifecycleEnabled(system)) return false;
79
- if (!context.isSystemEnabled(systemId)) return false;
80
- if (context.shellModel.requiresAdminFor(systemId) && !context.isPlatformAdmin) return false;
81
- if (context.shellModel.devOnlyFor(systemId) && !context.isDev) return false;
82
- return true;
83
- }
84
- function isSurfaceAccessible(node, context) {
85
- if (node.devOnly && !context.isDev) return false;
86
- if (node.requiresAdmin && !context.isPlatformAdmin) return false;
87
- const systemTargets = node.targets?.systems ?? [];
88
- if (systemTargets.length === 0) return true;
89
- return systemTargets.some((systemId) => isSystemAccessible(systemId, context));
90
- }
91
- function iconForNode(node, context) {
92
- if (node.type === "surface") {
93
- const targetIcon = node.targets?.systems?.map((systemId) => context.shellModel.findById(systemId)?.iconComponent).find(Boolean);
94
- if (targetIcon) return targetIcon;
95
- }
96
- return getSemanticIconComponent(node.icon);
97
- }
98
- function activeMatchPathsForSurface(node, context) {
99
- const targets = node.targets?.systems ?? [];
100
- if (targets.length !== 1) return void 0;
101
- const paths = context.shellModel.childrenOf(targets[0]).map((child) => child.path).filter((path) => Boolean(path && path !== node.path));
102
- return paths.length > 0 ? [...new Set(paths)] : void 0;
103
- }
104
- function surfaceToLinkItem(node, context, siblings) {
105
- if (!isSurfaceAccessible(node, context)) return void 0;
106
- const siblingShadows = siblings.some((sibling) => sibling !== node && sibling.path.startsWith(`${node.path}/`));
107
- const activeMatchPaths = activeMatchPathsForSurface(node, context);
108
- return {
109
- label: node.label,
110
- link: node.path,
111
- ...siblingShadows ? { exact: true } : {},
112
- ...activeMatchPaths ? { activeMatchPaths } : {}
113
- };
114
- }
115
- function projectNode(node, context) {
116
- if (node.type === "surface") {
117
- if (!isSurfaceAccessible(node, context)) return void 0;
118
- return {
119
- label: node.label,
120
- icon: iconForNode(node, context),
121
- link: node.path
122
- };
123
- }
124
- const childEntries = getSortedSidebarEntries(node.children);
125
- const childSurfaces = childEntries.map(([, child]) => child).filter((child) => child.type === "surface");
126
- const links = childEntries.flatMap(([, child]) => {
127
- if (child.type === "surface") {
128
- const link = surfaceToLinkItem(child, context, childSurfaces);
129
- return link ? [link] : [];
130
- }
131
- const nestedGroup = projectNode(child, context);
132
- return nestedGroup?.link ? [
133
- {
134
- label: nestedGroup.label,
135
- link: nestedGroup.link
136
- }
137
- ] : nestedGroup?.links ?? [];
138
- });
139
- if (links.length === 0) return void 0;
140
- return {
141
- label: node.label,
142
- icon: iconForNode(node, context),
143
- links
144
- };
145
- }
146
- function projectSection(section, context) {
147
- const entries = getSortedSidebarEntries(section);
148
- return entries.flatMap(([, node]) => {
149
- const group = projectNode(node, context);
150
- return group ? [group] : [];
151
- });
152
- }
153
- function projectSidebarLinks({
154
- shellModel,
155
- organizationModel,
156
- isSystemEnabled,
157
- isPlatformAdmin = false,
158
- isDev = false,
159
- section
160
- }) {
161
- const context = {
162
- shellModel,
163
- isSystemEnabled,
164
- isPlatformAdmin,
165
- isDev
166
- };
167
- const sidebar = organizationModel?.navigation.sidebar;
168
- if (!sidebar) return [];
169
- if (section) {
170
- return projectSection(sidebar[section], context);
171
- }
172
- return [...projectSection(sidebar.primary, context), ...projectSection(sidebar.bottom, context)];
173
- }
174
- function useElevasisSystems() {
175
- const context = useContext(ElevasisSystemsContext);
176
- if (!context) {
177
- throw new Error(
178
- "useElevasisSystems must be used within an ElevasisSystemsProvider. Wrap your app (or the relevant subtree) with <ElevasisSystemsProvider>."
179
- );
180
- }
181
- return context;
182
- }
183
- function useOptionalElevasisSystems() {
184
- return useContext(ElevasisSystemsContext);
185
- }
186
- function defaultSystems(organizationModel) {
187
- if (!organizationModel) return [];
188
- return listAllSystems(organizationModel).map(({ path, system }) => ({ ...system, id: path }));
189
- }
190
- function systemPath(system) {
191
- return system.ui?.path ?? system.path ?? defaultPathFor(system.id);
192
- }
193
- function systemLabel(system) {
194
- return system.label ?? system.title ?? system.id;
195
- }
196
- function moduleSystemId(module) {
197
- return module.systemId ?? module.key;
198
- }
199
- function isLifecycleEnabled2(system) {
200
- if (system.enabled === false) return false;
201
- return system.lifecycle !== "deprecated" && system.lifecycle !== "archived";
202
- }
203
- function isOrganizationModelSystemEnabled(organizationModel, systemId) {
204
- const system = defaultSystems(organizationModel).find((candidate) => candidate.id === systemId);
205
- return system ? isLifecycleEnabled2(system) : void 0;
206
- }
207
- function resolveSystemModules(systems, isSystemEnabled) {
208
- return systems.map((system) => {
209
- const systemId = system.systemId;
210
- const accessKey = systemId ?? system.key;
211
- return {
212
- ...system,
213
- systemId,
214
- access: {
215
- systemKey: system.key,
216
- systemId,
217
- enabled: isSystemEnabled(accessKey)
218
- },
219
- semantics: {
220
- capabilityIds: uniqueIds(system.capabilityIds ?? [])
221
- }
222
- };
223
- });
224
- }
225
- function buildShellSystems(organizationModel, modules) {
226
- const iconBySystemId = new Map(
227
- modules.flatMap((module) => module.systemId ? [[moduleSystemId(module), module.icon]] : [])
228
- );
229
- return defaultSystems(organizationModel).map((system) => ({
230
- ...system,
231
- label: systemLabel(system),
232
- path: systemPath(system),
233
- iconComponent: iconBySystemId.get(system.id)
234
- }));
235
- }
236
- function createShellModel(systems) {
237
- const systemsRecord = Object.fromEntries(systems.map((s) => [s.id, s]));
238
- return {
239
- systems,
240
- findByPath: (path) => findByPath(systemsRecord, normalizeRoutePath(path)),
241
- findById: (id) => findById(systemsRecord, id),
242
- childrenOf: (id) => childrenOf(systemsRecord, id),
243
- ancestorsOf: (id) => ancestorsOf(systemsRecord, id),
244
- parentOf: (id) => parentOf(systemsRecord, id),
245
- topLevel: () => topLevel(systemsRecord),
246
- requiresAdminFor: (id) => requiresAdminFor(systemsRecord, id),
247
- devOnlyFor: (id) => devOnlyFor(systemsRecord, id)
248
- };
249
- }
250
- function resolveOrganizationGraphSystem(systems, shellModel) {
251
- for (const system of systems) {
252
- const graphBridge = system.organizationGraph;
253
- if (!graphBridge) continue;
254
- const systemId = graphBridge.systemId;
255
- if (!systemId) continue;
256
- const node = shellModel.findById(systemId);
257
- return {
258
- available: Boolean(node),
259
- systemId,
260
- systemPath: node ? systemPath(node) : void 0
261
- };
262
- }
263
- return {
264
- available: false
265
- };
266
- }
267
- function findMatchingNode(shellModel, currentPath) {
268
- const normalizedPath = normalizeRoutePath(currentPath);
269
- const exact = shellModel.findByPath(normalizedPath);
270
- if (exact) return exact;
271
- return [...shellModel.systems].filter((system) => {
272
- const path = normalizeRoutePath(systemPath(system));
273
- return path !== "/" && isRouteMatch(normalizedPath, path);
274
- }).sort((a, b) => systemPath(b).length - systemPath(a).length)[0];
275
- }
276
- function ownsNode(module, node) {
277
- if (!node || !module.systemId) return false;
278
- return node.id === module.systemId || node.id.startsWith(`${module.systemId}.`);
279
- }
280
- function ownsRoutePrefix(module, normalizedPath) {
281
- return (module.routePrefixes ?? []).some((prefix) => isRouteMatch(normalizedPath, normalizeRoutePath(prefix)));
282
- }
283
- function resolveRoute(systems, shellModel, currentPath, disabledSubsectionPaths) {
284
- const node = findMatchingNode(shellModel, currentPath);
285
- const normalizedPath = normalizeRoutePath(currentPath);
286
- if (disabledSubsectionPaths.some((disabledPath) => isRouteMatch(normalizedPath, disabledPath))) {
287
- return {
288
- status: "hidden",
289
- path: currentPath,
290
- node
291
- };
292
- }
293
- const system = systems.find((candidate) => ownsNode(candidate, node)) ?? systems.filter((candidate) => ownsRoutePrefix(candidate, normalizedPath)).sort(
294
- (a, b) => Math.max(...(b.routePrefixes ?? []).map((prefix) => prefix.length)) - Math.max(...(a.routePrefixes ?? []).map((prefix) => prefix.length))
295
- )[0];
296
- if (!system) {
297
- return {
298
- status: "unmatched",
299
- path: currentPath,
300
- node
301
- };
302
- }
303
- return {
304
- status: "matched",
305
- path: currentPath,
306
- system,
307
- node
308
- };
309
- }
310
- function ElevasisSystemsProvider({
311
- systems,
312
- organizationModel,
313
- timeRange,
314
- operationsApiUrl,
315
- operationsSSEManager,
316
- deliveryApiUrl,
317
- deliverySSEManager,
318
- disabledSubsectionPaths = [],
319
- children
320
- }) {
321
- const activeSystems = systems ?? [];
322
- const resolvedOrganizationModel = useMemo(() => {
323
- if (!organizationModel) {
324
- return void 0;
325
- }
326
- return {
327
- ...organizationModel,
328
- knowledge: organizationModel.knowledge ?? {}
329
- };
330
- }, [organizationModel]);
331
- useMemo(() => validateManifests(activeSystems, resolvedOrganizationModel), [activeSystems, resolvedOrganizationModel]);
332
- const hasResolvedSystem = useCallback(
333
- (key) => {
334
- const organizationModelSystemEnabled = isOrganizationModelSystemEnabled(resolvedOrganizationModel, key);
335
- return organizationModelSystemEnabled ?? true;
336
- },
337
- [resolvedOrganizationModel]
338
- );
339
- const shellSystems = useMemo(
340
- () => buildShellSystems(resolvedOrganizationModel, activeSystems),
341
- [resolvedOrganizationModel, activeSystems]
342
- );
343
- const shellModel = useMemo(() => createShellModel(shellSystems), [shellSystems]);
344
- const normalizedDisabledSubsectionPaths = useMemo(
345
- () => [...new Set(disabledSubsectionPaths.map((path) => normalizeRoutePath(path)))],
346
- [disabledSubsectionPaths]
347
- );
348
- const resolvedSystems = useMemo(
349
- () => resolveSystemModules(activeSystems, hasResolvedSystem),
350
- [activeSystems, hasResolvedSystem]
351
- );
352
- const enabledResolvedSystems = useMemo(
353
- () => resolvedSystems.filter((system) => system.access.enabled),
354
- [resolvedSystems]
355
- );
356
- const organizationGraph = useMemo(
357
- () => resolveOrganizationGraphSystem(enabledResolvedSystems, shellModel),
358
- [enabledResolvedSystems, shellModel]
359
- );
360
- const getResolvedSystem = useCallback(
361
- (key) => resolvedSystems.find((system) => system.key === key),
362
- [resolvedSystems]
363
- );
364
- const isSystemEnabled = useCallback((key) => hasResolvedSystem(key), [hasResolvedSystem]);
365
- const getSidebarLinks = useCallback(
366
- (options = {}) => projectSidebarLinks({
367
- shellModel,
368
- organizationModel: resolvedOrganizationModel,
369
- isSystemEnabled,
370
- ...options
371
- }),
372
- [shellModel, resolvedOrganizationModel, isSystemEnabled]
373
- );
374
- const resolveRouteByPath = useCallback(
375
- (path) => resolveRoute(enabledResolvedSystems, shellModel, path, normalizedDisabledSubsectionPaths),
376
- [enabledResolvedSystems, shellModel, normalizedDisabledSubsectionPaths]
377
- );
378
- const shellRuntime = useMemo(
379
- () => ({
380
- resolveRoute: resolveRouteByPath
381
- }),
382
- [resolveRouteByPath]
383
- );
384
- const value = useMemo(
385
- () => ({
386
- shellModel,
387
- shellRuntime,
388
- getSidebarLinks,
389
- enabledResolvedSystems,
390
- resolvedSystems,
391
- organizationGraph,
392
- organizationModel: resolvedOrganizationModel,
393
- timeRange,
394
- operationsApiUrl,
395
- operationsSSEManager,
396
- deliveryApiUrl,
397
- deliverySSEManager,
398
- disabledSubsectionPaths: normalizedDisabledSubsectionPaths,
399
- isSystemEnabled,
400
- getResolvedSystem
401
- }),
402
- [
403
- shellModel,
404
- shellRuntime,
405
- enabledResolvedSystems,
406
- resolvedSystems,
407
- organizationGraph,
408
- resolvedOrganizationModel,
409
- timeRange,
410
- operationsApiUrl,
411
- operationsSSEManager,
412
- deliveryApiUrl,
413
- deliverySSEManager,
414
- normalizedDisabledSubsectionPaths,
415
- isSystemEnabled,
416
- getResolvedSystem,
417
- getSidebarLinks
418
- ]
419
- );
420
- return /* @__PURE__ */ jsx(ElevasisSystemsContext.Provider, { value, children });
421
- }
422
-
423
- export { ElevasisSystemsProvider, useElevasisSystems, useOptionalElevasisSystems };