@elevasis/ui 2.20.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.js +2 -2
- package/dist/app/index.js +5 -5
- package/dist/charts/index.js +3 -3
- package/dist/{chunk-TO7QXDBX.js → chunk-3HEUGBOT.js} +3 -3
- package/dist/chunk-AXXTN44Z.js +26 -0
- package/dist/{chunk-FMFX4K6E.js → chunk-B4FHWKEF.js} +3390 -2929
- package/dist/{chunk-AL23U6C3.js → chunk-BIWHHWCJ.js} +1 -2
- package/dist/{chunk-MZFJWCPH.js → chunk-BSZRKBAW.js} +277 -92
- package/dist/{chunk-GP3AFJYG.js → chunk-COG4ABRI.js} +8 -13
- package/dist/chunk-DDZOHLHB.js +48 -0
- package/dist/{chunk-ZE2KQSHL.js → chunk-GJ7EIABJ.js} +4 -4
- package/dist/{chunk-YP6T426C.js → chunk-IBUYJXA3.js} +1326 -1110
- package/dist/{chunk-2CFOFSSG.js → chunk-IOTLB6ND.js} +8 -13
- package/dist/{chunk-GBMNCNHX.js → chunk-KVJ3LFH2.js} +3 -1
- package/dist/chunk-LJWV4TWV.js +335 -0
- package/dist/{chunk-PJVG3ISO.js → chunk-LKVBEE63.js} +7 -9
- package/dist/{chunk-JR5WNTLA.js → chunk-LVJGPE6H.js} +11 -24
- package/dist/{chunk-OUYH2SBS.js → chunk-LVUCBY7X.js} +2 -2
- package/dist/{chunk-TIIPYB2Z.js → chunk-QZJM3RYI.js} +1 -1
- package/dist/{chunk-OD7GWIZS.js → chunk-SGXXJE52.js} +1 -121
- package/dist/{chunk-7YQKVWSD.js → chunk-SQ5JGELM.js} +25 -5
- package/dist/{chunk-R7OJCNL3.js → chunk-T6INEVX6.js} +1 -1
- package/dist/{chunk-RX4UWZZR.js → chunk-TKAYX2SP.js} +8 -3
- package/dist/{chunk-CTTY6FUT.js → chunk-TSSKOQBX.js} +2 -2
- package/dist/{chunk-GTYUP7MB.js → chunk-WWJ6S2HQ.js} +10 -22
- package/dist/{chunk-Q5HC6ENG.js → chunk-XOTJNW4Q.js} +1 -1
- package/dist/{chunk-BHR7IV72.js → chunk-XUYBOO32.js} +1 -1
- package/dist/{chunk-M7W7CGPL.js → chunk-Z6FAH4XV.js} +1 -1
- package/dist/{chunk-Q4QJOSVS.js → chunk-ZBCTB5CA.js} +1 -1
- package/dist/components/index.css +85 -85
- package/dist/components/index.d.ts +970 -746
- package/dist/components/index.js +246 -39
- package/dist/components/navigation/index.css +589 -0
- package/dist/components/navigation/index.d.ts +1 -13
- package/dist/components/navigation/index.js +11 -1
- package/dist/execution/index.d.ts +27 -0
- package/dist/features/auth/index.css +2 -2
- package/dist/features/auth/index.d.ts +184 -3
- package/dist/features/crm/index.css +2 -2
- package/dist/features/crm/index.d.ts +201 -38
- package/dist/features/crm/index.js +15 -14
- package/dist/features/dashboard/index.css +2 -2
- package/dist/features/dashboard/index.d.ts +25 -27
- package/dist/features/dashboard/index.js +15 -14
- package/dist/features/delivery/index.css +85 -85
- package/dist/features/delivery/index.d.ts +201 -38
- package/dist/features/delivery/index.js +15 -14
- package/dist/features/lead-gen/index.css +2 -2
- package/dist/features/lead-gen/index.d.ts +19 -37
- package/dist/features/lead-gen/index.js +15 -14
- package/dist/features/monitoring/index.css +85 -85
- package/dist/features/monitoring/index.d.ts +18 -36
- package/dist/features/monitoring/index.js +17 -16
- package/dist/features/monitoring/requests/index.css +2 -2
- package/dist/features/monitoring/requests/index.d.ts +18 -36
- package/dist/features/monitoring/requests/index.js +15 -14
- package/dist/features/operations/index.css +2 -2
- package/dist/features/operations/index.d.ts +49 -67
- package/dist/features/operations/index.js +18 -17
- package/dist/features/seo/index.d.ts +17 -35
- package/dist/features/seo/index.js +1 -1
- package/dist/features/settings/index.css +2 -2
- package/dist/features/settings/index.d.ts +222 -44
- package/dist/features/settings/index.js +16 -15
- package/dist/graph/index.css +2 -2
- package/dist/hooks/delivery/index.css +2 -2
- package/dist/hooks/delivery/index.d.ts +184 -3
- package/dist/hooks/delivery/index.js +2 -2
- package/dist/hooks/index.css +85 -85
- package/dist/hooks/index.d.ts +1862 -1582
- package/dist/hooks/index.js +13 -12
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +92 -121
- package/dist/hooks/published.css +85 -85
- package/dist/hooks/published.d.ts +1862 -1582
- package/dist/hooks/published.js +13 -12
- package/dist/index.css +12 -12
- package/dist/index.d.ts +689 -470
- package/dist/index.js +14 -13
- package/dist/initialization/index.d.ts +184 -3
- package/dist/layout/index.js +2 -2
- package/dist/organization/index.css +589 -0
- package/dist/organization/index.js +1 -1
- package/dist/profile/index.d.ts +184 -3
- package/dist/provider/index.css +384 -0
- package/dist/provider/index.d.ts +68 -125
- package/dist/provider/index.js +11 -10
- package/dist/provider/published.css +463 -0
- package/dist/provider/published.d.ts +68 -125
- package/dist/provider/published.js +8 -7
- package/dist/supabase/index.d.ts +359 -6
- package/dist/test-utils/index.d.ts +46 -2
- package/dist/test-utils/index.js +104 -3
- package/dist/theme/index.js +2 -2
- package/dist/types/index.d.ts +303 -141
- package/dist/utils/index.d.ts +26 -59
- package/dist/utils/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-LR5CRY5A.js +0 -514
- package/dist/chunk-MG3NF7QL.js +0 -63
- /package/dist/{chunk-6GUW5GGF.js → chunk-6Z3G4U2R.js} +0 -0
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IconBrain } from '@tabler/icons-react';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Date formatting utilities for consistent date display across the application
|
|
@@ -130,8 +131,10 @@ interface ResourceDefinition {
|
|
|
130
131
|
type: ResourceType;
|
|
131
132
|
/** Environment/deployment status */
|
|
132
133
|
status: ResourceStatus;
|
|
133
|
-
/**
|
|
134
|
-
|
|
134
|
+
/** Graph links to Organization Model nodes */
|
|
135
|
+
links?: ResourceLink[];
|
|
136
|
+
/** Infrastructure category for filtering */
|
|
137
|
+
category?: ResourceCategory;
|
|
135
138
|
/** Whether the agent supports multi-turn sessions (agents only) */
|
|
136
139
|
sessionCapable?: boolean;
|
|
137
140
|
/** Whether the resource is local (monorepo) or remote (externally deployed) */
|
|
@@ -139,64 +142,28 @@ interface ResourceDefinition {
|
|
|
139
142
|
/** Whether this resource is archived and should be excluded from registration and deployment */
|
|
140
143
|
archived?: boolean;
|
|
141
144
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Domain definition for Command View filtering
|
|
144
|
-
*
|
|
145
|
-
* Domains are organizational metadata for UI filtering/grouping.
|
|
146
|
-
* No execution impact - purely for visualization.
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* {
|
|
150
|
-
* id: 'support',
|
|
151
|
-
* name: 'Customer Support',
|
|
152
|
-
* description: 'Ticket triage, knowledge base, escalations',
|
|
153
|
-
* color: 'green',
|
|
154
|
-
* icon: 'IconHeadset'
|
|
155
|
-
* }
|
|
156
|
-
*/
|
|
157
|
-
interface DomainDefinition {
|
|
158
|
-
/** Unique identifier (e.g., 'support') */
|
|
159
|
-
id: string;
|
|
160
|
-
/** Display name (e.g., 'Customer Support') */
|
|
161
|
-
name: string;
|
|
162
|
-
/** Purpose description */
|
|
163
|
-
description: string;
|
|
164
|
-
/** Optional Mantine color for UI (e.g., 'blue', 'green', 'orange') */
|
|
165
|
-
color?: string;
|
|
166
|
-
/** Optional Tabler icon name (e.g., 'IconHeadset') */
|
|
167
|
-
icon?: string;
|
|
168
|
-
}
|
|
169
145
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
146
|
+
declare const LinkSchema: z.ZodObject<{
|
|
147
|
+
nodeId: z.ZodString;
|
|
148
|
+
kind: z.ZodEnum<{
|
|
149
|
+
contains: "contains";
|
|
150
|
+
references: "references";
|
|
151
|
+
exposes: "exposes";
|
|
152
|
+
maps_to: "maps_to";
|
|
153
|
+
"operates-on": "operates-on";
|
|
154
|
+
uses: "uses";
|
|
155
|
+
}>;
|
|
156
|
+
}, z.core.$strip>;
|
|
157
|
+
type Link = z.infer<typeof LinkSchema>;
|
|
174
158
|
|
|
175
|
-
declare const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
readonly EXECUTIVE: "executive";
|
|
184
|
-
readonly INSTANTLY: "instantly";
|
|
185
|
-
readonly TESTING: "testing";
|
|
186
|
-
readonly INTERNAL: "internal";
|
|
187
|
-
readonly INTEGRATION: "integration";
|
|
188
|
-
readonly UTILITY: "utility";
|
|
189
|
-
readonly DIAGNOSTIC: "diagnostic";
|
|
190
|
-
};
|
|
191
|
-
/**
|
|
192
|
-
* ResourceDomain - Strongly typed domain identifier
|
|
193
|
-
* Use this type for all domain references to ensure compile-time validation.
|
|
194
|
-
*/
|
|
195
|
-
type ResourceDomain = (typeof DOMAINS)[keyof typeof DOMAINS];
|
|
196
|
-
/**
|
|
197
|
-
* Domain lookup map for O(1) access during serialization
|
|
198
|
-
*/
|
|
199
|
-
declare const DOMAIN_MAP: Record<ResourceDomain, DomainDefinition>;
|
|
159
|
+
declare const ResourceCategorySchema: z.ZodEnum<{
|
|
160
|
+
production: "production";
|
|
161
|
+
diagnostic: "diagnostic";
|
|
162
|
+
internal: "internal";
|
|
163
|
+
testing: "testing";
|
|
164
|
+
}>;
|
|
165
|
+
type ResourceCategory = z.infer<typeof ResourceCategorySchema>;
|
|
166
|
+
type ResourceLink = Link;
|
|
200
167
|
|
|
201
168
|
/**
|
|
202
169
|
* Resource Type Metadata
|
|
@@ -375,5 +342,5 @@ declare function restoreConsole(): void;
|
|
|
375
342
|
|
|
376
343
|
declare function setupBrowserMocks(): void;
|
|
377
344
|
|
|
378
|
-
export { APIClientError, API_URL, DEBOUNCE_FILTER, DEBOUNCE_SLIDER,
|
|
345
|
+
export { APIClientError, API_URL, DEBOUNCE_FILTER, DEBOUNCE_SLIDER, GC_TIME_LONG, GC_TIME_MEDIUM, GC_TIME_SHORT, LIMIT_ACTIVITY_FEED, OAUTH_FLOW_TIMEOUT, OAUTH_POPUP_CHECK_INTERVAL, PAGE_SIZE_DEFAULT, REFETCH_INTERVAL_DASHBOARD, REFETCH_INTERVAL_REALTIME, REFETCH_INTERVAL_RUNNING, REFETCH_INTERVAL_RUNNING_FAST, ResourceStatusColors, SSE_CLOSE_GRACE_PERIOD, SSE_TOKEN_REFRESH_DELAY, STALE_TIME_ADMIN, STALE_TIME_DEFAULT, STALE_TIME_MONITORING, WS_MAX_RETRIES_BEFORE_ERROR, WS_RECONNECT_BASE_DELAY, WS_RECONNECT_MAX_DELAY, debounce, formatChartAxisDate, formatDate, formatDateTime, formatErrorMessage, formatRelativeTime, formatTimeAgo, getErrorInfo, getErrorTitle, getResourceColor, getResourceIcon, getTimeRangeDates, getTimeRangeLabel, isAPIClientError, restoreConsole, setupBrowserMocks, suppressKnownWarnings, validateEmail };
|
|
379
346
|
export type { TablerIcon };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { APIClientError, API_URL, DEBOUNCE_FILTER, DEBOUNCE_SLIDER,
|
|
1
|
+
export { APIClientError, API_URL, DEBOUNCE_FILTER, DEBOUNCE_SLIDER, GC_TIME_LONG, GC_TIME_MEDIUM, GC_TIME_SHORT, LIMIT_ACTIVITY_FEED, OAUTH_FLOW_TIMEOUT, OAUTH_POPUP_CHECK_INTERVAL, PAGE_SIZE_DEFAULT, REFETCH_INTERVAL_DASHBOARD, REFETCH_INTERVAL_REALTIME, REFETCH_INTERVAL_RUNNING, REFETCH_INTERVAL_RUNNING_FAST, SSE_CLOSE_GRACE_PERIOD, SSE_TOKEN_REFRESH_DELAY, STALE_TIME_ADMIN, STALE_TIME_DEFAULT, STALE_TIME_MONITORING, WS_MAX_RETRIES_BEFORE_ERROR, WS_RECONNECT_BASE_DELAY, WS_RECONNECT_MAX_DELAY, debounce, formatChartAxisDate, formatDate, formatDateTime, formatErrorMessage, formatRelativeTime, formatTimeAgo, getErrorInfo, getErrorTitle, getResourceColor, getResourceIcon, getTimeRangeDates, getTimeRangeLabel, isAPIClientError, restoreConsole, setupBrowserMocks, suppressKnownWarnings, validateEmail } from '../chunk-SGXXJE52.js';
|
|
2
2
|
export { ResourceStatusColors } from '../chunk-KRWALB24.js';
|
|
3
3
|
import '../chunk-I2KLQ2HA.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elevasis/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.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",
|
|
@@ -225,9 +225,9 @@
|
|
|
225
225
|
"@testing-library/jest-dom": "^6.9.1",
|
|
226
226
|
"msw": "^2.11.0",
|
|
227
227
|
"vitest": "^3.2.4",
|
|
228
|
-
"@repo/core": "0.
|
|
229
|
-
"@repo/
|
|
230
|
-
"@repo/
|
|
228
|
+
"@repo/core": "0.12.0",
|
|
229
|
+
"@repo/eslint-config": "0.0.0",
|
|
230
|
+
"@repo/typescript-config": "0.0.0"
|
|
231
231
|
},
|
|
232
232
|
"dependencies": {
|
|
233
233
|
"@dagrejs/dagre": "^1.1.4",
|
package/dist/chunk-LR5CRY5A.js
DELETED
|
@@ -1,514 +0,0 @@
|
|
|
1
|
-
import { SubshellContainer, SubshellSidebar, SubshellRightSideContainer } from './chunk-RX4UWZZR.js';
|
|
2
|
-
import { FeatureUnavailableState } from './chunk-BHR7IV72.js';
|
|
3
|
-
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
4
|
-
import { useInitialization } from './chunk-DK2HVHCY.js';
|
|
5
|
-
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
6
|
-
import { createContext, useMemo, useCallback, useContext } from 'react';
|
|
7
|
-
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
8
|
-
|
|
9
|
-
function createFeatureAccessHook({
|
|
10
|
-
useInitialization: useInitialization2,
|
|
11
|
-
useOrganization: useOrganization2
|
|
12
|
-
}) {
|
|
13
|
-
return function useFeatureAccess2() {
|
|
14
|
-
const { profile, organizationReady } = useInitialization2();
|
|
15
|
-
const { currentMembership } = useOrganization2();
|
|
16
|
-
const { orgConfig, membershipConfig } = useMemo(() => {
|
|
17
|
-
const organizationConfig = currentMembership?.organization?.config;
|
|
18
|
-
const memberConfig = currentMembership?.config;
|
|
19
|
-
return { orgConfig: organizationConfig, membershipConfig: memberConfig };
|
|
20
|
-
}, [currentMembership]);
|
|
21
|
-
const userConfig = profile?.config;
|
|
22
|
-
const checkFeature = useCallback(
|
|
23
|
-
(featureKey) => {
|
|
24
|
-
if (profile?.is_platform_admin) {
|
|
25
|
-
return { allowed: true, restrictedBy: null };
|
|
26
|
-
}
|
|
27
|
-
const membershipValue = membershipConfig?.features?.[featureKey];
|
|
28
|
-
if (membershipValue === false) return { allowed: false, restrictedBy: "membership" };
|
|
29
|
-
return { allowed: true, restrictedBy: null };
|
|
30
|
-
},
|
|
31
|
-
[profile?.is_platform_admin, membershipConfig]
|
|
32
|
-
);
|
|
33
|
-
const hasFeature = useCallback((featureKey) => checkFeature(featureKey).allowed, [checkFeature]);
|
|
34
|
-
return {
|
|
35
|
-
orgConfig,
|
|
36
|
-
membershipConfig,
|
|
37
|
-
userConfig,
|
|
38
|
-
hasFeature,
|
|
39
|
-
checkFeature,
|
|
40
|
-
isReady: organizationReady
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
var createUseFeatureAccess = createFeatureAccessHook;
|
|
45
|
-
|
|
46
|
-
// src/provider/resolvers/RouteResolver.ts
|
|
47
|
-
function normalizeRoutePath(path) {
|
|
48
|
-
const trimmedPath = path.trim();
|
|
49
|
-
if (!trimmedPath || trimmedPath === "/") {
|
|
50
|
-
return "/";
|
|
51
|
-
}
|
|
52
|
-
return trimmedPath.replace(/\/+$/, "") || "/";
|
|
53
|
-
}
|
|
54
|
-
function isRouteMatch(currentPath, route) {
|
|
55
|
-
const normalizedCurrentPath = normalizeRoutePath(currentPath);
|
|
56
|
-
const normalizedRoute = normalizeRoutePath(route);
|
|
57
|
-
return normalizedCurrentPath === normalizedRoute || normalizedCurrentPath.startsWith(`${normalizedRoute}/`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// src/provider/resolvers/NavResolver.ts
|
|
61
|
-
function uniqueIds(ids) {
|
|
62
|
-
return ids ? [...new Set(ids)] : [];
|
|
63
|
-
}
|
|
64
|
-
function collectNavLinkPaths(links) {
|
|
65
|
-
if (!links?.length) {
|
|
66
|
-
return [];
|
|
67
|
-
}
|
|
68
|
-
return links.flatMap((link) => [link.link, ...collectNavLinkPaths(link.links)]);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/provider/validateManifests.ts
|
|
72
|
-
function validateManifests(manifests, organizationModel) {
|
|
73
|
-
if (!organizationModel) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const validFeatureIds = new Set(organizationModel.features.map((f) => f.id));
|
|
77
|
-
const validCapabilityIds = /* @__PURE__ */ new Set([
|
|
78
|
-
...organizationModel.features.flatMap((f) => f.capabilityIds),
|
|
79
|
-
...organizationModel.navigation.surfaces.flatMap((s) => s.capabilityIds),
|
|
80
|
-
...organizationModel.resourceMappings.flatMap((r) => r.capabilityIds)
|
|
81
|
-
]);
|
|
82
|
-
const errors = [];
|
|
83
|
-
for (const manifest of manifests) {
|
|
84
|
-
const key = manifest.key;
|
|
85
|
-
if (!validFeatureIds.has(manifest.featureId)) {
|
|
86
|
-
errors.push(
|
|
87
|
-
`Manifest "${key}": featureId "${manifest.featureId}" is not a known feature id. Valid values: ${[...validFeatureIds].sort().join(", ")}`
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
if (manifest.capabilityIds) {
|
|
91
|
-
for (let i = 0; i < manifest.capabilityIds.length; i++) {
|
|
92
|
-
const capabilityId = manifest.capabilityIds[i];
|
|
93
|
-
if (!validCapabilityIds.has(capabilityId)) {
|
|
94
|
-
errors.push(
|
|
95
|
-
`Manifest "${key}": capabilityIds[${i}] references unknown capability "${capabilityId}". Valid capabilities: ${[...validCapabilityIds].sort().join(", ")}`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (errors.length > 0) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
`Feature manifest validation failed with ${errors.length} error(s):
|
|
104
|
-
` + errors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
var useFeatureAccess = createFeatureAccessHook({
|
|
109
|
-
useInitialization,
|
|
110
|
-
useOrganization
|
|
111
|
-
});
|
|
112
|
-
var ElevasisFeaturesContext = createContext(null);
|
|
113
|
-
function useElevasisFeatures() {
|
|
114
|
-
const context = useContext(ElevasisFeaturesContext);
|
|
115
|
-
if (!context) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
"useElevasisFeatures must be used within an ElevasisFeaturesProvider. Wrap your app (or the relevant subtree) with <ElevasisFeaturesProvider>."
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
return context;
|
|
121
|
-
}
|
|
122
|
-
function useOptionalElevasisFeatures() {
|
|
123
|
-
return useContext(ElevasisFeaturesContext);
|
|
124
|
-
}
|
|
125
|
-
function findOrganizationModelFeature(organizationModel, featureId) {
|
|
126
|
-
if (!organizationModel) {
|
|
127
|
-
return void 0;
|
|
128
|
-
}
|
|
129
|
-
return organizationModel.features.find((f) => f.id === featureId);
|
|
130
|
-
}
|
|
131
|
-
function findSurfaceByPath(organizationModel, path) {
|
|
132
|
-
if (!organizationModel) {
|
|
133
|
-
return void 0;
|
|
134
|
-
}
|
|
135
|
-
const normalizedPath = normalizeRoutePath(path);
|
|
136
|
-
return organizationModel.navigation.surfaces.find((surface) => normalizeRoutePath(surface.path) === normalizedPath);
|
|
137
|
-
}
|
|
138
|
-
function findSurfaceById(organizationModel, id) {
|
|
139
|
-
if (!organizationModel) {
|
|
140
|
-
return void 0;
|
|
141
|
-
}
|
|
142
|
-
return organizationModel.navigation.surfaces.find((surface) => surface.id === id);
|
|
143
|
-
}
|
|
144
|
-
function findSurfacesByPaths(organizationModel, paths) {
|
|
145
|
-
if (!organizationModel || paths.length === 0) {
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
const normalizedPaths = new Set(paths.map((path) => normalizeRoutePath(path)));
|
|
149
|
-
return organizationModel.navigation.surfaces.filter(
|
|
150
|
-
(surface) => normalizedPaths.has(normalizeRoutePath(surface.path))
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
function getOrganizationModelFeatureLabel(organizationModel, featureId) {
|
|
154
|
-
if (!organizationModel || !featureId) {
|
|
155
|
-
return void 0;
|
|
156
|
-
}
|
|
157
|
-
return findOrganizationModelFeature(organizationModel, featureId)?.label;
|
|
158
|
-
}
|
|
159
|
-
function isOrganizationModelFeatureEnabled(organizationModel, featureId) {
|
|
160
|
-
if (!organizationModel) {
|
|
161
|
-
return void 0;
|
|
162
|
-
}
|
|
163
|
-
const feature = findOrganizationModelFeature(organizationModel, featureId);
|
|
164
|
-
if (!feature) {
|
|
165
|
-
return void 0;
|
|
166
|
-
}
|
|
167
|
-
return feature.enabled;
|
|
168
|
-
}
|
|
169
|
-
function resolveOrganizationGraphSurface(features, organizationModel) {
|
|
170
|
-
for (const feature of features) {
|
|
171
|
-
const graphBridge = feature.organizationGraph;
|
|
172
|
-
if (!graphBridge) {
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
const surface = findSurfaceById(organizationModel, graphBridge.surfaceId);
|
|
176
|
-
return {
|
|
177
|
-
available: Boolean(surface),
|
|
178
|
-
surfaceId: graphBridge.surfaceId,
|
|
179
|
-
surfacePath: surface?.path,
|
|
180
|
-
surfaceType: surface?.surfaceType,
|
|
181
|
-
featureId: surface?.featureId
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
return {
|
|
185
|
-
available: false
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
function resolveNavLink(link, organizationModel) {
|
|
189
|
-
const matchedSurface = findSurfaceByPath(organizationModel, link.link);
|
|
190
|
-
const featureLabel = getOrganizationModelFeatureLabel(organizationModel, link.featureKey);
|
|
191
|
-
return {
|
|
192
|
-
...link,
|
|
193
|
-
label: matchedSurface?.label ?? featureLabel ?? link.label,
|
|
194
|
-
link: matchedSurface?.path ?? link.link,
|
|
195
|
-
links: link.links?.map((nestedLink) => resolveNavLink(nestedLink, organizationModel))
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
function resolveNavEntry(navEntry, organizationModel, ownerFeatureId) {
|
|
199
|
-
const matchedSurface = navEntry.link ? findSurfaceByPath(organizationModel, navEntry.link) : void 0;
|
|
200
|
-
const featureLabel = getOrganizationModelFeatureLabel(organizationModel, navEntry.featureKey ?? ownerFeatureId);
|
|
201
|
-
return {
|
|
202
|
-
...navEntry,
|
|
203
|
-
label: featureLabel ?? matchedSurface?.label ?? navEntry.label,
|
|
204
|
-
link: matchedSurface?.path ?? navEntry.link,
|
|
205
|
-
links: navEntry.links?.map((link) => resolveNavLink(link, organizationModel))
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
function resolveFeatureModule(feature, organizationModel) {
|
|
209
|
-
if (!feature.navEntry) {
|
|
210
|
-
return feature;
|
|
211
|
-
}
|
|
212
|
-
return {
|
|
213
|
-
...feature,
|
|
214
|
-
navEntry: resolveNavEntry(feature.navEntry, organizationModel, feature.featureId)
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
function resolveFeatureSemantics(feature, resolvedFeature, organizationModel) {
|
|
218
|
-
const linkedPaths = [resolvedFeature.navEntry?.link, ...collectNavLinkPaths(resolvedFeature.navEntry?.links)].filter(
|
|
219
|
-
(path) => Boolean(path)
|
|
220
|
-
);
|
|
221
|
-
const linkedSurfaces = findSurfacesByPaths(organizationModel, linkedPaths);
|
|
222
|
-
const organizationGraphSurface = feature.organizationGraph ? findSurfaceById(organizationModel, feature.organizationGraph.surfaceId) : void 0;
|
|
223
|
-
const surfaces = [...linkedSurfaces, ...organizationGraphSurface ? [organizationGraphSurface] : []].filter(
|
|
224
|
-
(surface, index, items) => Boolean(surface) && items.findIndex((candidate) => candidate.id === surface.id) === index
|
|
225
|
-
);
|
|
226
|
-
return {
|
|
227
|
-
capabilityIds: uniqueIds([
|
|
228
|
-
...feature.capabilityIds ?? [],
|
|
229
|
-
...surfaces.flatMap((surface) => surface.capabilityIds)
|
|
230
|
-
]),
|
|
231
|
-
surfaceIds: surfaces.map((surface) => surface.id),
|
|
232
|
-
surfaces
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
function resolveFeatureModules(features, organizationModel, isFeatureEnabled) {
|
|
236
|
-
return features.map((feature) => {
|
|
237
|
-
const resolvedFeature = resolveFeatureModule(feature, organizationModel);
|
|
238
|
-
const featureId = feature.featureId;
|
|
239
|
-
return {
|
|
240
|
-
...resolvedFeature,
|
|
241
|
-
access: {
|
|
242
|
-
featureId,
|
|
243
|
-
enabled: isFeatureEnabled(featureId)
|
|
244
|
-
},
|
|
245
|
-
semantics: resolveFeatureSemantics(feature, resolvedFeature, organizationModel)
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
function filterNavLinks(links, disabledSubsectionPaths, isFeatureEnabled) {
|
|
250
|
-
return links.flatMap((link) => {
|
|
251
|
-
if (link.featureKey && !isFeatureEnabled(link.featureKey)) {
|
|
252
|
-
return [];
|
|
253
|
-
}
|
|
254
|
-
if (disabledSubsectionPaths.some((disabledPath) => isRouteMatch(link.link, disabledPath))) {
|
|
255
|
-
return [];
|
|
256
|
-
}
|
|
257
|
-
const nestedLinks = link.links?.length ? filterNavLinks(link.links, disabledSubsectionPaths, isFeatureEnabled) : void 0;
|
|
258
|
-
return [
|
|
259
|
-
{
|
|
260
|
-
...link,
|
|
261
|
-
links: nestedLinks
|
|
262
|
-
}
|
|
263
|
-
];
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
function createShellNavItem(navEntry, placement, source, featureId, links = navEntry.links) {
|
|
267
|
-
return {
|
|
268
|
-
...navEntry,
|
|
269
|
-
links,
|
|
270
|
-
placement,
|
|
271
|
-
source,
|
|
272
|
-
featureId
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
function createFeatureShellNavItem(feature, links = feature.navEntry?.links) {
|
|
276
|
-
if (!feature.navEntry) {
|
|
277
|
-
return void 0;
|
|
278
|
-
}
|
|
279
|
-
return createShellNavItem(feature.navEntry, "primary", "feature", feature.access.featureId, links);
|
|
280
|
-
}
|
|
281
|
-
function getFeatureNavItems(features, disabledSubsectionPaths, isFeatureEnabled) {
|
|
282
|
-
return features.flatMap((feature) => {
|
|
283
|
-
if (!feature.navEntry) {
|
|
284
|
-
return [];
|
|
285
|
-
}
|
|
286
|
-
const links = feature.navEntry.links?.length ? filterNavLinks(feature.navEntry.links, disabledSubsectionPaths, isFeatureEnabled) : void 0;
|
|
287
|
-
const navItem = createFeatureShellNavItem(feature, links);
|
|
288
|
-
return navItem ? [navItem] : [];
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
function resolveAppShellOverrides(appShellOverrides, organizationModel) {
|
|
292
|
-
if (!appShellOverrides) {
|
|
293
|
-
return {};
|
|
294
|
-
}
|
|
295
|
-
return {
|
|
296
|
-
primaryNavItems: appShellOverrides.primaryNavItems?.map((navItem) => resolveNavEntry(navItem, organizationModel)),
|
|
297
|
-
bottomNavItems: appShellOverrides.bottomNavItems?.map((navItem) => resolveNavEntry(navItem, organizationModel))
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
function getAppShellNavItems(navItems, placement, disabledSubsectionPaths, isFeatureEnabled) {
|
|
301
|
-
if (!navItems?.length) {
|
|
302
|
-
return [];
|
|
303
|
-
}
|
|
304
|
-
return navItems.flatMap((navItem) => {
|
|
305
|
-
if (navItem.featureKey && !isFeatureEnabled(navItem.featureKey)) {
|
|
306
|
-
return [];
|
|
307
|
-
}
|
|
308
|
-
const links = navItem.links?.length ? filterNavLinks(navItem.links, disabledSubsectionPaths, isFeatureEnabled) : void 0;
|
|
309
|
-
if (navItem.links && !links?.length && !navItem.link) {
|
|
310
|
-
return [];
|
|
311
|
-
}
|
|
312
|
-
return [createShellNavItem(navItem, placement, "app", navItem.featureKey, links)];
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
function findMatchingNavLink(links, currentPath) {
|
|
316
|
-
for (const link of links) {
|
|
317
|
-
if (link.links?.length) {
|
|
318
|
-
const nestedLink = findMatchingNavLink(link.links, currentPath);
|
|
319
|
-
if (nestedLink) {
|
|
320
|
-
return nestedLink;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
if (isRouteMatch(currentPath, link.link)) {
|
|
324
|
-
return link;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return null;
|
|
328
|
-
}
|
|
329
|
-
function isHiddenNavLink(link, disabledSubsectionPaths, isFeatureEnabled) {
|
|
330
|
-
if (link.featureKey && !isFeatureEnabled(link.featureKey)) {
|
|
331
|
-
return true;
|
|
332
|
-
}
|
|
333
|
-
return disabledSubsectionPaths.some((disabledPath) => isRouteMatch(link.link, disabledPath));
|
|
334
|
-
}
|
|
335
|
-
function resolveRoute(features, currentPath, disabledSubsectionPaths, isFeatureEnabled) {
|
|
336
|
-
for (const feature of features) {
|
|
337
|
-
const navEntry = feature.navEntry;
|
|
338
|
-
const matchesSubshell = feature.subshellRoutes?.some((route) => isRouteMatch(currentPath, route)) ?? false;
|
|
339
|
-
const matchesEntryLink = navEntry?.link ? isRouteMatch(currentPath, navEntry.link) : false;
|
|
340
|
-
const matchedLink = navEntry?.links?.length ? findMatchingNavLink(navEntry.links, currentPath) : null;
|
|
341
|
-
if (!matchesSubshell && !matchesEntryLink && !matchedLink) {
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
if (matchedLink && isHiddenNavLink(matchedLink, disabledSubsectionPaths, isFeatureEnabled)) {
|
|
345
|
-
return {
|
|
346
|
-
status: "hidden",
|
|
347
|
-
path: currentPath,
|
|
348
|
-
feature,
|
|
349
|
-
navItem: createFeatureShellNavItem(feature),
|
|
350
|
-
navLink: matchedLink
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
return {
|
|
354
|
-
status: "matched",
|
|
355
|
-
path: currentPath,
|
|
356
|
-
feature,
|
|
357
|
-
navItem: createFeatureShellNavItem(feature),
|
|
358
|
-
navLink: matchedLink ?? void 0
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
return {
|
|
362
|
-
status: "unmatched",
|
|
363
|
-
path: currentPath
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
function ElevasisFeaturesProvider({
|
|
367
|
-
features,
|
|
368
|
-
organizationModel,
|
|
369
|
-
appShellOverrides,
|
|
370
|
-
timeRange,
|
|
371
|
-
operationsApiUrl,
|
|
372
|
-
operationsSSEManager,
|
|
373
|
-
deliveryApiUrl,
|
|
374
|
-
deliverySSEManager,
|
|
375
|
-
disabledSubsectionPaths = [],
|
|
376
|
-
children
|
|
377
|
-
}) {
|
|
378
|
-
useMemo(() => validateManifests(features, organizationModel), [features, organizationModel]);
|
|
379
|
-
const { hasFeature } = useFeatureAccess();
|
|
380
|
-
const hasResolvedFeature = useCallback(
|
|
381
|
-
(key) => {
|
|
382
|
-
if (!hasFeature(key)) {
|
|
383
|
-
return false;
|
|
384
|
-
}
|
|
385
|
-
const organizationModelFeatureEnabled = isOrganizationModelFeatureEnabled(organizationModel, key);
|
|
386
|
-
if (organizationModelFeatureEnabled === void 0) {
|
|
387
|
-
return true;
|
|
388
|
-
}
|
|
389
|
-
return organizationModelFeatureEnabled;
|
|
390
|
-
},
|
|
391
|
-
[hasFeature, organizationModel]
|
|
392
|
-
);
|
|
393
|
-
const normalizedDisabledSubsectionPaths = useMemo(() => {
|
|
394
|
-
const explicit = disabledSubsectionPaths.map((path) => normalizeRoutePath(path));
|
|
395
|
-
const fromModel = organizationModel?.navigation.surfaces.filter((s) => s.enabled === false).map((s) => normalizeRoutePath(s.path)) ?? [];
|
|
396
|
-
return [.../* @__PURE__ */ new Set([...explicit, ...fromModel])];
|
|
397
|
-
}, [disabledSubsectionPaths, organizationModel]);
|
|
398
|
-
const resolvedFeatures = useMemo(
|
|
399
|
-
() => resolveFeatureModules(features, organizationModel, hasResolvedFeature),
|
|
400
|
-
[features, organizationModel, hasResolvedFeature]
|
|
401
|
-
);
|
|
402
|
-
const resolvedAppShellOverrides = useMemo(
|
|
403
|
-
() => resolveAppShellOverrides(appShellOverrides, organizationModel),
|
|
404
|
-
[appShellOverrides, organizationModel]
|
|
405
|
-
);
|
|
406
|
-
const enabledResolvedFeatures = useMemo(
|
|
407
|
-
() => resolvedFeatures.filter((feature) => feature.access.enabled),
|
|
408
|
-
[resolvedFeatures]
|
|
409
|
-
);
|
|
410
|
-
const featureNavItems = useMemo(
|
|
411
|
-
() => getFeatureNavItems(enabledResolvedFeatures, normalizedDisabledSubsectionPaths, hasResolvedFeature),
|
|
412
|
-
[enabledResolvedFeatures, normalizedDisabledSubsectionPaths, hasResolvedFeature]
|
|
413
|
-
);
|
|
414
|
-
const primaryNavItems = useMemo(
|
|
415
|
-
() => [
|
|
416
|
-
...getAppShellNavItems(
|
|
417
|
-
resolvedAppShellOverrides.primaryNavItems,
|
|
418
|
-
"primary",
|
|
419
|
-
normalizedDisabledSubsectionPaths,
|
|
420
|
-
hasResolvedFeature
|
|
421
|
-
),
|
|
422
|
-
...featureNavItems
|
|
423
|
-
],
|
|
424
|
-
[resolvedAppShellOverrides.primaryNavItems, normalizedDisabledSubsectionPaths, hasResolvedFeature, featureNavItems]
|
|
425
|
-
);
|
|
426
|
-
const bottomNavItems = useMemo(
|
|
427
|
-
() => getAppShellNavItems(
|
|
428
|
-
resolvedAppShellOverrides.bottomNavItems,
|
|
429
|
-
"bottom",
|
|
430
|
-
normalizedDisabledSubsectionPaths,
|
|
431
|
-
hasResolvedFeature
|
|
432
|
-
),
|
|
433
|
-
[resolvedAppShellOverrides.bottomNavItems, normalizedDisabledSubsectionPaths, hasResolvedFeature]
|
|
434
|
-
);
|
|
435
|
-
const shellNavItems = useMemo(() => [...primaryNavItems, ...bottomNavItems], [primaryNavItems, bottomNavItems]);
|
|
436
|
-
const shellModel = useMemo(
|
|
437
|
-
() => ({
|
|
438
|
-
navItems: shellNavItems
|
|
439
|
-
}),
|
|
440
|
-
[shellNavItems]
|
|
441
|
-
);
|
|
442
|
-
const organizationGraph = useMemo(
|
|
443
|
-
() => resolveOrganizationGraphSurface(enabledResolvedFeatures, organizationModel),
|
|
444
|
-
[enabledResolvedFeatures, organizationModel]
|
|
445
|
-
);
|
|
446
|
-
const getResolvedFeature = useCallback(
|
|
447
|
-
(key) => resolvedFeatures.find((feature) => feature.key === key),
|
|
448
|
-
[resolvedFeatures]
|
|
449
|
-
);
|
|
450
|
-
const isFeatureEnabled = useCallback((key) => hasResolvedFeature(key), [hasResolvedFeature]);
|
|
451
|
-
const resolveRouteByPath = useCallback(
|
|
452
|
-
(path) => resolveRoute(enabledResolvedFeatures, path, normalizedDisabledSubsectionPaths, isFeatureEnabled),
|
|
453
|
-
[enabledResolvedFeatures, normalizedDisabledSubsectionPaths, isFeatureEnabled]
|
|
454
|
-
);
|
|
455
|
-
const shellRuntime = useMemo(
|
|
456
|
-
() => ({
|
|
457
|
-
resolveRoute: resolveRouteByPath
|
|
458
|
-
}),
|
|
459
|
-
[resolveRouteByPath]
|
|
460
|
-
);
|
|
461
|
-
const value = useMemo(
|
|
462
|
-
() => ({
|
|
463
|
-
shellModel,
|
|
464
|
-
shellRuntime,
|
|
465
|
-
enabledResolvedFeatures,
|
|
466
|
-
resolvedFeatures,
|
|
467
|
-
organizationGraph,
|
|
468
|
-
organizationModel,
|
|
469
|
-
timeRange,
|
|
470
|
-
operationsApiUrl,
|
|
471
|
-
operationsSSEManager,
|
|
472
|
-
deliveryApiUrl,
|
|
473
|
-
deliverySSEManager,
|
|
474
|
-
disabledSubsectionPaths: normalizedDisabledSubsectionPaths,
|
|
475
|
-
isFeatureEnabled,
|
|
476
|
-
getResolvedFeature
|
|
477
|
-
}),
|
|
478
|
-
[
|
|
479
|
-
shellModel,
|
|
480
|
-
shellRuntime,
|
|
481
|
-
enabledResolvedFeatures,
|
|
482
|
-
resolvedFeatures,
|
|
483
|
-
organizationGraph,
|
|
484
|
-
organizationModel,
|
|
485
|
-
timeRange,
|
|
486
|
-
operationsApiUrl,
|
|
487
|
-
operationsSSEManager,
|
|
488
|
-
deliveryApiUrl,
|
|
489
|
-
deliverySSEManager,
|
|
490
|
-
normalizedDisabledSubsectionPaths,
|
|
491
|
-
isFeatureEnabled,
|
|
492
|
-
getResolvedFeature
|
|
493
|
-
]
|
|
494
|
-
);
|
|
495
|
-
return /* @__PURE__ */ jsx(ElevasisFeaturesContext.Provider, { value, children });
|
|
496
|
-
}
|
|
497
|
-
function FeatureShell({ children }) {
|
|
498
|
-
const { shellRuntime } = useElevasisFeatures();
|
|
499
|
-
const { currentPath } = useRouterContext();
|
|
500
|
-
const routeMatch = shellRuntime.resolveRoute(currentPath);
|
|
501
|
-
if (routeMatch.status === "hidden") {
|
|
502
|
-
return /* @__PURE__ */ jsx(FeatureUnavailableState, { path: currentPath });
|
|
503
|
-
}
|
|
504
|
-
if (routeMatch.status !== "matched" || !routeMatch.feature?.sidebar) {
|
|
505
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
506
|
-
}
|
|
507
|
-
const SidebarComponent = routeMatch.feature.sidebar;
|
|
508
|
-
return /* @__PURE__ */ jsxs(SubshellContainer, { children: [
|
|
509
|
-
/* @__PURE__ */ jsx(SubshellSidebar, { width: 250, children: /* @__PURE__ */ jsx(SidebarComponent, {}) }),
|
|
510
|
-
/* @__PURE__ */ jsx(SubshellRightSideContainer, { children })
|
|
511
|
-
] });
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
export { ElevasisFeaturesProvider, FeatureShell, createFeatureAccessHook, createUseFeatureAccess, useElevasisFeatures, useOptionalElevasisFeatures };
|