@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
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import { ChatHeader, ChatSidebar } from './chunk-ROSMICXG.js';
|
|
2
2
|
import { SubshellSidebarLoader, SubshellLoader } from './chunk-3JCMO7SD.js';
|
|
3
|
-
import { BaseNode, useGraphTheme, BaseEdge, FormFieldRenderer, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-
|
|
4
|
-
import { ResourceHealthPanel } from './chunk-
|
|
5
|
-
import { useCyberColors, CyberDonut } from './chunk-
|
|
3
|
+
import { BaseNode, useGraphTheme, BaseEdge, FormFieldRenderer, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-LKVBEE63.js';
|
|
4
|
+
import { ResourceHealthPanel } from './chunk-GJ7EIABJ.js';
|
|
5
|
+
import { useCyberColors, CyberDonut } from './chunk-TSSKOQBX.js';
|
|
6
6
|
import { AppShellLoader } from './chunk-M25JL54Z.js';
|
|
7
7
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
8
8
|
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
9
|
-
import { CustomModal, ConfirmationModal } from './chunk-
|
|
9
|
+
import { CustomModal, ConfirmationModal } from './chunk-KVJ3LFH2.js';
|
|
10
10
|
import { getResourceStatusColor, useTimelineData, useAgentIterationData, getStatusIcon } from './chunk-E4WQGJNS.js';
|
|
11
|
-
import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, useExecuteAsync, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions } from './chunk-
|
|
12
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-
|
|
11
|
+
import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, collectResourceFilterFacets, useExecuteAsync, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, COMMAND_VIEW_VISUALIZATION_MODES, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions, getCommandViewGraphPositions } from './chunk-B4FHWKEF.js';
|
|
12
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-Z6FAH4XV.js';
|
|
13
13
|
import { useGraphHighlighting, calculateGraphHeight, Graph_module_css_default, GRAPH_CONSTANTS } from './chunk-22UVE3RA.js';
|
|
14
14
|
import { useMergedExecution } from './chunk-3ZMAGTWF.js';
|
|
15
|
-
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-
|
|
16
|
-
import { SubshellContentContainer } from './chunk-
|
|
17
|
-
import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-
|
|
15
|
+
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-LJWV4TWV.js';
|
|
16
|
+
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
17
|
+
import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-XUYBOO32.js';
|
|
18
18
|
import { StyledMarkdown } from './chunk-3KMDHCAR.js';
|
|
19
19
|
import { NavigationButton } from './chunk-NYBEU5TE.js';
|
|
20
20
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
21
21
|
import { useAppearance } from './chunk-QJ2KCHKX.js';
|
|
22
22
|
import { topbarHeight } from './chunk-DT3QYZVU.js';
|
|
23
|
-
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime,
|
|
23
|
+
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, getNodeId, PAGE_SIZE_DEFAULT, debounce } from './chunk-SGXXJE52.js';
|
|
24
24
|
import { ResourceStatusColors, toWorkflowLogMessages } from './chunk-KRWALB24.js';
|
|
25
25
|
import { useInitialization } from './chunk-DK2HVHCY.js';
|
|
26
26
|
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
27
27
|
import { z } from 'zod';
|
|
28
|
-
import { Stack, Group, Text, Badge, Title, Textarea, Alert, Button, ActionIcon, Collapse, Card, ThemeIcon, SimpleGrid, Divider, Paper, Space, CopyButton, Center, Tooltip, Code, Menu, useMantineTheme, UnstyledButton, Select, RangeSlider, Box, Progress, Tabs, Pagination, TextInput, Modal, LoadingOverlay, Loader, SegmentedControl,
|
|
28
|
+
import { Stack, Group, Text, Badge, Title, Textarea, Alert, Button, ActionIcon, Collapse, Card, ThemeIcon, SimpleGrid, Divider, Paper, Space, CopyButton, Center, Tooltip, Code, Menu, useMantineTheme, UnstyledButton, Select, RangeSlider, Box, Progress, Tabs, Pagination, TextInput, Modal, LoadingOverlay, Loader, SegmentedControl, ScrollArea, Checkbox, MultiSelect, Switch } from '@mantine/core';
|
|
29
29
|
import { IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconCode, IconAlertCircle, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconPlayerPlay, IconNetwork, IconSitemap, IconCopy, IconPlayerStop, IconReload, IconTrash, IconTerminal2, IconBug, IconChevronDown, IconMessage, IconArrowLeft, IconRobot, IconGitBranch, IconDotsVertical, IconFilter, IconCircleCheck, IconCategory, IconDatabase, IconApps, IconRoute, IconAdjustmentsHorizontal, IconSearch, IconCircleX, IconCircleDashed, IconExternalLink, IconFolders, IconBraces, IconBolt, IconTopologyStar3, IconInfoCircle, IconPlus, IconLayoutSidebarRightExpand, IconNote, IconArchive, IconDownload, IconTimeline, IconActivityHeartbeat, IconClockPause, IconArrowsMaximize, IconShare2, IconHistory } from '@tabler/icons-react';
|
|
30
30
|
import { useForm } from '@mantine/form';
|
|
31
31
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -72,7 +72,7 @@ var TechStackEntrySchema = z.object({
|
|
|
72
72
|
*/
|
|
73
73
|
isSystemOfRecord: z.boolean().default(false)
|
|
74
74
|
});
|
|
75
|
-
|
|
75
|
+
DisplayMetadataSchema.extend({
|
|
76
76
|
id: ModelIdSchema,
|
|
77
77
|
resourceId: z.string().trim().min(1).max(255),
|
|
78
78
|
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
|
|
@@ -84,7 +84,22 @@ var ResourceMappingSchema = DisplayMetadataSchema.extend({
|
|
|
84
84
|
techStack: TechStackEntrySchema.optional()
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
// ../core/src/organization-model/domains/
|
|
87
|
+
// ../core/src/organization-model/domains/features.ts
|
|
88
|
+
var NodeIdPathSchema = z.string().trim().min(1).max(100).regex(/^([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node IDs must be lowercase dotted paths");
|
|
89
|
+
z.string().trim().min(1).max(200).regex(/^[a-z]+:([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node references must use kind:dotted-path");
|
|
90
|
+
var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]);
|
|
91
|
+
var FeatureSchema = z.object({
|
|
92
|
+
id: NodeIdPathSchema,
|
|
93
|
+
label: LabelSchema,
|
|
94
|
+
description: DescriptionSchema.optional(),
|
|
95
|
+
enabled: z.boolean().default(true),
|
|
96
|
+
path: PathSchema.optional(),
|
|
97
|
+
icon: IconNameSchema.optional(),
|
|
98
|
+
color: ColorTokenSchema.optional(),
|
|
99
|
+
uiPosition: UiPositionSchema.optional(),
|
|
100
|
+
requiresAdmin: z.boolean().optional(),
|
|
101
|
+
devOnly: z.boolean().optional()
|
|
102
|
+
});
|
|
88
103
|
var OrganizationModelBrandingSchema = z.object({
|
|
89
104
|
organizationName: LabelSchema,
|
|
90
105
|
productName: LabelSchema,
|
|
@@ -127,18 +142,6 @@ var OrganizationModelProjectsSchema = z.object({
|
|
|
127
142
|
milestoneStatuses: z.array(ProjectsDomainStateSchema).min(1),
|
|
128
143
|
taskStatuses: z.array(ProjectsDomainStateSchema).min(1)
|
|
129
144
|
});
|
|
130
|
-
var FeatureSchema = z.object({
|
|
131
|
-
id: ModelIdSchema,
|
|
132
|
-
label: LabelSchema,
|
|
133
|
-
description: DescriptionSchema.optional(),
|
|
134
|
-
enabled: z.boolean().default(true),
|
|
135
|
-
color: ColorTokenSchema.optional(),
|
|
136
|
-
icon: IconNameSchema.optional(),
|
|
137
|
-
entityIds: ReferenceIdsSchema,
|
|
138
|
-
surfaceIds: ReferenceIdsSchema,
|
|
139
|
-
resourceIds: ReferenceIdsSchema,
|
|
140
|
-
capabilityIds: ReferenceIdsSchema
|
|
141
|
-
});
|
|
142
145
|
var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
143
146
|
id: ModelIdSchema,
|
|
144
147
|
order: z.number().int().min(0)
|
|
@@ -159,6 +162,7 @@ var SurfaceDefinitionSchema = z.object({
|
|
|
159
162
|
surfaceType: SurfaceTypeSchema,
|
|
160
163
|
description: DescriptionSchema.optional(),
|
|
161
164
|
enabled: z.boolean().default(true),
|
|
165
|
+
devOnly: z.boolean().optional(),
|
|
162
166
|
icon: IconNameSchema.optional(),
|
|
163
167
|
featureId: ModelIdSchema.optional(),
|
|
164
168
|
featureIds: ReferenceIdsSchema,
|
|
@@ -456,7 +460,7 @@ var OrganizationModelSchemaBase = z.object({
|
|
|
456
460
|
version: z.literal(1).default(1),
|
|
457
461
|
features: z.array(FeatureSchema).default([]),
|
|
458
462
|
branding: OrganizationModelBrandingSchema,
|
|
459
|
-
navigation: OrganizationModelNavigationSchema,
|
|
463
|
+
navigation: OrganizationModelNavigationSchema.default({ surfaces: [], groups: [] }),
|
|
460
464
|
sales: OrganizationModelSalesSchema,
|
|
461
465
|
prospecting: OrganizationModelProspectingSchema,
|
|
462
466
|
projects: OrganizationModelProjectsSchema,
|
|
@@ -466,8 +470,7 @@ var OrganizationModelSchemaBase = z.object({
|
|
|
466
470
|
roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
|
|
467
471
|
goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
|
|
468
472
|
statuses: StatusesDomainSchema.default({ entries: [] }),
|
|
469
|
-
operations: OperationsDomainSchema.default({ entries: [] })
|
|
470
|
-
resourceMappings: z.array(ResourceMappingSchema).default([])
|
|
473
|
+
operations: OperationsDomainSchema.default({ entries: [] })
|
|
471
474
|
});
|
|
472
475
|
function addIssue(ctx, path, message) {
|
|
473
476
|
ctx.addIssue({
|
|
@@ -487,123 +490,39 @@ function collectIds(items, ctx, collectionPath, label) {
|
|
|
487
490
|
});
|
|
488
491
|
return itemsById;
|
|
489
492
|
}
|
|
493
|
+
var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
|
|
494
|
+
["crm", "sales.crm"],
|
|
495
|
+
["lead-gen", "sales.lead-gen"],
|
|
496
|
+
["submitted-requests", "monitoring.submitted-requests"]
|
|
497
|
+
]);
|
|
498
|
+
function hasFeature(featuresById, featureId) {
|
|
499
|
+
return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
|
|
500
|
+
}
|
|
490
501
|
var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
491
502
|
const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
|
|
492
|
-
const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Surface");
|
|
493
|
-
collectIds(model.navigation.groups, ctx, ["navigation", "groups"], "Navigation group");
|
|
494
|
-
collectIds(model.resourceMappings, ctx, ["resourceMappings"], "Resource mapping");
|
|
495
|
-
const resourceMappingsByResourceId = /* @__PURE__ */ new Map();
|
|
496
|
-
model.resourceMappings.forEach((resourceMapping, index) => {
|
|
497
|
-
if (resourceMappingsByResourceId.has(resourceMapping.resourceId)) {
|
|
498
|
-
addIssue(
|
|
499
|
-
ctx,
|
|
500
|
-
["resourceMappings", index, "resourceId"],
|
|
501
|
-
`Resource mapping resourceId "${resourceMapping.resourceId}" must be unique`
|
|
502
|
-
);
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
resourceMappingsByResourceId.set(resourceMapping.resourceId, resourceMapping);
|
|
506
|
-
});
|
|
507
|
-
if (model.navigation.defaultSurfaceId && !surfacesById.has(model.navigation.defaultSurfaceId)) {
|
|
508
|
-
addIssue(
|
|
509
|
-
ctx,
|
|
510
|
-
["navigation", "defaultSurfaceId"],
|
|
511
|
-
`Default surface "${model.navigation.defaultSurfaceId}" must reference a declared navigation surface`
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
model.navigation.groups.forEach((group, groupIndex) => {
|
|
515
|
-
group.surfaceIds.forEach((surfaceId, surfaceIndex) => {
|
|
516
|
-
if (!surfacesById.has(surfaceId)) {
|
|
517
|
-
addIssue(
|
|
518
|
-
ctx,
|
|
519
|
-
["navigation", "groups", groupIndex, "surfaceIds", surfaceIndex],
|
|
520
|
-
`Navigation group "${group.id}" references unknown surface "${surfaceId}"`
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
});
|
|
524
|
-
});
|
|
525
503
|
model.features.forEach((feature, featureIndex) => {
|
|
526
|
-
feature.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
["features", featureIndex, "surfaceIds", surfaceIndex],
|
|
532
|
-
`Feature "${feature.id}" references unknown surface "${surfaceId}"`
|
|
533
|
-
);
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
if (!surface.featureIds.includes(feature.id)) {
|
|
537
|
-
addIssue(
|
|
538
|
-
ctx,
|
|
539
|
-
["features", featureIndex, "surfaceIds", surfaceIndex],
|
|
540
|
-
`Feature "${feature.id}" references surface "${surfaceId}" but that surface does not include feature "${feature.id}"`
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
feature.resourceIds.forEach((resourceId, resourceIndex) => {
|
|
545
|
-
const resourceMapping = resourceMappingsByResourceId.get(resourceId);
|
|
546
|
-
if (!resourceMapping) {
|
|
547
|
-
addIssue(
|
|
548
|
-
ctx,
|
|
549
|
-
["features", featureIndex, "resourceIds", resourceIndex],
|
|
550
|
-
`Feature "${feature.id}" references unknown resource "${resourceId}"`
|
|
551
|
-
);
|
|
552
|
-
return;
|
|
504
|
+
const segments = feature.id.split(".");
|
|
505
|
+
if (segments.length > 1) {
|
|
506
|
+
const parentId = segments.slice(0, -1).join(".");
|
|
507
|
+
if (!featuresById.has(parentId)) {
|
|
508
|
+
addIssue(ctx, ["features", featureIndex, "id"], `Feature "${feature.id}" references unknown parent "${parentId}"`);
|
|
553
509
|
}
|
|
554
|
-
if (!resourceMapping.featureIds.includes(feature.id)) {
|
|
555
|
-
addIssue(
|
|
556
|
-
ctx,
|
|
557
|
-
["features", featureIndex, "resourceIds", resourceIndex],
|
|
558
|
-
`Feature "${feature.id}" references resource "${resourceId}" but that resource mapping does not include feature "${feature.id}"`
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
});
|
|
563
|
-
model.navigation.surfaces.forEach((surface, surfaceIndex) => {
|
|
564
|
-
if (surface.parentId && !surfacesById.has(surface.parentId)) {
|
|
565
|
-
addIssue(
|
|
566
|
-
ctx,
|
|
567
|
-
["navigation", "surfaces", surfaceIndex, "parentId"],
|
|
568
|
-
`Surface "${surface.id}" references unknown parent surface "${surface.parentId}"`
|
|
569
|
-
);
|
|
570
510
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
if (!feature.surfaceIds.includes(surface.id)) {
|
|
582
|
-
addIssue(
|
|
583
|
-
ctx,
|
|
584
|
-
["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
|
|
585
|
-
`Surface "${surface.id}" references feature "${featureId}" but that feature does not include surface "${surface.id}"`
|
|
586
|
-
);
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
surface.resourceIds.forEach((resourceId, resourceIndex) => {
|
|
590
|
-
const resourceMapping = resourceMappingsByResourceId.get(resourceId);
|
|
591
|
-
if (!resourceMapping) {
|
|
592
|
-
addIssue(
|
|
593
|
-
ctx,
|
|
594
|
-
["navigation", "surfaces", surfaceIndex, "resourceIds", resourceIndex],
|
|
595
|
-
`Surface "${surface.id}" references unknown resource "${resourceId}"`
|
|
596
|
-
);
|
|
597
|
-
return;
|
|
598
|
-
}
|
|
599
|
-
if (!resourceMapping.surfaceIds.includes(surface.id)) {
|
|
511
|
+
const hasChildren = model.features.some(
|
|
512
|
+
(candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
|
|
513
|
+
);
|
|
514
|
+
if (hasChildren && feature.enabled) {
|
|
515
|
+
const hasEnabledDescendant = model.features.some(
|
|
516
|
+
(candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
|
|
517
|
+
);
|
|
518
|
+
if (!hasEnabledDescendant) {
|
|
600
519
|
addIssue(
|
|
601
520
|
ctx,
|
|
602
|
-
["
|
|
603
|
-
`
|
|
521
|
+
["features", featureIndex, "enabled"],
|
|
522
|
+
`Feature "${feature.id}" is enabled but has no enabled descendants`
|
|
604
523
|
);
|
|
605
524
|
}
|
|
606
|
-
}
|
|
525
|
+
}
|
|
607
526
|
});
|
|
608
527
|
const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
|
|
609
528
|
model.offerings.products.forEach((product, productIndex) => {
|
|
@@ -616,7 +535,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
616
535
|
);
|
|
617
536
|
}
|
|
618
537
|
});
|
|
619
|
-
if (product.deliveryFeatureId !== void 0 && !featuresById
|
|
538
|
+
if (product.deliveryFeatureId !== void 0 && !hasFeature(featuresById, product.deliveryFeatureId)) {
|
|
620
539
|
addIssue(
|
|
621
540
|
ctx,
|
|
622
541
|
["offerings", "products", productIndex, "deliveryFeatureId"],
|
|
@@ -643,45 +562,9 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
643
562
|
);
|
|
644
563
|
}
|
|
645
564
|
});
|
|
646
|
-
model.resourceMappings.forEach((resourceMapping, resourceIndex) => {
|
|
647
|
-
resourceMapping.featureIds.forEach((featureId, featureIndex) => {
|
|
648
|
-
const feature = featuresById.get(featureId);
|
|
649
|
-
if (!feature) {
|
|
650
|
-
addIssue(
|
|
651
|
-
ctx,
|
|
652
|
-
["resourceMappings", resourceIndex, "featureIds", featureIndex],
|
|
653
|
-
`Resource mapping "${resourceMapping.id}" references unknown feature "${featureId}"`
|
|
654
|
-
);
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
if (!feature.resourceIds.includes(resourceMapping.resourceId)) {
|
|
658
|
-
addIssue(
|
|
659
|
-
ctx,
|
|
660
|
-
["resourceMappings", resourceIndex, "featureIds", featureIndex],
|
|
661
|
-
`Resource mapping "${resourceMapping.id}" references feature "${featureId}" but that feature does not include resource "${resourceMapping.resourceId}"`
|
|
662
|
-
);
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
resourceMapping.surfaceIds.forEach((surfaceId, surfaceIndex) => {
|
|
666
|
-
const surface = surfacesById.get(surfaceId);
|
|
667
|
-
if (!surface) {
|
|
668
|
-
addIssue(
|
|
669
|
-
ctx,
|
|
670
|
-
["resourceMappings", resourceIndex, "surfaceIds", surfaceIndex],
|
|
671
|
-
`Resource mapping "${resourceMapping.id}" references unknown surface "${surfaceId}"`
|
|
672
|
-
);
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
if (!surface.resourceIds.includes(resourceMapping.resourceId)) {
|
|
676
|
-
addIssue(
|
|
677
|
-
ctx,
|
|
678
|
-
["resourceMappings", resourceIndex, "surfaceIds", surfaceIndex],
|
|
679
|
-
`Resource mapping "${resourceMapping.id}" references surface "${surfaceId}" but that surface does not include resource "${resourceMapping.resourceId}"`
|
|
680
|
-
);
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
});
|
|
684
565
|
});
|
|
566
|
+
|
|
567
|
+
// ../core/src/organization-model/graph/schema.ts
|
|
685
568
|
var OrganizationGraphNodeKindSchema = z.enum([
|
|
686
569
|
"organization",
|
|
687
570
|
"feature",
|
|
@@ -690,7 +573,14 @@ var OrganizationGraphNodeKindSchema = z.enum([
|
|
|
690
573
|
"capability",
|
|
691
574
|
"resource"
|
|
692
575
|
]);
|
|
693
|
-
var OrganizationGraphEdgeKindSchema = z.enum([
|
|
576
|
+
var OrganizationGraphEdgeKindSchema = z.enum([
|
|
577
|
+
"contains",
|
|
578
|
+
"references",
|
|
579
|
+
"exposes",
|
|
580
|
+
"maps_to",
|
|
581
|
+
"operates-on",
|
|
582
|
+
"uses"
|
|
583
|
+
]);
|
|
694
584
|
var OrganizationGraphNodeSchema = z.object({
|
|
695
585
|
id: z.string().trim().min(1).max(200),
|
|
696
586
|
kind: OrganizationGraphNodeKindSchema,
|
|
@@ -698,8 +588,7 @@ var OrganizationGraphNodeSchema = z.object({
|
|
|
698
588
|
sourceId: z.string().trim().min(1).max(255).optional(),
|
|
699
589
|
description: DescriptionSchema.optional(),
|
|
700
590
|
enabled: z.boolean().optional(),
|
|
701
|
-
featureId:
|
|
702
|
-
surfaceType: SurfaceTypeSchema.optional(),
|
|
591
|
+
featureId: z.string().trim().min(1).max(100).optional(),
|
|
703
592
|
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]).optional()
|
|
704
593
|
});
|
|
705
594
|
var OrganizationGraphEdgeSchema = z.object({
|
|
@@ -782,6 +671,16 @@ function collectCommandViewResources(commandViewData) {
|
|
|
782
671
|
...commandViewData.humanCheckpoints
|
|
783
672
|
];
|
|
784
673
|
}
|
|
674
|
+
function pushResourceLinks(edges, edgeIds, resourceNodeId, links) {
|
|
675
|
+
for (const link of links ?? []) {
|
|
676
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
677
|
+
id: edgeId(link.kind, resourceNodeId, link.nodeId),
|
|
678
|
+
kind: link.kind,
|
|
679
|
+
sourceId: resourceNodeId,
|
|
680
|
+
targetId: link.nodeId
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
}
|
|
785
684
|
function buildOrganizationGraph(input) {
|
|
786
685
|
const parsed = BuildOrganizationGraphInputSchema.parse(input);
|
|
787
686
|
const organizationModel = parsed.organizationModel;
|
|
@@ -797,27 +696,6 @@ function buildOrganizationGraph(input) {
|
|
|
797
696
|
label: "Organization Model"
|
|
798
697
|
};
|
|
799
698
|
pushUniqueNode(nodes, nodeIds, organizationNode);
|
|
800
|
-
const featureMap = /* @__PURE__ */ new Map();
|
|
801
|
-
for (const feature of organizationModel.features) {
|
|
802
|
-
featureMap.set(feature.id, feature);
|
|
803
|
-
}
|
|
804
|
-
const surfaceMap = /* @__PURE__ */ new Map();
|
|
805
|
-
for (const surface of organizationModel.navigation.surfaces) {
|
|
806
|
-
surfaceMap.set(surface.id, surface);
|
|
807
|
-
}
|
|
808
|
-
const entityIds = /* @__PURE__ */ new Set();
|
|
809
|
-
const capabilityIds = /* @__PURE__ */ new Set();
|
|
810
|
-
const resourceMappings = [...organizationModel.resourceMappings].sort(
|
|
811
|
-
(a, b) => a.resourceId.localeCompare(b.resourceId)
|
|
812
|
-
);
|
|
813
|
-
for (const resourceMapping of resourceMappings) {
|
|
814
|
-
for (const entityId of resourceMapping.entityIds) {
|
|
815
|
-
entityIds.add(entityId);
|
|
816
|
-
}
|
|
817
|
-
for (const capabilityId of resourceMapping.capabilityIds) {
|
|
818
|
-
capabilityIds.add(capabilityId);
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
699
|
for (const feature of [...organizationModel.features].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
822
700
|
const id = nodeId("feature", feature.id);
|
|
823
701
|
pushUniqueNode(nodes, nodeIds, {
|
|
@@ -835,157 +713,15 @@ function buildOrganizationGraph(input) {
|
|
|
835
713
|
sourceId: organizationNode.id,
|
|
836
714
|
targetId: id
|
|
837
715
|
});
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
}
|
|
841
|
-
for (const capabilityId of feature.capabilityIds) {
|
|
842
|
-
capabilityIds.add(capabilityId);
|
|
843
|
-
}
|
|
844
|
-
for (const surfaceId of feature.surfaceIds) {
|
|
845
|
-
const surface = surfaceMap.get(surfaceId);
|
|
846
|
-
if (surface) {
|
|
847
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
848
|
-
id: edgeId("references", id, nodeId("surface", surface.id)),
|
|
849
|
-
kind: "references",
|
|
850
|
-
sourceId: id,
|
|
851
|
-
targetId: nodeId("surface", surface.id)
|
|
852
|
-
});
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
for (const surface of [...organizationModel.navigation.surfaces].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
857
|
-
const id = nodeId("surface", surface.id);
|
|
858
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
859
|
-
id,
|
|
860
|
-
kind: "surface",
|
|
861
|
-
label: surface.label,
|
|
862
|
-
sourceId: surface.id,
|
|
863
|
-
description: surface.description,
|
|
864
|
-
surfaceType: surface.surfaceType
|
|
865
|
-
});
|
|
866
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
867
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
868
|
-
kind: "contains",
|
|
869
|
-
sourceId: organizationNode.id,
|
|
870
|
-
targetId: id
|
|
871
|
-
});
|
|
872
|
-
if (surface.featureId) {
|
|
716
|
+
const parentId = feature.id.includes(".") ? feature.id.slice(0, feature.id.lastIndexOf(".")) : void 0;
|
|
717
|
+
if (parentId) {
|
|
873
718
|
pushUniqueEdge(edges, edgeIds, {
|
|
874
|
-
id: edgeId("
|
|
875
|
-
kind: "
|
|
876
|
-
sourceId: nodeId("feature",
|
|
719
|
+
id: edgeId("contains", nodeId("feature", parentId), id),
|
|
720
|
+
kind: "contains",
|
|
721
|
+
sourceId: nodeId("feature", parentId),
|
|
877
722
|
targetId: id
|
|
878
723
|
});
|
|
879
724
|
}
|
|
880
|
-
for (const featureId of surface.featureIds) {
|
|
881
|
-
if (featureMap.has(featureId)) {
|
|
882
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
883
|
-
id: edgeId("references", id, nodeId("feature", featureId)),
|
|
884
|
-
kind: "references",
|
|
885
|
-
sourceId: id,
|
|
886
|
-
targetId: nodeId("feature", featureId)
|
|
887
|
-
});
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
for (const entityId of surface.entityIds) {
|
|
891
|
-
entityIds.add(entityId);
|
|
892
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
893
|
-
id: edgeId("references", id, nodeId("entity", entityId)),
|
|
894
|
-
kind: "references",
|
|
895
|
-
sourceId: id,
|
|
896
|
-
targetId: nodeId("entity", entityId)
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
|
-
for (const capabilityId of surface.capabilityIds) {
|
|
900
|
-
capabilityIds.add(capabilityId);
|
|
901
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
902
|
-
id: edgeId("references", id, nodeId("capability", capabilityId)),
|
|
903
|
-
kind: "references",
|
|
904
|
-
sourceId: id,
|
|
905
|
-
targetId: nodeId("capability", capabilityId)
|
|
906
|
-
});
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
for (const entityId of [...entityIds].sort()) {
|
|
910
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
911
|
-
id: nodeId("entity", entityId),
|
|
912
|
-
kind: "entity",
|
|
913
|
-
label: entityId,
|
|
914
|
-
sourceId: entityId
|
|
915
|
-
});
|
|
916
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
917
|
-
id: edgeId("contains", organizationNode.id, nodeId("entity", entityId)),
|
|
918
|
-
kind: "contains",
|
|
919
|
-
sourceId: organizationNode.id,
|
|
920
|
-
targetId: nodeId("entity", entityId)
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
for (const capabilityId of [...capabilityIds].sort()) {
|
|
924
|
-
pushUniqueNode(nodes, nodeIds, {
|
|
925
|
-
id: nodeId("capability", capabilityId),
|
|
926
|
-
kind: "capability",
|
|
927
|
-
label: capabilityId,
|
|
928
|
-
sourceId: capabilityId
|
|
929
|
-
});
|
|
930
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
931
|
-
id: edgeId("contains", organizationNode.id, nodeId("capability", capabilityId)),
|
|
932
|
-
kind: "contains",
|
|
933
|
-
sourceId: organizationNode.id,
|
|
934
|
-
targetId: nodeId("capability", capabilityId)
|
|
935
|
-
});
|
|
936
|
-
}
|
|
937
|
-
for (const resourceMapping of resourceMappings) {
|
|
938
|
-
const id = nodeId("resource", resourceMapping.resourceId);
|
|
939
|
-
upsertResourceNode(nodes, nodeIds, resourceNodesById, {
|
|
940
|
-
id,
|
|
941
|
-
kind: "resource",
|
|
942
|
-
label: resourceMapping.label,
|
|
943
|
-
sourceId: resourceMapping.resourceId,
|
|
944
|
-
description: resourceMapping.description,
|
|
945
|
-
resourceType: resourceMapping.resourceType
|
|
946
|
-
});
|
|
947
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
948
|
-
id: edgeId("contains", organizationNode.id, id),
|
|
949
|
-
kind: "contains",
|
|
950
|
-
sourceId: organizationNode.id,
|
|
951
|
-
targetId: id
|
|
952
|
-
});
|
|
953
|
-
for (const featureId of resourceMapping.featureIds) {
|
|
954
|
-
if (featureMap.has(featureId)) {
|
|
955
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
956
|
-
id: edgeId("maps_to", id, nodeId("feature", featureId)),
|
|
957
|
-
kind: "maps_to",
|
|
958
|
-
sourceId: id,
|
|
959
|
-
targetId: nodeId("feature", featureId)
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
for (const entityId of resourceMapping.entityIds) {
|
|
964
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
965
|
-
id: edgeId("maps_to", id, nodeId("entity", entityId)),
|
|
966
|
-
kind: "maps_to",
|
|
967
|
-
sourceId: id,
|
|
968
|
-
targetId: nodeId("entity", entityId)
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
|
-
for (const surfaceId of resourceMapping.surfaceIds) {
|
|
972
|
-
if (surfaceMap.has(surfaceId)) {
|
|
973
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
974
|
-
id: edgeId("maps_to", id, nodeId("surface", surfaceId)),
|
|
975
|
-
kind: "maps_to",
|
|
976
|
-
sourceId: id,
|
|
977
|
-
targetId: nodeId("surface", surfaceId)
|
|
978
|
-
});
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
for (const capabilityId of resourceMapping.capabilityIds) {
|
|
982
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
983
|
-
id: edgeId("maps_to", id, nodeId("capability", capabilityId)),
|
|
984
|
-
kind: "maps_to",
|
|
985
|
-
sourceId: id,
|
|
986
|
-
targetId: nodeId("capability", capabilityId)
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
725
|
}
|
|
990
726
|
if (commandViewData) {
|
|
991
727
|
const commandViewResources = collectCommandViewResources(commandViewData).sort(
|
|
@@ -1001,22 +737,13 @@ function buildOrganizationGraph(input) {
|
|
|
1001
737
|
description: resource.description,
|
|
1002
738
|
resourceType: normalizeCommandViewResourceType(resource.type)
|
|
1003
739
|
});
|
|
1004
|
-
for (const featureId of resource.domains ?? []) {
|
|
1005
|
-
if (featureMap.has(featureId)) {
|
|
1006
|
-
pushUniqueEdge(edges, edgeIds, {
|
|
1007
|
-
id: edgeId("references", resourceNode.id, nodeId("feature", featureId), "feature"),
|
|
1008
|
-
kind: "references",
|
|
1009
|
-
sourceId: resourceNode.id,
|
|
1010
|
-
targetId: nodeId("feature", featureId)
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
740
|
pushUniqueEdge(edges, edgeIds, {
|
|
1015
741
|
id: edgeId("contains", organizationNode.id, resourceNode.id),
|
|
1016
742
|
kind: "contains",
|
|
1017
743
|
sourceId: organizationNode.id,
|
|
1018
744
|
targetId: resourceNode.id
|
|
1019
745
|
});
|
|
746
|
+
pushResourceLinks(edges, edgeIds, resourceNode.id, resource.links);
|
|
1020
747
|
}
|
|
1021
748
|
for (const relationship of [...commandViewData.edges].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
1022
749
|
const sourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.source);
|
|
@@ -3459,18 +3186,10 @@ function ResourcesSidebar({ timeRange }) {
|
|
|
3459
3186
|
const theme = useMantineTheme();
|
|
3460
3187
|
const colors = useCyberColors();
|
|
3461
3188
|
const { data: executionData } = useRecentExecutionsByResource({ timeRange });
|
|
3462
|
-
const
|
|
3189
|
+
const activeFacets = useMemo(() => {
|
|
3463
3190
|
if (!resources) return [];
|
|
3464
3191
|
const allResources = [...resources.workflows || [], ...resources.agents || []];
|
|
3465
|
-
|
|
3466
|
-
allResources.forEach((r) => r.domains?.forEach((d) => domainSet.add(d)));
|
|
3467
|
-
const bottomDomains = /* @__PURE__ */ new Set(["utility", "diagnostic"]);
|
|
3468
|
-
return Array.from(domainSet).sort((a, b) => {
|
|
3469
|
-
const aBottom = bottomDomains.has(a) ? 1 : 0;
|
|
3470
|
-
const bBottom = bottomDomains.has(b) ? 1 : 0;
|
|
3471
|
-
if (aBottom !== bBottom) return aBottom - bBottom;
|
|
3472
|
-
return a.localeCompare(b);
|
|
3473
|
-
});
|
|
3192
|
+
return collectResourceFilterFacets(allResources);
|
|
3474
3193
|
}, [resources]);
|
|
3475
3194
|
const domainFilteredResources = useMemo(() => {
|
|
3476
3195
|
if (!resources) return [];
|
|
@@ -3633,7 +3352,7 @@ function ResourcesSidebar({ timeRange }) {
|
|
|
3633
3352
|
style: { flexShrink: 0 }
|
|
3634
3353
|
}
|
|
3635
3354
|
),
|
|
3636
|
-
|
|
3355
|
+
activeFacets.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3637
3356
|
/* @__PURE__ */ jsx(UnstyledButton, { onClick: () => setDomainsOpen((o) => !o), style: { width: "100%", flexShrink: 0 }, mt: 4, children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
3638
3357
|
/* @__PURE__ */ jsx(
|
|
3639
3358
|
Text,
|
|
@@ -3645,7 +3364,7 @@ function ResourcesSidebar({ timeRange }) {
|
|
|
3645
3364
|
color: "var(--color-text-subtle)",
|
|
3646
3365
|
fontFamily: "var(--elevasis-font-family-subtitle)"
|
|
3647
3366
|
},
|
|
3648
|
-
children: "
|
|
3367
|
+
children: "Resource Facets"
|
|
3649
3368
|
}
|
|
3650
3369
|
),
|
|
3651
3370
|
/* @__PURE__ */ jsx(
|
|
@@ -3668,16 +3387,14 @@ function ResourcesSidebar({ timeRange }) {
|
|
|
3668
3387
|
gridTemplateRows: domainsOpen ? "1fr" : "0fr",
|
|
3669
3388
|
transition: "grid-template-rows 200ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
3670
3389
|
},
|
|
3671
|
-
children: /* @__PURE__ */ jsx("div", { style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(Stack, { gap: 2, mt: "xs", style: { flexShrink: 0 }, children:
|
|
3672
|
-
const
|
|
3673
|
-
if (!domain) return null;
|
|
3674
|
-
const filterState = domainFilters[domainId] || "neutral";
|
|
3390
|
+
children: /* @__PURE__ */ jsx("div", { style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(Stack, { gap: 2, mt: "xs", style: { flexShrink: 0 }, children: activeFacets.map((facet) => {
|
|
3391
|
+
const filterState = domainFilters[facet.id] || "neutral";
|
|
3675
3392
|
const StateIcon = FILTER_STATE_ICONS[filterState];
|
|
3676
3393
|
return /* @__PURE__ */ jsx(
|
|
3677
3394
|
UnstyledButton,
|
|
3678
3395
|
{
|
|
3679
3396
|
title: FILTER_STATE_LABELS[filterState],
|
|
3680
|
-
onClick: () => cycleDomainFilter(
|
|
3397
|
+
onClick: () => cycleDomainFilter(facet.id),
|
|
3681
3398
|
py: 5,
|
|
3682
3399
|
px: 6,
|
|
3683
3400
|
style: {
|
|
@@ -3703,12 +3420,12 @@ function ResourcesSidebar({ timeRange }) {
|
|
|
3703
3420
|
truncate: true,
|
|
3704
3421
|
fw: filterState !== "neutral" ? 500 : 400,
|
|
3705
3422
|
c: filterState !== "neutral" ? void 0 : "dimmed",
|
|
3706
|
-
children:
|
|
3423
|
+
children: facet.label
|
|
3707
3424
|
}
|
|
3708
3425
|
)
|
|
3709
3426
|
] })
|
|
3710
3427
|
},
|
|
3711
|
-
|
|
3428
|
+
facet.id
|
|
3712
3429
|
);
|
|
3713
3430
|
}) }) })
|
|
3714
3431
|
}
|
|
@@ -4590,13 +4307,17 @@ var EDGE_KIND_LABELS = {
|
|
|
4590
4307
|
contains: "Containment",
|
|
4591
4308
|
references: "Reference",
|
|
4592
4309
|
exposes: "Exposure",
|
|
4593
|
-
maps_to: "Mapping"
|
|
4310
|
+
maps_to: "Mapping",
|
|
4311
|
+
"operates-on": "Operates on",
|
|
4312
|
+
uses: "Uses"
|
|
4594
4313
|
};
|
|
4595
4314
|
var EDGE_KIND_MEANINGS = {
|
|
4596
4315
|
contains: "A hierarchy or ownership link inside the shared graph.",
|
|
4597
4316
|
references: "A semantic association or dependency between two graph nodes.",
|
|
4598
4317
|
exposes: "A feature enables a surface to be visible or reachable.",
|
|
4599
|
-
maps_to: "A concrete resource is aligned to a domain, entity, capability, or surface."
|
|
4318
|
+
maps_to: "A concrete resource is aligned to a domain, entity, capability, or surface.",
|
|
4319
|
+
"operates-on": "A concrete resource operates on an Organization Model node.",
|
|
4320
|
+
uses: "A concrete resource depends on another graph node or integration."
|
|
4600
4321
|
};
|
|
4601
4322
|
var RELATIONSHIP_MEANINGS = {
|
|
4602
4323
|
triggers: "Executable handoff: the source resource starts the target resource.",
|
|
@@ -4619,9 +4340,6 @@ function getNodeMeaning(node) {
|
|
|
4619
4340
|
if (node.kind === "feature") {
|
|
4620
4341
|
return node.enabled === false ? `${baseMeaning} This feature is currently disabled in the organization model.` : `${baseMeaning} This feature is currently enabled in the organization model.`;
|
|
4621
4342
|
}
|
|
4622
|
-
if (node.kind === "surface" && node.surfaceType) {
|
|
4623
|
-
return `${baseMeaning} Surface type: ${titleCase(node.surfaceType)}.`;
|
|
4624
|
-
}
|
|
4625
4343
|
if (node.kind === "resource" && node.resourceType) {
|
|
4626
4344
|
return `${baseMeaning} Resource type: ${titleCase(node.resourceType)}.`;
|
|
4627
4345
|
}
|
|
@@ -4710,9 +4428,6 @@ function buildNodeState(graph, node, nodesById) {
|
|
|
4710
4428
|
if (node.featureId) {
|
|
4711
4429
|
metadata.push({ label: "Feature ID", value: node.featureId });
|
|
4712
4430
|
}
|
|
4713
|
-
if (node.surfaceType) {
|
|
4714
|
-
metadata.push({ label: "Surface Type", value: titleCase(node.surfaceType) });
|
|
4715
|
-
}
|
|
4716
4431
|
if (node.resourceType) {
|
|
4717
4432
|
metadata.push({ label: "Resource Type", value: titleCase(node.resourceType) });
|
|
4718
4433
|
}
|
|
@@ -5350,20 +5065,20 @@ function getNodeStatus(node, commandViewData) {
|
|
|
5350
5065
|
}
|
|
5351
5066
|
return "status" in node && typeof node.status === "string" ? node.status : void 0;
|
|
5352
5067
|
}
|
|
5353
|
-
function
|
|
5068
|
+
function getExplicitNodeFacets(node, commandViewData) {
|
|
5354
5069
|
const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
|
|
5355
|
-
if (commandViewNode
|
|
5356
|
-
return
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5070
|
+
if (commandViewNode) {
|
|
5071
|
+
return [
|
|
5072
|
+
...commandViewNode.category ? [`category:${commandViewNode.category}`] : [],
|
|
5073
|
+
...commandViewNode.links?.map((link) => link.nodeId) ?? []
|
|
5074
|
+
];
|
|
5360
5075
|
}
|
|
5361
|
-
return
|
|
5076
|
+
return [];
|
|
5362
5077
|
}
|
|
5363
|
-
function
|
|
5364
|
-
const
|
|
5365
|
-
if (
|
|
5366
|
-
return
|
|
5078
|
+
function getNodeFacets(graph, node, commandViewData) {
|
|
5079
|
+
const explicitFacets = getExplicitNodeFacets(node, commandViewData);
|
|
5080
|
+
if (explicitFacets.length > 0) {
|
|
5081
|
+
return explicitFacets;
|
|
5367
5082
|
}
|
|
5368
5083
|
if (node.kind === "feature") {
|
|
5369
5084
|
return node.sourceId ? [node.sourceId] : [];
|
|
@@ -5371,24 +5086,24 @@ function getNodeDomains(graph, node, commandViewData) {
|
|
|
5371
5086
|
if (node.kind !== "resource") {
|
|
5372
5087
|
return [];
|
|
5373
5088
|
}
|
|
5374
|
-
const
|
|
5089
|
+
const facetIds = /* @__PURE__ */ new Set();
|
|
5375
5090
|
for (const edge of graph.edges) {
|
|
5376
5091
|
if (edge.sourceId !== node.id) {
|
|
5377
5092
|
continue;
|
|
5378
5093
|
}
|
|
5379
5094
|
const targetNode = graph.nodes.find((candidate) => candidate.id === edge.targetId);
|
|
5380
5095
|
if (targetNode?.kind === "feature" && targetNode.sourceId) {
|
|
5381
|
-
|
|
5096
|
+
facetIds.add(targetNode.id);
|
|
5382
5097
|
}
|
|
5383
5098
|
}
|
|
5384
|
-
return [...
|
|
5099
|
+
return [...facetIds];
|
|
5385
5100
|
}
|
|
5386
5101
|
function matchesOrganizationGraphNodeSearch(node, search) {
|
|
5387
5102
|
const query = normalizeOrganizationGraphSearch(search);
|
|
5388
5103
|
if (!query) return true;
|
|
5389
5104
|
const nodeStatus = getNodeStatus(node);
|
|
5390
|
-
const
|
|
5391
|
-
return includesQuery(node.id, query) || includesQuery(node.label, query) || includesQuery(node.description, query) || includesQuery(node.sourceId, query) || includesQuery(node.featureId, query) || includesQuery(node.
|
|
5105
|
+
const nodeFacets = getExplicitNodeFacets(node);
|
|
5106
|
+
return includesQuery(node.id, query) || includesQuery(node.label, query) || includesQuery(node.description, query) || includesQuery(node.sourceId, query) || includesQuery(node.featureId, query) || includesQuery(node.resourceType, query) || includesQuery(nodeStatus, query) || nodeFacets.some((facet) => includesQuery(facet, query)) || includesQuery(node.kind, query);
|
|
5392
5107
|
}
|
|
5393
5108
|
function matchesOrganizationGraphEdgeSearch(edge, graph, search) {
|
|
5394
5109
|
const query = normalizeOrganizationGraphSearch(search);
|
|
@@ -5410,11 +5125,11 @@ function matchesDomainFilters(graph, node, domainFilters, commandViewData) {
|
|
|
5410
5125
|
}
|
|
5411
5126
|
const includedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "include").map(([domainId]) => domainId);
|
|
5412
5127
|
const excludedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "exclude").map(([domainId]) => domainId);
|
|
5413
|
-
const
|
|
5414
|
-
if (excludedDomains.length > 0 &&
|
|
5128
|
+
const nodeFacets = getNodeFacets(graph, node, commandViewData);
|
|
5129
|
+
if (excludedDomains.length > 0 && nodeFacets.some((domainId) => excludedDomains.includes(domainId))) {
|
|
5415
5130
|
return false;
|
|
5416
5131
|
}
|
|
5417
|
-
if (includedDomains.length > 0 && !
|
|
5132
|
+
if (includedDomains.length > 0 && !nodeFacets.some((domainId) => includedDomains.includes(domainId))) {
|
|
5418
5133
|
return false;
|
|
5419
5134
|
}
|
|
5420
5135
|
return true;
|
|
@@ -5499,6 +5214,83 @@ function filterOrganizationGraph(graph, filters, options) {
|
|
|
5499
5214
|
edges: visibleEdges
|
|
5500
5215
|
};
|
|
5501
5216
|
}
|
|
5217
|
+
function getCommandViewResourceCategory(node, commandViewData) {
|
|
5218
|
+
return getCommandViewNodeForGraphNode(node, commandViewData)?.category ?? null;
|
|
5219
|
+
}
|
|
5220
|
+
function getConnectedHiddenResourceIds(graph, nodeId2, hiddenIds) {
|
|
5221
|
+
if (!nodeId2) {
|
|
5222
|
+
return /* @__PURE__ */ new Set();
|
|
5223
|
+
}
|
|
5224
|
+
const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
5225
|
+
const connectedIds = /* @__PURE__ */ new Set();
|
|
5226
|
+
for (const edge of graph.edges) {
|
|
5227
|
+
const neighborId = edge.sourceId === nodeId2 ? edge.targetId : edge.targetId === nodeId2 ? edge.sourceId : null;
|
|
5228
|
+
if (!neighborId || !hiddenIds.has(neighborId)) {
|
|
5229
|
+
continue;
|
|
5230
|
+
}
|
|
5231
|
+
if (nodesById.get(neighborId)?.kind === "resource") {
|
|
5232
|
+
connectedIds.add(neighborId);
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
return connectedIds;
|
|
5236
|
+
}
|
|
5237
|
+
function getCommandViewVisibilityProjection({
|
|
5238
|
+
graph,
|
|
5239
|
+
commandViewData,
|
|
5240
|
+
resourcesHidden,
|
|
5241
|
+
diagnosticsHidden,
|
|
5242
|
+
diagnosticCategories,
|
|
5243
|
+
revealedIds = /* @__PURE__ */ new Set(),
|
|
5244
|
+
mode
|
|
5245
|
+
}) {
|
|
5246
|
+
const hiddenIds = /* @__PURE__ */ new Set();
|
|
5247
|
+
const hiddenEdgeIds = /* @__PURE__ */ new Set();
|
|
5248
|
+
const diagnosticCategorySet = new Set(diagnosticCategories);
|
|
5249
|
+
let totalResourceCount = 0;
|
|
5250
|
+
let hiddenDiagnosticResourceCount = 0;
|
|
5251
|
+
if (mode === "trace" || mode === "impact") {
|
|
5252
|
+
const resourceCount = graph.nodes.filter((node) => node.kind === "resource").length;
|
|
5253
|
+
return {
|
|
5254
|
+
hiddenIds,
|
|
5255
|
+
hiddenEdgeIds,
|
|
5256
|
+
totalResourceCount: resourceCount,
|
|
5257
|
+
visibleResourceCount: resourceCount,
|
|
5258
|
+
hiddenResourceCount: 0,
|
|
5259
|
+
hiddenDiagnosticResourceCount: 0
|
|
5260
|
+
};
|
|
5261
|
+
}
|
|
5262
|
+
for (const node of graph.nodes) {
|
|
5263
|
+
if (node.kind !== "resource") {
|
|
5264
|
+
continue;
|
|
5265
|
+
}
|
|
5266
|
+
totalResourceCount += 1;
|
|
5267
|
+
const category = getCommandViewResourceCategory(node, commandViewData);
|
|
5268
|
+
const isDiagnostic = Boolean(category && diagnosticCategorySet.has(category));
|
|
5269
|
+
if (isDiagnostic && diagnosticsHidden) {
|
|
5270
|
+
hiddenDiagnosticResourceCount += 1;
|
|
5271
|
+
}
|
|
5272
|
+
if (revealedIds.has(node.id)) {
|
|
5273
|
+
continue;
|
|
5274
|
+
}
|
|
5275
|
+
if (resourcesHidden || diagnosticsHidden && isDiagnostic) {
|
|
5276
|
+
hiddenIds.add(node.id);
|
|
5277
|
+
}
|
|
5278
|
+
}
|
|
5279
|
+
for (const edge of graph.edges) {
|
|
5280
|
+
if (hiddenIds.has(edge.sourceId) || hiddenIds.has(edge.targetId)) {
|
|
5281
|
+
hiddenEdgeIds.add(edge.id);
|
|
5282
|
+
}
|
|
5283
|
+
}
|
|
5284
|
+
const hiddenResourceCount = hiddenIds.size;
|
|
5285
|
+
return {
|
|
5286
|
+
hiddenIds,
|
|
5287
|
+
hiddenEdgeIds,
|
|
5288
|
+
totalResourceCount,
|
|
5289
|
+
visibleResourceCount: totalResourceCount - hiddenResourceCount,
|
|
5290
|
+
hiddenResourceCount,
|
|
5291
|
+
hiddenDiagnosticResourceCount
|
|
5292
|
+
};
|
|
5293
|
+
}
|
|
5502
5294
|
function isOrganizationGraphFilterPristine(filters) {
|
|
5503
5295
|
return normalizeOrganizationGraphSearch(filters.search) === "" && filters.nodeKinds.length === 0 && filters.topologyPresence === DEFAULT_ORGANIZATION_GRAPH_FILTERS.topologyPresence && filters.environmentStatus === DEFAULT_ORGANIZATION_GRAPH_FILTERS.environmentStatus && filters.resourceTypes.length === 0 && filters.showIntegrations === DEFAULT_ORGANIZATION_GRAPH_FILTERS.showIntegrations && !hasActiveDomainFilters(filters.domainFilters);
|
|
5504
5296
|
}
|
|
@@ -5706,7 +5498,14 @@ function useOrganizationGraphFilters(initialFilters) {
|
|
|
5706
5498
|
}
|
|
5707
5499
|
|
|
5708
5500
|
// src/features/operations/organization-graph/lenses.ts
|
|
5709
|
-
var COMMAND_VIEW_NODE_KINDS = [
|
|
5501
|
+
var COMMAND_VIEW_NODE_KINDS = [
|
|
5502
|
+
"organization",
|
|
5503
|
+
"feature",
|
|
5504
|
+
"surface",
|
|
5505
|
+
"entity",
|
|
5506
|
+
"capability",
|
|
5507
|
+
"resource"
|
|
5508
|
+
];
|
|
5710
5509
|
function getOrganizationGraphLensConfig(lens) {
|
|
5711
5510
|
if (lens === "command-view") {
|
|
5712
5511
|
return {
|
|
@@ -5715,9 +5514,9 @@ function getOrganizationGraphLensConfig(lens) {
|
|
|
5715
5514
|
initialMode: "map",
|
|
5716
5515
|
initialFilters: {
|
|
5717
5516
|
nodeKinds: COMMAND_VIEW_NODE_KINDS,
|
|
5718
|
-
topologyPresence: "
|
|
5517
|
+
topologyPresence: "all"
|
|
5719
5518
|
},
|
|
5720
|
-
filterSummary: "Command View lens
|
|
5519
|
+
filterSummary: "Command View lens keeps the organization structure visible while resource visibility is controlled progressively."
|
|
5721
5520
|
};
|
|
5722
5521
|
}
|
|
5723
5522
|
return {
|
|
@@ -5806,8 +5605,11 @@ function buildResourceSelectionSummary(node, stats) {
|
|
|
5806
5605
|
{ label: "Version", value: node.version },
|
|
5807
5606
|
{ label: "Origin", value: node.origin ? node.origin : "local" }
|
|
5808
5607
|
];
|
|
5809
|
-
if (node.
|
|
5810
|
-
metadata.push({ label: "
|
|
5608
|
+
if (node.category) {
|
|
5609
|
+
metadata.push({ label: "Category", value: node.category });
|
|
5610
|
+
}
|
|
5611
|
+
if (node.links?.length) {
|
|
5612
|
+
metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
|
|
5811
5613
|
}
|
|
5812
5614
|
if (node.type === "agent") {
|
|
5813
5615
|
metadata.push({ label: "Model", value: `${node.modelProvider}/${node.modelId}` });
|
|
@@ -5847,8 +5649,11 @@ function buildHumanSelectionSummary(node, stats) {
|
|
|
5847
5649
|
{ label: "Version", value: node.version },
|
|
5848
5650
|
{ label: "Origin", value: node.origin ? node.origin : "local" }
|
|
5849
5651
|
];
|
|
5850
|
-
if (node.
|
|
5851
|
-
metadata.push({ label: "
|
|
5652
|
+
if (node.category) {
|
|
5653
|
+
metadata.push({ label: "Category", value: node.category });
|
|
5654
|
+
}
|
|
5655
|
+
if (node.links?.length) {
|
|
5656
|
+
metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
|
|
5852
5657
|
}
|
|
5853
5658
|
return {
|
|
5854
5659
|
title: "Approval Queue Summary",
|
|
@@ -6030,94 +5835,280 @@ function buildCommandViewDrillDownSections({
|
|
|
6030
5835
|
}
|
|
6031
5836
|
var cellStyle = {
|
|
6032
5837
|
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
6033
|
-
borderRight: "1px solid var(--color-border)",
|
|
6034
5838
|
display: "flex",
|
|
6035
5839
|
alignItems: "center",
|
|
6036
5840
|
gap: "var(--mantine-spacing-sm)",
|
|
6037
5841
|
minWidth: 0
|
|
6038
5842
|
};
|
|
6039
|
-
var lastCellStyle = {
|
|
6040
|
-
...cellStyle,
|
|
6041
|
-
borderRight: "none"
|
|
6042
|
-
};
|
|
6043
5843
|
function CommandViewHealthStrip({
|
|
6044
5844
|
overview,
|
|
6045
5845
|
hotspots,
|
|
6046
5846
|
visibleResources,
|
|
5847
|
+
hiddenResources = 0,
|
|
5848
|
+
resourcesHidden,
|
|
6047
5849
|
selectedLabel,
|
|
6048
5850
|
onFocusHotspot,
|
|
5851
|
+
onResourcesHiddenChange,
|
|
6049
5852
|
onResetFocus
|
|
6050
5853
|
}) {
|
|
6051
|
-
return /* @__PURE__ */ jsxs(
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
5854
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
5855
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5856
|
+
/* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5857
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
|
|
5858
|
+
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
5859
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
|
|
5860
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
|
|
5861
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
|
|
5862
|
+
] }),
|
|
5863
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
|
|
5864
|
+
] }),
|
|
5865
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5866
|
+
/* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5867
|
+
hotspots.length > 0 ? /* @__PURE__ */ jsx(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0, overflow: "hidden" }, children: hotspots.map((hotspot) => /* @__PURE__ */ jsx(Group, { gap: 4, wrap: "nowrap", children: /* @__PURE__ */ jsx(
|
|
5868
|
+
Badge,
|
|
5869
|
+
{
|
|
5870
|
+
variant: "light",
|
|
5871
|
+
color: "red",
|
|
5872
|
+
size: "xs",
|
|
5873
|
+
style: { cursor: "pointer", flexShrink: 0 },
|
|
5874
|
+
onClick: () => onFocusHotspot(hotspot.resourceId),
|
|
5875
|
+
children: hotspot.label
|
|
5876
|
+
}
|
|
5877
|
+
) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
|
|
5878
|
+
] }),
|
|
5879
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5880
|
+
/* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5881
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
|
|
5882
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
|
|
5883
|
+
"pending / ",
|
|
5884
|
+
overview?.activeHumanCheckpoints ?? 0,
|
|
5885
|
+
" queues"
|
|
5886
|
+
] })
|
|
5887
|
+
] }),
|
|
5888
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5889
|
+
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5890
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
|
|
5891
|
+
/* @__PURE__ */ jsx(
|
|
5892
|
+
Button,
|
|
5893
|
+
{
|
|
5894
|
+
size: "compact-xs",
|
|
5895
|
+
variant: resourcesHidden ? "light" : "subtle",
|
|
5896
|
+
onClick: () => onResourcesHiddenChange(!resourcesHidden),
|
|
5897
|
+
style: { flexShrink: 0 },
|
|
5898
|
+
children: resourcesHidden ? "Show resources" : "Hide resources"
|
|
5899
|
+
}
|
|
5900
|
+
),
|
|
5901
|
+
/* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
|
|
5902
|
+
] })
|
|
5903
|
+
] });
|
|
5904
|
+
}
|
|
5905
|
+
var FILTER_STATE_ICONS2 = {
|
|
5906
|
+
neutral: IconCircleDashed,
|
|
5907
|
+
include: IconCircleCheck,
|
|
5908
|
+
exclude: IconCircleX
|
|
5909
|
+
};
|
|
5910
|
+
var FILTER_STATE_COLORS2 = {
|
|
5911
|
+
neutral: "var(--color-text-dimmed)",
|
|
5912
|
+
include: "var(--mantine-color-green-6)",
|
|
5913
|
+
exclude: "var(--mantine-color-red-6)"
|
|
5914
|
+
};
|
|
5915
|
+
var FILTER_STATE_LABELS2 = {
|
|
5916
|
+
neutral: "Not filtered",
|
|
5917
|
+
include: "Include only",
|
|
5918
|
+
exclude: "Exclude"
|
|
5919
|
+
};
|
|
5920
|
+
function getCommandViewResources(commandViewData) {
|
|
5921
|
+
if (!commandViewData) {
|
|
5922
|
+
return [];
|
|
5923
|
+
}
|
|
5924
|
+
return [
|
|
5925
|
+
...commandViewData.agents,
|
|
5926
|
+
...commandViewData.workflows,
|
|
5927
|
+
...commandViewData.triggers,
|
|
5928
|
+
...commandViewData.integrations,
|
|
5929
|
+
...commandViewData.externalResources,
|
|
5930
|
+
...commandViewData.humanCheckpoints
|
|
5931
|
+
];
|
|
5932
|
+
}
|
|
5933
|
+
function nextDomainFilterState(current) {
|
|
5934
|
+
if (current === "neutral") return "include";
|
|
5935
|
+
if (current === "include") return "exclude";
|
|
5936
|
+
return "neutral";
|
|
5937
|
+
}
|
|
5938
|
+
function FilterPanel({
|
|
5939
|
+
filters,
|
|
5940
|
+
onChangeFilters,
|
|
5941
|
+
resetValue,
|
|
5942
|
+
disabled = false,
|
|
5943
|
+
commandViewData,
|
|
5944
|
+
lens,
|
|
5945
|
+
resourcesHidden,
|
|
5946
|
+
diagnosticsHidden,
|
|
5947
|
+
onResourcesHiddenChange,
|
|
5948
|
+
onDiagnosticsHiddenChange,
|
|
5949
|
+
onRevealResources,
|
|
5950
|
+
onResetFilters,
|
|
5951
|
+
visibilityCounts,
|
|
5952
|
+
graph,
|
|
5953
|
+
baseGraph,
|
|
5954
|
+
layout = "grid"
|
|
5955
|
+
}) {
|
|
5956
|
+
const resourceFacets = collectResourceFilterFacets(getCommandViewResources(commandViewData));
|
|
5957
|
+
const Section = ({ children }) => layout === "stack" ? /* @__PURE__ */ jsx(
|
|
5958
|
+
Stack,
|
|
5959
|
+
{
|
|
5960
|
+
gap: "sm",
|
|
5961
|
+
pb: "sm",
|
|
5962
|
+
style: {
|
|
5963
|
+
borderBottom: "1px solid var(--color-border)"
|
|
5964
|
+
},
|
|
5965
|
+
children
|
|
5966
|
+
}
|
|
5967
|
+
) : /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", style: { background: "var(--color-surface)" }, children });
|
|
5968
|
+
const updateDomainFilter = (domainId) => {
|
|
5969
|
+
const current = filters.domainFilters[domainId] ?? "neutral";
|
|
5970
|
+
onChangeFilters({
|
|
5971
|
+
...filters,
|
|
5972
|
+
domainFilters: {
|
|
5973
|
+
...filters.domainFilters,
|
|
5974
|
+
[domainId]: nextDomainFilterState(current)
|
|
5975
|
+
}
|
|
5976
|
+
});
|
|
5977
|
+
};
|
|
5978
|
+
const handleResourceVisibilityAction = () => {
|
|
5979
|
+
if (resourcesHidden) {
|
|
5980
|
+
onRevealResources();
|
|
5981
|
+
return;
|
|
5982
|
+
}
|
|
5983
|
+
onResourcesHiddenChange(true);
|
|
5984
|
+
};
|
|
5985
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5986
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5987
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Filters" }),
|
|
5988
|
+
/* @__PURE__ */ jsx(
|
|
5989
|
+
OrganizationGraphFilterToolbar,
|
|
5990
|
+
{
|
|
5991
|
+
value: filters,
|
|
5992
|
+
onChange: onChangeFilters,
|
|
5993
|
+
disabled,
|
|
5994
|
+
resetValue
|
|
5995
|
+
}
|
|
5996
|
+
)
|
|
5997
|
+
] }) }),
|
|
5998
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5999
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
|
|
6000
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Visibility" }),
|
|
6001
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
6002
|
+
visibilityCounts.visibleResourceCount,
|
|
6003
|
+
"/",
|
|
6004
|
+
visibilityCounts.totalResourceCount,
|
|
6005
|
+
" resources"
|
|
6006
|
+
] })
|
|
6007
|
+
] }),
|
|
6008
|
+
lens === "command-view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6009
|
+
/* @__PURE__ */ jsx(
|
|
6010
|
+
Checkbox,
|
|
6011
|
+
{
|
|
6012
|
+
label: "Hide resource nodes",
|
|
6013
|
+
description: "Keep the organization structure readable and reveal resource nodes as needed.",
|
|
6014
|
+
checked: resourcesHidden,
|
|
6015
|
+
onChange: (event) => onResourcesHiddenChange(event.currentTarget.checked),
|
|
6016
|
+
disabled
|
|
6017
|
+
}
|
|
6018
|
+
),
|
|
6019
|
+
/* @__PURE__ */ jsx(
|
|
6020
|
+
Checkbox,
|
|
6021
|
+
{
|
|
6022
|
+
label: "Hide diagnostic and testing resources",
|
|
6023
|
+
description: "Diagnostics stay available through filters, trace, impact, and contextual reveal.",
|
|
6024
|
+
checked: diagnosticsHidden,
|
|
6025
|
+
onChange: (event) => onDiagnosticsHiddenChange(event.currentTarget.checked),
|
|
6026
|
+
disabled
|
|
6027
|
+
}
|
|
6028
|
+
),
|
|
6029
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
6030
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenResourceCount > 0 ? "yellow" : "green", children: [
|
|
6031
|
+
visibilityCounts.hiddenResourceCount,
|
|
6032
|
+
" hidden"
|
|
6033
|
+
] }),
|
|
6034
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenDiagnosticResourceCount > 0 ? "yellow" : "gray", children: [
|
|
6035
|
+
visibilityCounts.hiddenDiagnosticResourceCount,
|
|
6036
|
+
" diagnostic/testing"
|
|
6037
|
+
] })
|
|
6038
|
+
] }),
|
|
6039
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
6040
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: handleResourceVisibilityAction, disabled, children: resourcesHidden ? "Reveal resources" : "Hide resources" }),
|
|
6041
|
+
/* @__PURE__ */ jsx(
|
|
6042
|
+
Button,
|
|
6043
|
+
{
|
|
6044
|
+
size: "xs",
|
|
6045
|
+
variant: "subtle",
|
|
6046
|
+
leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
|
|
6047
|
+
onClick: onResetFilters,
|
|
6048
|
+
disabled,
|
|
6049
|
+
children: "Reset filters"
|
|
6050
|
+
}
|
|
6051
|
+
)
|
|
6052
|
+
] })
|
|
6053
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Visibility controls are available in the Command View lens." })
|
|
6054
|
+
] }) }),
|
|
6055
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6056
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Resource Facets" }),
|
|
6057
|
+
resourceFacets.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: resourceFacets.map((facet) => {
|
|
6058
|
+
const filterState = filters.domainFilters[facet.id] ?? "neutral";
|
|
6059
|
+
const StateIcon = FILTER_STATE_ICONS2[filterState];
|
|
6060
|
+
return /* @__PURE__ */ jsx(
|
|
6061
|
+
UnstyledButton,
|
|
6062
|
+
{
|
|
6063
|
+
title: FILTER_STATE_LABELS2[filterState],
|
|
6064
|
+
onClick: () => updateDomainFilter(facet.id),
|
|
6065
|
+
disabled,
|
|
6066
|
+
style: {
|
|
6067
|
+
border: "1px solid var(--color-border)",
|
|
6068
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
6069
|
+
padding: "6px 8px"
|
|
6070
|
+
},
|
|
6071
|
+
children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
|
|
6072
|
+
/* @__PURE__ */ jsx(StateIcon, { size: 16, style: { color: FILTER_STATE_COLORS2[filterState], flexShrink: 0 } }),
|
|
6073
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, c: filterState === "neutral" ? "dimmed" : void 0, children: facet.label })
|
|
6074
|
+
] })
|
|
6075
|
+
},
|
|
6076
|
+
facet.id
|
|
6077
|
+
);
|
|
6078
|
+
}) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No resource facets are available for the current topology." }),
|
|
6079
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
6080
|
+
"Showing ",
|
|
6081
|
+
graph?.nodes.length ?? 0,
|
|
6082
|
+
" nodes and ",
|
|
6083
|
+
graph?.edges.length ?? 0,
|
|
6084
|
+
" edges from",
|
|
6085
|
+
" ",
|
|
6086
|
+
baseGraph?.nodes.length ?? 0,
|
|
6087
|
+
" total nodes."
|
|
6088
|
+
] })
|
|
6089
|
+
] }) })
|
|
6090
|
+
] });
|
|
6091
|
+
if (layout === "stack") {
|
|
6092
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: content });
|
|
6093
|
+
}
|
|
6094
|
+
return /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, lg: 3 }, spacing: "md", children: content });
|
|
6095
|
+
}
|
|
6096
|
+
|
|
6097
|
+
// src/features/operations/organization-graph/commandViewGraphHealth.ts
|
|
6098
|
+
function toResourceHealth(node, stats) {
|
|
6099
|
+
const resourceId = node.sourceId ?? node.id;
|
|
6100
|
+
if (node.resourceType === "human_checkpoint") {
|
|
6101
|
+
const checkpointStats = stats.humanCheckpoints[resourceId];
|
|
6102
|
+
if (!checkpointStats) {
|
|
6103
|
+
return {
|
|
6104
|
+
nodeId: node.id,
|
|
6105
|
+
resourceId,
|
|
6106
|
+
label: node.label,
|
|
6107
|
+
resourceType: node.resourceType,
|
|
6108
|
+
healthLevel: "inactive",
|
|
6109
|
+
summaryLabel: "No queue activity",
|
|
6110
|
+
detailLabel: "No approvals in range",
|
|
6111
|
+
successRate: null,
|
|
6121
6112
|
totalRuns: 0,
|
|
6122
6113
|
successCount: 0,
|
|
6123
6114
|
failureCount: 0,
|
|
@@ -6594,6 +6585,8 @@ var EMPTY_TRACE_SELECTION = {
|
|
|
6594
6585
|
sourceId: null,
|
|
6595
6586
|
targetId: null
|
|
6596
6587
|
};
|
|
6588
|
+
var EMPTY_GRAPH_HIDDEN_IDS = /* @__PURE__ */ new Set();
|
|
6589
|
+
var EMPTY_GRAPH_HIDDEN_EDGE_IDS = /* @__PURE__ */ new Set();
|
|
6597
6590
|
var FALLBACK_GRAPH_THEME = {
|
|
6598
6591
|
primary: "#4a6e8e",
|
|
6599
6592
|
background: "#030507",
|
|
@@ -6606,6 +6599,12 @@ var FALLBACK_GRAPH_THEME = {
|
|
|
6606
6599
|
warning: "#ffb74d",
|
|
6607
6600
|
error: "#ff5252"
|
|
6608
6601
|
};
|
|
6602
|
+
function truncateGraphLabel(value, maxLength) {
|
|
6603
|
+
if (value.length <= maxLength) {
|
|
6604
|
+
return value;
|
|
6605
|
+
}
|
|
6606
|
+
return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
6607
|
+
}
|
|
6609
6608
|
function parseColor(input) {
|
|
6610
6609
|
const value = input.trim();
|
|
6611
6610
|
if (value.startsWith("#")) {
|
|
@@ -6737,12 +6736,12 @@ function getEdgeColor(edge, tokens) {
|
|
|
6737
6736
|
}
|
|
6738
6737
|
function getNodeSize(kind) {
|
|
6739
6738
|
if (kind === "organization") {
|
|
6740
|
-
return { width:
|
|
6739
|
+
return { width: 230, height: 88 };
|
|
6741
6740
|
}
|
|
6742
6741
|
if (kind === "resource") {
|
|
6743
|
-
return { width:
|
|
6742
|
+
return { width: 154, height: 54 };
|
|
6744
6743
|
}
|
|
6745
|
-
return { width:
|
|
6744
|
+
return { width: 174, height: 66 };
|
|
6746
6745
|
}
|
|
6747
6746
|
function getNodeScore(node, graph) {
|
|
6748
6747
|
const relationshipCount = graph.edges.filter((edge) => edge.sourceId === node.id || edge.targetId === node.id).length;
|
|
@@ -6761,8 +6760,13 @@ function getCommandViewRingColor(level, tokens) {
|
|
|
6761
6760
|
return mixColors(tokens.textDimmed, tokens.border, 0.6);
|
|
6762
6761
|
}
|
|
6763
6762
|
}
|
|
6764
|
-
function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId) {
|
|
6763
|
+
function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId, visualizationMode, selectedElement) {
|
|
6765
6764
|
const nodeThemeByKind = getNodeThemeByKind(tokens);
|
|
6765
|
+
const presetPositions = getCommandViewGraphPositions({
|
|
6766
|
+
graph,
|
|
6767
|
+
visualizationMode,
|
|
6768
|
+
selectedNodeId: selectedElement?.type === "node" ? selectedElement.id : null
|
|
6769
|
+
});
|
|
6766
6770
|
return [
|
|
6767
6771
|
...graph.nodes.map((node) => {
|
|
6768
6772
|
const size = getNodeSize(node.kind);
|
|
@@ -6770,19 +6774,22 @@ function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId)
|
|
|
6770
6774
|
const health = commandViewHealthByNodeId?.get(node.id) ?? null;
|
|
6771
6775
|
const fillColor = health && node.kind === "resource" ? mixColors(tokens.surfaceHover, tokens.background, 0.76) : theme.background;
|
|
6772
6776
|
const borderColor = health ? getCommandViewRingColor(health.healthLevel, tokens) : theme.border;
|
|
6773
|
-
const
|
|
6774
|
-
|
|
6777
|
+
const maxLabelLength = node.kind === "resource" ? 22 : 30;
|
|
6778
|
+
const label = truncateGraphLabel(node.label, maxLabelLength);
|
|
6779
|
+
const displayLabel = health ? `${label}
|
|
6780
|
+
${health.summaryLabel}` : label;
|
|
6775
6781
|
return {
|
|
6776
6782
|
data: {
|
|
6777
6783
|
...node,
|
|
6778
6784
|
width: size.width,
|
|
6779
6785
|
height: size.height,
|
|
6780
6786
|
score: getNodeScore(node, graph),
|
|
6781
|
-
label,
|
|
6787
|
+
label: displayLabel,
|
|
6782
6788
|
fillColor,
|
|
6783
6789
|
borderColor,
|
|
6784
6790
|
textColor: health ? tokens.text : theme.color
|
|
6785
|
-
}
|
|
6791
|
+
},
|
|
6792
|
+
position: presetPositions.get(node.id)
|
|
6786
6793
|
};
|
|
6787
6794
|
}),
|
|
6788
6795
|
...graph.edges.map((edge) => ({
|
|
@@ -6808,9 +6815,9 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
6808
6815
|
name: "concentric",
|
|
6809
6816
|
fit: true,
|
|
6810
6817
|
animate: true,
|
|
6811
|
-
animationDuration:
|
|
6812
|
-
padding:
|
|
6813
|
-
spacingFactor: 1
|
|
6818
|
+
animationDuration: 220,
|
|
6819
|
+
padding: 48,
|
|
6820
|
+
spacingFactor: 1,
|
|
6814
6821
|
concentric: (node) => {
|
|
6815
6822
|
if (node.id() === impactRootId) {
|
|
6816
6823
|
return 20;
|
|
@@ -6825,24 +6832,19 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
6825
6832
|
name: "breadthfirst",
|
|
6826
6833
|
fit: true,
|
|
6827
6834
|
animate: true,
|
|
6828
|
-
animationDuration:
|
|
6835
|
+
animationDuration: 220,
|
|
6829
6836
|
directed: true,
|
|
6830
6837
|
circle: false,
|
|
6831
|
-
spacingFactor: 1.
|
|
6832
|
-
padding:
|
|
6838
|
+
spacingFactor: 1.08,
|
|
6839
|
+
padding: 48,
|
|
6833
6840
|
roots
|
|
6834
6841
|
};
|
|
6835
6842
|
}
|
|
6836
6843
|
return {
|
|
6837
|
-
name: "
|
|
6844
|
+
name: "preset",
|
|
6838
6845
|
fit: true,
|
|
6839
|
-
animate:
|
|
6840
|
-
|
|
6841
|
-
padding: 56,
|
|
6842
|
-
nodeRepulsion: 72e4,
|
|
6843
|
-
idealEdgeLength: 160,
|
|
6844
|
-
edgeElasticity: 120,
|
|
6845
|
-
gravity: 0.3
|
|
6846
|
+
animate: false,
|
|
6847
|
+
padding: 48
|
|
6846
6848
|
};
|
|
6847
6849
|
}
|
|
6848
6850
|
function createCytoscapeStyle(tokens) {
|
|
@@ -6862,13 +6864,13 @@ function createCytoscapeStyle(tokens) {
|
|
|
6862
6864
|
"border-style": "solid",
|
|
6863
6865
|
"border-color": "data(borderColor)",
|
|
6864
6866
|
color: "data(textColor)",
|
|
6865
|
-
"font-size":
|
|
6867
|
+
"font-size": 10,
|
|
6866
6868
|
"font-weight": 700,
|
|
6867
6869
|
"text-wrap": "wrap",
|
|
6868
|
-
"text-max-width": "
|
|
6870
|
+
"text-max-width": "120px",
|
|
6869
6871
|
"text-valign": "center",
|
|
6870
6872
|
"text-halign": "center",
|
|
6871
|
-
padding: "
|
|
6873
|
+
padding: "10px",
|
|
6872
6874
|
"overlay-opacity": 0,
|
|
6873
6875
|
"text-outline-width": 0
|
|
6874
6876
|
}
|
|
@@ -6878,14 +6880,25 @@ function createCytoscapeStyle(tokens) {
|
|
|
6878
6880
|
style: {
|
|
6879
6881
|
shape: "cut-rectangle",
|
|
6880
6882
|
"border-width": 3,
|
|
6881
|
-
"font-size":
|
|
6883
|
+
"font-size": 13
|
|
6884
|
+
}
|
|
6885
|
+
},
|
|
6886
|
+
{
|
|
6887
|
+
selector: 'node[kind = "resource"]',
|
|
6888
|
+
style: {
|
|
6889
|
+
"border-width": 1.5,
|
|
6890
|
+
"font-size": 8,
|
|
6891
|
+
"font-weight": 650,
|
|
6892
|
+
"text-max-width": "104px",
|
|
6893
|
+
"background-opacity": 0.82,
|
|
6894
|
+
"min-zoomed-font-size": 7
|
|
6882
6895
|
}
|
|
6883
6896
|
},
|
|
6884
6897
|
{
|
|
6885
6898
|
selector: "edge",
|
|
6886
6899
|
style: {
|
|
6887
|
-
width:
|
|
6888
|
-
label: "
|
|
6900
|
+
width: 1.25,
|
|
6901
|
+
label: "",
|
|
6889
6902
|
color: tokens.text,
|
|
6890
6903
|
"font-size": 10,
|
|
6891
6904
|
"font-weight": 700,
|
|
@@ -6900,20 +6913,26 @@ function createCytoscapeStyle(tokens) {
|
|
|
6900
6913
|
"text-border-opacity": 0,
|
|
6901
6914
|
"text-rotation": "autorotate",
|
|
6902
6915
|
"overlay-opacity": 0,
|
|
6903
|
-
"line-opacity": 0.
|
|
6916
|
+
"line-opacity": 0.38
|
|
6917
|
+
}
|
|
6918
|
+
},
|
|
6919
|
+
{
|
|
6920
|
+
selector: ".is-hidden",
|
|
6921
|
+
style: {
|
|
6922
|
+
display: "none"
|
|
6904
6923
|
}
|
|
6905
6924
|
},
|
|
6906
6925
|
{
|
|
6907
6926
|
selector: 'edge[relationshipType = "triggers"]',
|
|
6908
6927
|
style: {
|
|
6909
|
-
width:
|
|
6928
|
+
width: 1.9,
|
|
6910
6929
|
"line-style": "dashed"
|
|
6911
6930
|
}
|
|
6912
6931
|
},
|
|
6913
6932
|
{
|
|
6914
6933
|
selector: ".is-faded",
|
|
6915
6934
|
style: {
|
|
6916
|
-
opacity: 0.
|
|
6935
|
+
opacity: 0.1
|
|
6917
6936
|
}
|
|
6918
6937
|
},
|
|
6919
6938
|
{
|
|
@@ -6926,7 +6945,8 @@ function createCytoscapeStyle(tokens) {
|
|
|
6926
6945
|
selector: "edge.is-connected",
|
|
6927
6946
|
style: {
|
|
6928
6947
|
opacity: 1,
|
|
6929
|
-
width:
|
|
6948
|
+
width: 2.9,
|
|
6949
|
+
"line-opacity": 0.9
|
|
6930
6950
|
}
|
|
6931
6951
|
},
|
|
6932
6952
|
{
|
|
@@ -6934,7 +6954,8 @@ function createCytoscapeStyle(tokens) {
|
|
|
6934
6954
|
style: {
|
|
6935
6955
|
opacity: 1,
|
|
6936
6956
|
"border-color": selectedBorder,
|
|
6937
|
-
"border-width": 3
|
|
6957
|
+
"border-width": 3.5,
|
|
6958
|
+
"background-opacity": 1
|
|
6938
6959
|
}
|
|
6939
6960
|
},
|
|
6940
6961
|
{
|
|
@@ -6957,7 +6978,9 @@ function createCytoscapeStyle(tokens) {
|
|
|
6957
6978
|
selector: "edge.is-selected",
|
|
6958
6979
|
style: {
|
|
6959
6980
|
opacity: 1,
|
|
6960
|
-
width: 4.2
|
|
6981
|
+
width: 4.2,
|
|
6982
|
+
"line-opacity": 1,
|
|
6983
|
+
label: "data(label)"
|
|
6961
6984
|
}
|
|
6962
6985
|
},
|
|
6963
6986
|
{
|
|
@@ -6965,6 +6988,8 @@ function createCytoscapeStyle(tokens) {
|
|
|
6965
6988
|
style: {
|
|
6966
6989
|
opacity: 1,
|
|
6967
6990
|
width: 4.6,
|
|
6991
|
+
"line-opacity": 1,
|
|
6992
|
+
label: "data(label)",
|
|
6968
6993
|
"line-color": traceBorder,
|
|
6969
6994
|
"target-arrow-color": traceBorder,
|
|
6970
6995
|
"line-style": "solid"
|
|
@@ -6972,11 +6997,23 @@ function createCytoscapeStyle(tokens) {
|
|
|
6972
6997
|
}
|
|
6973
6998
|
];
|
|
6974
6999
|
}
|
|
6975
|
-
function syncGraphClasses(cy, selectedElement, traceResult) {
|
|
7000
|
+
function syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds) {
|
|
6976
7001
|
cy.batch(() => {
|
|
6977
7002
|
cy.elements().removeClass(
|
|
6978
|
-
"is-faded is-context is-selected is-connected is-trace-node is-trace-edge is-trace-endpoint"
|
|
7003
|
+
"is-hidden is-faded is-context is-selected is-connected is-trace-node is-trace-edge is-trace-endpoint"
|
|
6979
7004
|
);
|
|
7005
|
+
for (const nodeId2 of hiddenIds) {
|
|
7006
|
+
const node = cy.getElementById(nodeId2);
|
|
7007
|
+
if (!node.empty()) {
|
|
7008
|
+
node.addClass("is-hidden");
|
|
7009
|
+
}
|
|
7010
|
+
}
|
|
7011
|
+
for (const edgeId2 of hiddenEdgeIds) {
|
|
7012
|
+
const edge2 = cy.getElementById(edgeId2);
|
|
7013
|
+
if (!edge2.empty()) {
|
|
7014
|
+
edge2.addClass("is-hidden");
|
|
7015
|
+
}
|
|
7016
|
+
}
|
|
6980
7017
|
const hasTrace = Boolean(
|
|
6981
7018
|
traceResult && (traceResult.highlightNodeIds.length > 0 || traceResult.highlightEdgeIds.length > 0)
|
|
6982
7019
|
);
|
|
@@ -7030,24 +7067,56 @@ function syncGraphClasses(cy, selectedElement, traceResult) {
|
|
|
7030
7067
|
edge.connectedNodes().addClass("is-selected");
|
|
7031
7068
|
});
|
|
7032
7069
|
}
|
|
7070
|
+
function syncCytoscapeElements(cy, elements) {
|
|
7071
|
+
const nextIds = new Set(elements.map((element) => element.data.id));
|
|
7072
|
+
cy.batch(() => {
|
|
7073
|
+
cy.elements().forEach((element) => {
|
|
7074
|
+
if (!nextIds.has(element.id())) {
|
|
7075
|
+
element.remove();
|
|
7076
|
+
}
|
|
7077
|
+
});
|
|
7078
|
+
for (const element of elements) {
|
|
7079
|
+
const id = element.data.id;
|
|
7080
|
+
const existing = cy.getElementById(id);
|
|
7081
|
+
if (existing.empty()) {
|
|
7082
|
+
cy.add(element);
|
|
7083
|
+
continue;
|
|
7084
|
+
}
|
|
7085
|
+
existing.data(element.data);
|
|
7086
|
+
if ("position" in element && element.position && existing.isNode()) {
|
|
7087
|
+
existing.position(element.position);
|
|
7088
|
+
}
|
|
7089
|
+
}
|
|
7090
|
+
});
|
|
7091
|
+
}
|
|
7033
7092
|
function OrganizationGraphCanvas({
|
|
7034
7093
|
graph,
|
|
7035
7094
|
mode,
|
|
7095
|
+
visualizationMode,
|
|
7036
7096
|
selectedElement,
|
|
7037
7097
|
traceResult,
|
|
7098
|
+
hiddenIds,
|
|
7099
|
+
hiddenEdgeIds,
|
|
7038
7100
|
themeTokens,
|
|
7039
7101
|
commandViewHealthByNodeId,
|
|
7040
7102
|
focusRequest,
|
|
7103
|
+
toolbar,
|
|
7041
7104
|
onSelectElement
|
|
7042
7105
|
}) {
|
|
7043
7106
|
const containerRef = useRef(null);
|
|
7044
7107
|
const cytoscapeRef = useRef(null);
|
|
7045
7108
|
const previousModeRef = useRef(mode);
|
|
7109
|
+
const onSelectElementRef = useRef(onSelectElement);
|
|
7110
|
+
const lastSizeRef = useRef(null);
|
|
7111
|
+
const layoutSelectedElement = visualizationMode === "focus" ? selectedElement : null;
|
|
7046
7112
|
const elements = useMemo(
|
|
7047
|
-
() => toCytoscapeElementsWithHealth(graph, themeTokens, commandViewHealthByNodeId),
|
|
7048
|
-
[commandViewHealthByNodeId, graph, themeTokens]
|
|
7113
|
+
() => toCytoscapeElementsWithHealth(graph, themeTokens, commandViewHealthByNodeId, visualizationMode, layoutSelectedElement),
|
|
7114
|
+
[commandViewHealthByNodeId, graph, layoutSelectedElement, themeTokens, visualizationMode]
|
|
7049
7115
|
);
|
|
7050
7116
|
const cytoscapeStyle = useMemo(() => createCytoscapeStyle(themeTokens), [themeTokens]);
|
|
7117
|
+
useEffect(() => {
|
|
7118
|
+
onSelectElementRef.current = onSelectElement;
|
|
7119
|
+
}, [onSelectElement]);
|
|
7051
7120
|
useEffect(() => {
|
|
7052
7121
|
if (!containerRef.current) {
|
|
7053
7122
|
return;
|
|
@@ -7059,32 +7128,52 @@ function OrganizationGraphCanvas({
|
|
|
7059
7128
|
layout: getLayoutOptions(mode, null, traceResult),
|
|
7060
7129
|
minZoom: 0.22,
|
|
7061
7130
|
maxZoom: 1.6,
|
|
7062
|
-
wheelSensitivity:
|
|
7131
|
+
wheelSensitivity: 1.35
|
|
7063
7132
|
});
|
|
7064
7133
|
cytoscapeRef.current = cy;
|
|
7065
7134
|
cy.on("tap", "node", (event) => {
|
|
7066
|
-
|
|
7135
|
+
onSelectElementRef.current({ type: "node", id: event.target.id() });
|
|
7067
7136
|
});
|
|
7068
7137
|
cy.on("tap", "edge", (event) => {
|
|
7069
|
-
|
|
7138
|
+
onSelectElementRef.current({ type: "edge", id: event.target.id() });
|
|
7070
7139
|
});
|
|
7071
7140
|
cy.on("tap", (event) => {
|
|
7072
7141
|
if (event.target === cy) {
|
|
7073
|
-
|
|
7142
|
+
onSelectElementRef.current(null);
|
|
7074
7143
|
}
|
|
7075
7144
|
});
|
|
7076
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
7077
|
-
|
|
7078
|
-
|
|
7145
|
+
const resizeObserver = new ResizeObserver(([entry]) => {
|
|
7146
|
+
const { width, height } = entry.contentRect;
|
|
7147
|
+
const lastSize = lastSizeRef.current;
|
|
7148
|
+
if (lastSize && Math.abs(lastSize.width - width) < 1 && Math.abs(lastSize.height - height) < 1) {
|
|
7149
|
+
return;
|
|
7150
|
+
}
|
|
7151
|
+
lastSizeRef.current = { width, height };
|
|
7152
|
+
window.requestAnimationFrame(() => {
|
|
7153
|
+
if (cy.destroyed()) {
|
|
7154
|
+
return;
|
|
7155
|
+
}
|
|
7156
|
+
cy.resize();
|
|
7157
|
+
cy.fit(void 0, 44);
|
|
7158
|
+
});
|
|
7079
7159
|
});
|
|
7080
7160
|
resizeObserver.observe(containerRef.current);
|
|
7081
|
-
syncGraphClasses(cy, selectedElement, traceResult);
|
|
7161
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds);
|
|
7082
7162
|
return () => {
|
|
7083
7163
|
resizeObserver.disconnect();
|
|
7084
7164
|
cy.destroy();
|
|
7085
7165
|
cytoscapeRef.current = null;
|
|
7086
7166
|
};
|
|
7087
|
-
}, [cytoscapeStyle
|
|
7167
|
+
}, [cytoscapeStyle]);
|
|
7168
|
+
useEffect(() => {
|
|
7169
|
+
const cy = cytoscapeRef.current;
|
|
7170
|
+
if (!cy) {
|
|
7171
|
+
return;
|
|
7172
|
+
}
|
|
7173
|
+
syncCytoscapeElements(cy, elements);
|
|
7174
|
+
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
7175
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds);
|
|
7176
|
+
}, [elements]);
|
|
7088
7177
|
useEffect(() => {
|
|
7089
7178
|
const cy = cytoscapeRef.current;
|
|
7090
7179
|
if (!cy) {
|
|
@@ -7092,7 +7181,7 @@ function OrganizationGraphCanvas({
|
|
|
7092
7181
|
}
|
|
7093
7182
|
const modeChanged = previousModeRef.current !== mode;
|
|
7094
7183
|
previousModeRef.current = mode;
|
|
7095
|
-
if (!modeChanged && mode === "map"
|
|
7184
|
+
if (!modeChanged && mode === "map") {
|
|
7096
7185
|
return;
|
|
7097
7186
|
}
|
|
7098
7187
|
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
@@ -7102,8 +7191,27 @@ function OrganizationGraphCanvas({
|
|
|
7102
7191
|
if (!cy) {
|
|
7103
7192
|
return;
|
|
7104
7193
|
}
|
|
7105
|
-
syncGraphClasses(cy, selectedElement, traceResult);
|
|
7106
|
-
|
|
7194
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds);
|
|
7195
|
+
if (mode === "map" && selectedElement?.type === "node") {
|
|
7196
|
+
const node = cy.getElementById(selectedElement.id);
|
|
7197
|
+
if (!node.empty()) {
|
|
7198
|
+
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
7199
|
+
cy.stop();
|
|
7200
|
+
cy.animate(
|
|
7201
|
+
{
|
|
7202
|
+
fit: {
|
|
7203
|
+
eles: visibleNeighborhood.empty() ? node : visibleNeighborhood,
|
|
7204
|
+
padding: 72
|
|
7205
|
+
},
|
|
7206
|
+
duration: 220
|
|
7207
|
+
},
|
|
7208
|
+
{
|
|
7209
|
+
easing: "ease-out-cubic"
|
|
7210
|
+
}
|
|
7211
|
+
);
|
|
7212
|
+
}
|
|
7213
|
+
}
|
|
7214
|
+
}, [hiddenEdgeIds, hiddenIds, mode, selectedElement, traceResult]);
|
|
7107
7215
|
useEffect(() => {
|
|
7108
7216
|
const cy = cytoscapeRef.current;
|
|
7109
7217
|
if (!cy || !focusRequest) {
|
|
@@ -7113,13 +7221,15 @@ function OrganizationGraphCanvas({
|
|
|
7113
7221
|
if (node.empty()) {
|
|
7114
7222
|
return;
|
|
7115
7223
|
}
|
|
7224
|
+
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
7225
|
+
cy.stop();
|
|
7116
7226
|
cy.animate(
|
|
7117
7227
|
{
|
|
7118
7228
|
fit: {
|
|
7119
|
-
eles:
|
|
7120
|
-
padding:
|
|
7229
|
+
eles: visibleNeighborhood.empty() ? node : visibleNeighborhood,
|
|
7230
|
+
padding: 72
|
|
7121
7231
|
},
|
|
7122
|
-
duration:
|
|
7232
|
+
duration: 220
|
|
7123
7233
|
},
|
|
7124
7234
|
{
|
|
7125
7235
|
easing: "ease-out-cubic"
|
|
@@ -7140,25 +7250,39 @@ function OrganizationGraphCanvas({
|
|
|
7140
7250
|
},
|
|
7141
7251
|
children: [
|
|
7142
7252
|
/* @__PURE__ */ jsx(Box, { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
7143
|
-
/* @__PURE__ */
|
|
7144
|
-
|
|
7253
|
+
/* @__PURE__ */ jsxs(
|
|
7254
|
+
Group,
|
|
7145
7255
|
{
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
size: "lg",
|
|
7256
|
+
gap: "xs",
|
|
7257
|
+
wrap: "nowrap",
|
|
7149
7258
|
style: {
|
|
7150
7259
|
position: "absolute",
|
|
7151
7260
|
top: 12,
|
|
7152
7261
|
right: 12,
|
|
7153
7262
|
zIndex: 2,
|
|
7154
|
-
|
|
7155
|
-
backdropFilter: "var(--glass-blur)",
|
|
7156
|
-
color: "var(--color-text)"
|
|
7263
|
+
maxWidth: "calc(100% - 24px)"
|
|
7157
7264
|
},
|
|
7158
|
-
|
|
7159
|
-
|
|
7265
|
+
children: [
|
|
7266
|
+
toolbar,
|
|
7267
|
+
/* @__PURE__ */ jsx(Tooltip, { label: "Fit graph to view", children: /* @__PURE__ */ jsx(
|
|
7268
|
+
ActionIcon,
|
|
7269
|
+
{
|
|
7270
|
+
variant: "light",
|
|
7271
|
+
radius: "xl",
|
|
7272
|
+
size: "lg",
|
|
7273
|
+
style: {
|
|
7274
|
+
background: "var(--glass-background)",
|
|
7275
|
+
backdropFilter: "var(--glass-blur)",
|
|
7276
|
+
color: "var(--color-text)",
|
|
7277
|
+
flexShrink: 0
|
|
7278
|
+
},
|
|
7279
|
+
onClick: () => cytoscapeRef.current?.fit(void 0, 44),
|
|
7280
|
+
children: /* @__PURE__ */ jsx(IconArrowsMaximize, { size: 18 })
|
|
7281
|
+
}
|
|
7282
|
+
) })
|
|
7283
|
+
]
|
|
7160
7284
|
}
|
|
7161
|
-
)
|
|
7285
|
+
)
|
|
7162
7286
|
]
|
|
7163
7287
|
}
|
|
7164
7288
|
);
|
|
@@ -7166,6 +7290,38 @@ function OrganizationGraphCanvas({
|
|
|
7166
7290
|
function getGraphCountByKind(graph, kind) {
|
|
7167
7291
|
return graph?.nodes.filter((node) => node.kind === kind).length ?? 0;
|
|
7168
7292
|
}
|
|
7293
|
+
function getCommandViewRenderableGraph(graph) {
|
|
7294
|
+
if (!graph) {
|
|
7295
|
+
return null;
|
|
7296
|
+
}
|
|
7297
|
+
const hasSpecificParentByNodeId = /* @__PURE__ */ new Set();
|
|
7298
|
+
const hasOperationalEdgeByResourceId = /* @__PURE__ */ new Set();
|
|
7299
|
+
for (const edge of graph.edges) {
|
|
7300
|
+
if (edge.kind === "contains" && edge.sourceId !== ORGANIZATION_NODE_ID) {
|
|
7301
|
+
hasSpecificParentByNodeId.add(edge.targetId);
|
|
7302
|
+
}
|
|
7303
|
+
if (edge.kind !== "contains") {
|
|
7304
|
+
hasOperationalEdgeByResourceId.add(edge.sourceId);
|
|
7305
|
+
hasOperationalEdgeByResourceId.add(edge.targetId);
|
|
7306
|
+
}
|
|
7307
|
+
}
|
|
7308
|
+
return {
|
|
7309
|
+
...graph,
|
|
7310
|
+
edges: graph.edges.filter((edge) => {
|
|
7311
|
+
if (edge.kind !== "contains" || edge.sourceId !== ORGANIZATION_NODE_ID) {
|
|
7312
|
+
return true;
|
|
7313
|
+
}
|
|
7314
|
+
const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
|
|
7315
|
+
if (!targetNode) {
|
|
7316
|
+
return false;
|
|
7317
|
+
}
|
|
7318
|
+
if (targetNode.kind === "resource") {
|
|
7319
|
+
return !hasOperationalEdgeByResourceId.has(targetNode.id);
|
|
7320
|
+
}
|
|
7321
|
+
return !hasSpecificParentByNodeId.has(targetNode.id);
|
|
7322
|
+
})
|
|
7323
|
+
};
|
|
7324
|
+
}
|
|
7169
7325
|
function formatGeneratedTimestamp(value) {
|
|
7170
7326
|
if (!value) return "unavailable";
|
|
7171
7327
|
return new Intl.DateTimeFormat("en-US", {
|
|
@@ -7176,13 +7332,25 @@ function formatGeneratedTimestamp(value) {
|
|
|
7176
7332
|
}).format(new Date(value));
|
|
7177
7333
|
}
|
|
7178
7334
|
function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
7179
|
-
const { organizationModel
|
|
7335
|
+
const { organizationModel } = useElevasisFeatures();
|
|
7180
7336
|
const { data: commandViewData, isLoading, error } = useCommandViewData();
|
|
7181
7337
|
const { data: commandViewStats } = useCommandViewStats(timeRange, { enabled: lens === "command-view" });
|
|
7182
7338
|
const setSelectedNodeId = useCommandViewStore((state) => state.setSelectedNodeId);
|
|
7339
|
+
const visualizationMode = useCommandViewStore((state) => state.visualizationMode);
|
|
7340
|
+
const setVisualizationMode = useCommandViewStore((state) => state.setVisualizationMode);
|
|
7341
|
+
const effectiveVisualizationMode = visualizationMode === "spatial" ? "network" : visualizationMode;
|
|
7342
|
+
const resourcesHidden = useCommandViewStore((state) => state.resourcesHidden);
|
|
7343
|
+
const setResourcesHidden = useCommandViewStore((state) => state.setResourcesHidden);
|
|
7344
|
+
const diagnosticsHidden = useCommandViewStore((state) => state.diagnosticsHidden);
|
|
7345
|
+
const setDiagnosticsHidden = useCommandViewStore((state) => state.setDiagnosticsHidden);
|
|
7346
|
+
const diagnosticCategories = useCommandViewStore((state) => state.diagnosticCategories);
|
|
7347
|
+
const revealedIds = useCommandViewStore((state) => state.revealedIds);
|
|
7348
|
+
const setRevealedIds = useCommandViewStore((state) => state.setRevealedIds);
|
|
7349
|
+
const clearRevealedIds = useCommandViewStore((state) => state.clearRevealedIds);
|
|
7350
|
+
const markVisibilityInteraction = useCommandViewStore((state) => state.markVisibilityInteraction);
|
|
7183
7351
|
const lensConfig = useMemo(() => getOrganizationGraphLensConfig(lens), [lens]);
|
|
7184
7352
|
const [mode, setMode] = useState(lensConfig.initialMode);
|
|
7185
|
-
const [activePanelTab, setActivePanelTab] = useState("controls");
|
|
7353
|
+
const [activePanelTab, setActivePanelTab] = useState(lens === "command-view" ? "details" : "controls");
|
|
7186
7354
|
const [selectedElement, setSelectedElement] = useState(null);
|
|
7187
7355
|
const [focusRequest, setFocusRequest] = useState(null);
|
|
7188
7356
|
const [pathTraceSelection, setPathTraceSelection] = useState(EMPTY_TRACE_SELECTION);
|
|
@@ -7195,6 +7363,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7195
7363
|
const rawThemeTokens = readGraphThemeTokens();
|
|
7196
7364
|
const themeSignature = Object.values(rawThemeTokens).join("|");
|
|
7197
7365
|
const themeTokens = useMemo(() => rawThemeTokens, [themeSignature]);
|
|
7366
|
+
useEffect(() => {
|
|
7367
|
+
if (visualizationMode === "spatial") {
|
|
7368
|
+
setVisualizationMode("network");
|
|
7369
|
+
}
|
|
7370
|
+
}, [setVisualizationMode, visualizationMode]);
|
|
7198
7371
|
const baseGraph = useMemo(() => {
|
|
7199
7372
|
if (!organizationModel) {
|
|
7200
7373
|
return null;
|
|
@@ -7212,12 +7385,48 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7212
7385
|
commandViewData
|
|
7213
7386
|
});
|
|
7214
7387
|
}, [baseGraph, commandViewData, deferredFilters]);
|
|
7388
|
+
const visibilityProjection = useMemo(() => {
|
|
7389
|
+
if (!graph || lens !== "command-view") {
|
|
7390
|
+
const resourceCount = getGraphCountByKind(graph, "resource");
|
|
7391
|
+
return {
|
|
7392
|
+
hiddenIds: /* @__PURE__ */ new Set(),
|
|
7393
|
+
hiddenEdgeIds: /* @__PURE__ */ new Set(),
|
|
7394
|
+
totalResourceCount: resourceCount,
|
|
7395
|
+
visibleResourceCount: resourceCount,
|
|
7396
|
+
hiddenResourceCount: 0,
|
|
7397
|
+
hiddenDiagnosticResourceCount: 0
|
|
7398
|
+
};
|
|
7399
|
+
}
|
|
7400
|
+
return getCommandViewVisibilityProjection({
|
|
7401
|
+
graph,
|
|
7402
|
+
commandViewData,
|
|
7403
|
+
resourcesHidden,
|
|
7404
|
+
diagnosticsHidden,
|
|
7405
|
+
diagnosticCategories,
|
|
7406
|
+
revealedIds,
|
|
7407
|
+
mode
|
|
7408
|
+
});
|
|
7409
|
+
}, [commandViewData, diagnosticCategories, diagnosticsHidden, graph, lens, mode, resourcesHidden, revealedIds]);
|
|
7410
|
+
const visibleGraph = useMemo(() => {
|
|
7411
|
+
if (!graph || visibilityProjection.hiddenIds.size === 0) {
|
|
7412
|
+
return graph;
|
|
7413
|
+
}
|
|
7414
|
+
return {
|
|
7415
|
+
...graph,
|
|
7416
|
+
nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
|
|
7417
|
+
edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
|
|
7418
|
+
};
|
|
7419
|
+
}, [graph, visibilityProjection]);
|
|
7420
|
+
const renderGraph = useMemo(
|
|
7421
|
+
() => lens === "command-view" ? getCommandViewRenderableGraph(visibleGraph) : visibleGraph,
|
|
7422
|
+
[lens, visibleGraph]
|
|
7423
|
+
);
|
|
7215
7424
|
const selectedGraphNode = useMemo(() => {
|
|
7216
|
-
if (!
|
|
7425
|
+
if (!visibleGraph || !selectedElement || selectedElement.type !== "node") {
|
|
7217
7426
|
return null;
|
|
7218
7427
|
}
|
|
7219
|
-
return
|
|
7220
|
-
}, [
|
|
7428
|
+
return visibleGraph.nodes.find((node) => node.id === selectedElement.id) ?? null;
|
|
7429
|
+
}, [selectedElement, visibleGraph]);
|
|
7221
7430
|
const selectedCommandViewResourceId = selectedGraphNode?.kind === "resource" ? selectedGraphNode.sourceId ?? null : null;
|
|
7222
7431
|
const isExecutableSelection = lens === "command-view" && selectedGraphNode?.kind === "resource" && (selectedGraphNode.resourceType === "agent" || selectedGraphNode.resourceType === "workflow") && Boolean(selectedCommandViewResourceId);
|
|
7223
7432
|
const isCheckpointSelection = lens === "command-view" && selectedGraphNode?.kind === "resource" && selectedGraphNode.resourceType === "human_checkpoint" && Boolean(selectedCommandViewResourceId);
|
|
@@ -7231,11 +7440,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7231
7440
|
enabled: isCheckpointSelection
|
|
7232
7441
|
});
|
|
7233
7442
|
const traceResult = useMemo(() => {
|
|
7234
|
-
if (!
|
|
7443
|
+
if (!visibleGraph) {
|
|
7235
7444
|
return null;
|
|
7236
7445
|
}
|
|
7237
|
-
return resolveOrganizationGraphPathTrace(
|
|
7238
|
-
}, [
|
|
7446
|
+
return resolveOrganizationGraphPathTrace(visibleGraph, pathTraceSelection);
|
|
7447
|
+
}, [pathTraceSelection, visibleGraph]);
|
|
7239
7448
|
const activeTraceResult = mode === "trace" ? traceResult : null;
|
|
7240
7449
|
const operationalOverview = useMemo(
|
|
7241
7450
|
() => lens === "command-view" ? getCommandViewOperationalOverview(commandViewData, commandViewStats) : null,
|
|
@@ -7259,8 +7468,8 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7259
7468
|
[baseGraph, commandViewStats, lens]
|
|
7260
7469
|
);
|
|
7261
7470
|
const visibleCommandViewHealth = useMemo(
|
|
7262
|
-
() =>
|
|
7263
|
-
[commandViewHealthByNodeId,
|
|
7471
|
+
() => visibleGraph && commandViewHealthByNodeId ? visibleGraph.nodes.map((node) => commandViewHealthByNodeId.get(node.id) ?? null).filter((entry) => entry !== null) : [],
|
|
7472
|
+
[commandViewHealthByNodeId, visibleGraph]
|
|
7264
7473
|
);
|
|
7265
7474
|
const visibleHotspots = useMemo(() => rankCommandViewHotspots(visibleCommandViewHealth), [visibleCommandViewHealth]);
|
|
7266
7475
|
const pendingCheckpointHotspot = useMemo(
|
|
@@ -7268,11 +7477,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7268
7477
|
[visibleCommandViewHealth]
|
|
7269
7478
|
);
|
|
7270
7479
|
const jumpToResourceOptions = useMemo(
|
|
7271
|
-
() => (
|
|
7480
|
+
() => (visibleGraph?.nodes ?? []).filter((node) => node.kind === "resource").map((node) => ({
|
|
7272
7481
|
value: node.id,
|
|
7273
7482
|
label: node.label
|
|
7274
7483
|
})).sort((left, right) => left.label.localeCompare(right.label)),
|
|
7275
|
-
[
|
|
7484
|
+
[visibleGraph]
|
|
7276
7485
|
);
|
|
7277
7486
|
const focusGraphNode = useEffectEvent((nodeId2) => {
|
|
7278
7487
|
setFocusRequest({
|
|
@@ -7281,7 +7490,7 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7281
7490
|
});
|
|
7282
7491
|
});
|
|
7283
7492
|
const focusCommandViewResource = useEffectEvent((resourceId) => {
|
|
7284
|
-
const focusNode =
|
|
7493
|
+
const focusNode = visibleGraph?.nodes.find((node) => node.kind === "resource" && node.sourceId === resourceId);
|
|
7285
7494
|
if (!focusNode) {
|
|
7286
7495
|
return;
|
|
7287
7496
|
}
|
|
@@ -7289,26 +7498,64 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7289
7498
|
setSelectedElement({ type: "node", id: focusNode.id });
|
|
7290
7499
|
focusGraphNode(focusNode.id);
|
|
7291
7500
|
});
|
|
7501
|
+
const handleResetFilters = useEffectEvent(() => {
|
|
7502
|
+
resetFilters();
|
|
7503
|
+
clearRevealedIds();
|
|
7504
|
+
setSelectedElement(null);
|
|
7505
|
+
setPathTraceSelection(EMPTY_TRACE_SELECTION);
|
|
7506
|
+
});
|
|
7507
|
+
const handleResourcesHiddenChange = useEffectEvent((value) => {
|
|
7508
|
+
setResourcesHidden(value);
|
|
7509
|
+
if (value) {
|
|
7510
|
+
clearRevealedIds();
|
|
7511
|
+
setSelectedElement(null);
|
|
7512
|
+
}
|
|
7513
|
+
});
|
|
7514
|
+
const handleDiagnosticsHiddenChange = useEffectEvent((value) => {
|
|
7515
|
+
setDiagnosticsHidden(value);
|
|
7516
|
+
if (value) {
|
|
7517
|
+
clearRevealedIds();
|
|
7518
|
+
}
|
|
7519
|
+
});
|
|
7520
|
+
const revealAllResources = useEffectEvent(() => {
|
|
7521
|
+
setResourcesHidden(false);
|
|
7522
|
+
setDiagnosticsHidden(false);
|
|
7523
|
+
clearRevealedIds();
|
|
7524
|
+
});
|
|
7292
7525
|
const handleSelectElement = useEffectEvent((element) => {
|
|
7293
7526
|
if (!element) {
|
|
7527
|
+
if (!selectedElement && revealedIds.size === 0) {
|
|
7528
|
+
return;
|
|
7529
|
+
}
|
|
7294
7530
|
setSelectedElement(null);
|
|
7531
|
+
clearRevealedIds();
|
|
7295
7532
|
return;
|
|
7296
7533
|
}
|
|
7297
7534
|
if (mode === "map" && element.type === "node" && selectedElement?.type === "node" && selectedElement.id === element.id) {
|
|
7298
7535
|
setActivePanelTab("details");
|
|
7299
7536
|
return;
|
|
7300
7537
|
}
|
|
7538
|
+
if (lens === "command-view" && element.type === "node" && graph) {
|
|
7539
|
+
const connectedHiddenIds = getConnectedHiddenResourceIds(graph, element.id, visibilityProjection.hiddenIds);
|
|
7540
|
+
setRevealedIds(connectedHiddenIds);
|
|
7541
|
+
if (connectedHiddenIds.size > 0) {
|
|
7542
|
+
markVisibilityInteraction();
|
|
7543
|
+
}
|
|
7544
|
+
} else {
|
|
7545
|
+
clearRevealedIds();
|
|
7546
|
+
}
|
|
7301
7547
|
setSelectedElement(element);
|
|
7302
7548
|
});
|
|
7303
7549
|
useEffect(() => {
|
|
7304
7550
|
if (!graph || !selectedElement) {
|
|
7305
7551
|
return;
|
|
7306
7552
|
}
|
|
7307
|
-
const elementExists = selectedElement.type === "node" ?
|
|
7553
|
+
const elementExists = selectedElement.type === "node" ? Boolean(visibleGraph?.nodes.some((node) => node.id === selectedElement.id)) : Boolean(visibleGraph?.edges.some((edge) => edge.id === selectedElement.id));
|
|
7308
7554
|
if (!elementExists) {
|
|
7309
7555
|
setSelectedElement(null);
|
|
7556
|
+
clearRevealedIds();
|
|
7310
7557
|
}
|
|
7311
|
-
}, [
|
|
7558
|
+
}, [clearRevealedIds, selectedElement, visibleGraph]);
|
|
7312
7559
|
useEffect(() => {
|
|
7313
7560
|
if (lens !== "command-view") {
|
|
7314
7561
|
return;
|
|
@@ -7331,7 +7578,7 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7331
7578
|
});
|
|
7332
7579
|
return;
|
|
7333
7580
|
}
|
|
7334
|
-
const visibleNodeIds = new Set(
|
|
7581
|
+
const visibleNodeIds = new Set(visibleGraph?.nodes.map((node) => node.id) ?? []);
|
|
7335
7582
|
setPathTraceSelection((current) => {
|
|
7336
7583
|
const sourceId = current.sourceId && visibleNodeIds.has(current.sourceId) ? current.sourceId : null;
|
|
7337
7584
|
const targetId = current.targetId && visibleNodeIds.has(current.targetId) ? current.targetId : null;
|
|
@@ -7340,14 +7587,14 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7340
7587
|
}
|
|
7341
7588
|
return { sourceId, targetId };
|
|
7342
7589
|
});
|
|
7343
|
-
}, [graph]);
|
|
7590
|
+
}, [graph, visibleGraph]);
|
|
7344
7591
|
if (!organizationModel) {
|
|
7345
7592
|
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
7346
7593
|
/* @__PURE__ */ jsx(
|
|
7347
7594
|
PageTitleCaption,
|
|
7348
7595
|
{
|
|
7349
|
-
title: "
|
|
7350
|
-
caption: "
|
|
7596
|
+
title: lens === "command-view" ? "Command View" : "Operations Graph",
|
|
7597
|
+
caption: "This surface needs an organization model before it can render."
|
|
7351
7598
|
}
|
|
7352
7599
|
),
|
|
7353
7600
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "xl", children: /* @__PURE__ */ jsx(
|
|
@@ -7360,363 +7607,357 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7360
7607
|
) })
|
|
7361
7608
|
] });
|
|
7362
7609
|
}
|
|
7363
|
-
return /* @__PURE__ */ jsx(Stack, { gap: "lg", style: { flex: 1, minHeight: 0
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7610
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "lg", style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsx(Tabs, { value: activePanelTab, onChange: setActivePanelTab, keepMounted: false, children: /* @__PURE__ */ jsxs(
|
|
7611
|
+
Paper,
|
|
7612
|
+
{
|
|
7613
|
+
withBorder: true,
|
|
7614
|
+
radius: "md",
|
|
7615
|
+
style: {
|
|
7616
|
+
display: "flex",
|
|
7617
|
+
flexDirection: "column",
|
|
7618
|
+
minHeight: 0,
|
|
7619
|
+
background: "var(--color-surface)",
|
|
7620
|
+
boxShadow: "var(--card-shadow)",
|
|
7621
|
+
overflow: "hidden"
|
|
7622
|
+
},
|
|
7623
|
+
children: [
|
|
7624
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
7625
|
+
CommandViewHealthStrip,
|
|
7626
|
+
{
|
|
7627
|
+
overview: operationalOverview,
|
|
7628
|
+
hotspots: visibleHotspots,
|
|
7629
|
+
visibleResources: visibilityProjection.visibleResourceCount,
|
|
7630
|
+
hiddenResources: visibilityProjection.hiddenResourceCount,
|
|
7631
|
+
resourcesHidden,
|
|
7632
|
+
selectedLabel: selectedGraphNode?.label ?? null,
|
|
7633
|
+
onFocusHotspot: focusCommandViewResource,
|
|
7634
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
7635
|
+
onResetFocus: () => {
|
|
7636
|
+
setMode("map");
|
|
7637
|
+
setSelectedElement(null);
|
|
7638
|
+
clearRevealedIds();
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
) : null,
|
|
7642
|
+
/* @__PURE__ */ jsx(
|
|
7643
|
+
Box,
|
|
7644
|
+
{
|
|
7645
|
+
style: {
|
|
7646
|
+
height: lens === "command-view" ? "54vh" : "62vh",
|
|
7647
|
+
minHeight: lens === "command-view" ? 420 : 520,
|
|
7648
|
+
maxHeight: lens === "command-view" ? 620 : void 0,
|
|
7649
|
+
position: "relative"
|
|
7650
|
+
},
|
|
7651
|
+
children: renderGraph && renderGraph.nodes.length > 0 ? /* @__PURE__ */ jsx(
|
|
7392
7652
|
OrganizationGraphCanvas,
|
|
7393
7653
|
{
|
|
7394
|
-
graph,
|
|
7654
|
+
graph: renderGraph,
|
|
7395
7655
|
mode,
|
|
7656
|
+
visualizationMode: lens === "command-view" ? effectiveVisualizationMode : "network",
|
|
7396
7657
|
selectedElement,
|
|
7397
7658
|
traceResult: activeTraceResult,
|
|
7659
|
+
hiddenIds: EMPTY_GRAPH_HIDDEN_IDS,
|
|
7660
|
+
hiddenEdgeIds: EMPTY_GRAPH_HIDDEN_EDGE_IDS,
|
|
7398
7661
|
themeTokens,
|
|
7399
7662
|
commandViewHealthByNodeId,
|
|
7400
7663
|
focusRequest,
|
|
7664
|
+
toolbar: /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
7665
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
7666
|
+
SegmentedControl,
|
|
7667
|
+
{
|
|
7668
|
+
value: effectiveVisualizationMode,
|
|
7669
|
+
onChange: (value) => setVisualizationMode(value),
|
|
7670
|
+
size: "xs",
|
|
7671
|
+
data: COMMAND_VIEW_VISUALIZATION_MODES
|
|
7672
|
+
}
|
|
7673
|
+
) : null,
|
|
7674
|
+
/* @__PURE__ */ jsx(
|
|
7675
|
+
SegmentedControl,
|
|
7676
|
+
{
|
|
7677
|
+
value: mode,
|
|
7678
|
+
onChange: (value) => setMode(value),
|
|
7679
|
+
size: "xs",
|
|
7680
|
+
data: [
|
|
7681
|
+
{ label: "Map", value: "map" },
|
|
7682
|
+
{ label: "Trace", value: "trace" },
|
|
7683
|
+
{ label: "Impact", value: "impact" }
|
|
7684
|
+
]
|
|
7685
|
+
}
|
|
7686
|
+
)
|
|
7687
|
+
] }),
|
|
7401
7688
|
onSelectElement: handleSelectElement
|
|
7402
7689
|
}
|
|
7690
|
+
) : /* @__PURE__ */ jsx(
|
|
7691
|
+
EmptyState,
|
|
7692
|
+
{
|
|
7693
|
+
icon: IconTopologyStar3,
|
|
7694
|
+
title: "No graph elements match the current filters",
|
|
7695
|
+
description: lens === "command-view" && visibilityProjection.hiddenResourceCount > 0 ? "Reveal resources or adjust filters to bring graph elements back into view." : "Adjust the graph controls to bring semantic nodes, topology nodes, or relationship matches back into view."
|
|
7696
|
+
}
|
|
7697
|
+
)
|
|
7698
|
+
}
|
|
7699
|
+
),
|
|
7700
|
+
/* @__PURE__ */ jsx(Box, { p: "xs", children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "wrap", children: [
|
|
7701
|
+
/* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "wrap", children: [
|
|
7702
|
+
/* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", children: lens === "command-view" ? "Command View" : lensConfig.title }),
|
|
7703
|
+
/* @__PURE__ */ jsxs(Tabs.List, { children: [
|
|
7704
|
+
lens === "command-view" ? null : /* @__PURE__ */ jsx(Tabs.Tab, { value: "controls", children: "Controls" }),
|
|
7705
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "trace", children: "Trace" }),
|
|
7706
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "details", children: "Details" }),
|
|
7707
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" })
|
|
7708
|
+
] })
|
|
7709
|
+
] }),
|
|
7710
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
7711
|
+
/* @__PURE__ */ jsx(
|
|
7712
|
+
Select,
|
|
7713
|
+
{
|
|
7714
|
+
placeholder: "Jump to resource",
|
|
7715
|
+
searchable: true,
|
|
7716
|
+
clearable: true,
|
|
7717
|
+
size: "xs",
|
|
7718
|
+
data: jumpToResourceOptions,
|
|
7719
|
+
value: selectedElement?.type === "node" ? selectedElement.id : null,
|
|
7720
|
+
onChange: (value) => {
|
|
7721
|
+
if (!value) {
|
|
7722
|
+
return;
|
|
7723
|
+
}
|
|
7724
|
+
setMode("map");
|
|
7725
|
+
setSelectedElement({ type: "node", id: value });
|
|
7726
|
+
focusGraphNode(value);
|
|
7727
|
+
},
|
|
7728
|
+
styles: {
|
|
7729
|
+
root: { minWidth: 220 }
|
|
7730
|
+
},
|
|
7731
|
+
nothingFoundMessage: "No matching resource"
|
|
7732
|
+
}
|
|
7403
7733
|
),
|
|
7404
7734
|
/* @__PURE__ */ jsx(
|
|
7405
|
-
|
|
7735
|
+
Button,
|
|
7406
7736
|
{
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
maxWidth: "calc(100% - 320px)"
|
|
7737
|
+
size: "xs",
|
|
7738
|
+
variant: "subtle",
|
|
7739
|
+
onClick: () => {
|
|
7740
|
+
setSelectedElement(null);
|
|
7741
|
+
clearRevealedIds();
|
|
7413
7742
|
},
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
{
|
|
7417
|
-
value: mode,
|
|
7418
|
-
onChange: (value) => setMode(value),
|
|
7419
|
-
size: "xs",
|
|
7420
|
-
data: [
|
|
7421
|
-
{ label: "Map", value: "map" },
|
|
7422
|
-
{ label: "Trace", value: "trace" },
|
|
7423
|
-
{ label: "Impact", value: "impact" }
|
|
7424
|
-
]
|
|
7425
|
-
}
|
|
7426
|
-
)
|
|
7743
|
+
disabled: !selectedElement,
|
|
7744
|
+
children: "Clear selection"
|
|
7427
7745
|
}
|
|
7428
|
-
)
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
{
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" })
|
|
7456
|
-
] })
|
|
7457
|
-
] }),
|
|
7458
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
7459
|
-
/* @__PURE__ */ jsx(
|
|
7460
|
-
Select,
|
|
7461
|
-
{
|
|
7462
|
-
placeholder: "Jump to resource",
|
|
7463
|
-
searchable: true,
|
|
7464
|
-
clearable: true,
|
|
7465
|
-
size: "xs",
|
|
7466
|
-
data: jumpToResourceOptions,
|
|
7467
|
-
value: selectedElement?.type === "node" ? selectedElement.id : null,
|
|
7468
|
-
onChange: (value) => {
|
|
7469
|
-
if (!value) {
|
|
7470
|
-
return;
|
|
7471
|
-
}
|
|
7472
|
-
setMode("map");
|
|
7473
|
-
setSelectedElement({ type: "node", id: value });
|
|
7474
|
-
focusGraphNode(value);
|
|
7475
|
-
},
|
|
7476
|
-
styles: {
|
|
7477
|
-
root: { minWidth: 220 }
|
|
7478
|
-
},
|
|
7479
|
-
nothingFoundMessage: "No matching resource"
|
|
7480
|
-
}
|
|
7481
|
-
),
|
|
7482
|
-
/* @__PURE__ */ jsx(
|
|
7483
|
-
Button,
|
|
7484
|
-
{
|
|
7485
|
-
size: "xs",
|
|
7486
|
-
variant: "subtle",
|
|
7487
|
-
onClick: () => setSelectedElement(null),
|
|
7488
|
-
disabled: !selectedElement,
|
|
7489
|
-
children: "Clear selection"
|
|
7490
|
-
}
|
|
7491
|
-
),
|
|
7492
|
-
/* @__PURE__ */ jsx(
|
|
7493
|
-
Button,
|
|
7494
|
-
{
|
|
7495
|
-
size: "xs",
|
|
7496
|
-
variant: "subtle",
|
|
7497
|
-
onClick: () => setPathTraceSelection(EMPTY_TRACE_SELECTION),
|
|
7498
|
-
disabled: !pathTraceSelection.sourceId && !pathTraceSelection.targetId,
|
|
7499
|
-
children: "Clear trace"
|
|
7500
|
-
}
|
|
7501
|
-
),
|
|
7502
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: resetFilters, children: "Reset filters" })
|
|
7503
|
-
] })
|
|
7504
|
-
] }) }),
|
|
7505
|
-
/* @__PURE__ */ jsxs(
|
|
7506
|
-
Box,
|
|
7746
|
+
),
|
|
7747
|
+
/* @__PURE__ */ jsx(
|
|
7748
|
+
Button,
|
|
7749
|
+
{
|
|
7750
|
+
size: "xs",
|
|
7751
|
+
variant: "subtle",
|
|
7752
|
+
onClick: () => setPathTraceSelection(EMPTY_TRACE_SELECTION),
|
|
7753
|
+
disabled: !pathTraceSelection.sourceId && !pathTraceSelection.targetId,
|
|
7754
|
+
children: "Clear trace"
|
|
7755
|
+
}
|
|
7756
|
+
),
|
|
7757
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: handleResetFilters, children: "Reset filters" })
|
|
7758
|
+
] })
|
|
7759
|
+
] }) }),
|
|
7760
|
+
/* @__PURE__ */ jsxs(
|
|
7761
|
+
Box,
|
|
7762
|
+
{
|
|
7763
|
+
p: "xs",
|
|
7764
|
+
className: HIDE_SCROLLBAR_CLASS_NAME,
|
|
7765
|
+
style: {
|
|
7766
|
+
padding: "var(--mantine-spacing-md)",
|
|
7767
|
+
paddingTop: 0
|
|
7768
|
+
},
|
|
7769
|
+
children: [
|
|
7770
|
+
lens === "command-view" ? null : /* @__PURE__ */ jsx(Tabs.Panel, { value: "controls", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
7771
|
+
/* @__PURE__ */ jsx(
|
|
7772
|
+
FilterPanel,
|
|
7507
7773
|
{
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
|
|
7535
|
-
}
|
|
7536
|
-
),
|
|
7537
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "md", style: { gridColumn: "span 2" }, children: [
|
|
7538
|
-
/* @__PURE__ */ jsxs(
|
|
7539
|
-
Card,
|
|
7540
|
-
{
|
|
7541
|
-
withBorder: true,
|
|
7542
|
-
radius: "lg",
|
|
7543
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7544
|
-
children: [
|
|
7545
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Tracked runs" : "Visible nodes" }),
|
|
7546
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.totalRuns ?? 0 : graph?.nodes.length ?? 0 }),
|
|
7547
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${timeRange} execution window` : `of ${baseGraph?.nodes.length ?? 0} total` })
|
|
7548
|
-
]
|
|
7549
|
-
}
|
|
7550
|
-
),
|
|
7551
|
-
/* @__PURE__ */ jsxs(
|
|
7552
|
-
Card,
|
|
7553
|
-
{
|
|
7554
|
-
withBorder: true,
|
|
7555
|
-
radius: "lg",
|
|
7556
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7557
|
-
children: [
|
|
7558
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Success rate" : "Visible edges" }),
|
|
7559
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? `${Math.round(operationalOverview?.successRate ?? 0)}%` : graph?.edges.length ?? 0 }),
|
|
7560
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${operationalOverview?.successCount ?? 0} successful runs` : `of ${baseGraph?.edges.length ?? 0} total` })
|
|
7561
|
-
]
|
|
7562
|
-
}
|
|
7563
|
-
),
|
|
7564
|
-
/* @__PURE__ */ jsxs(
|
|
7565
|
-
Card,
|
|
7566
|
-
{
|
|
7567
|
-
withBorder: true,
|
|
7568
|
-
radius: "lg",
|
|
7569
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7570
|
-
children: [
|
|
7571
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Failing resources" : "Visible features" }),
|
|
7572
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.topFailingResources.length ?? 0 : getGraphCountByKind(graph, "feature") }),
|
|
7573
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? operationalOverview?.topFailingResources.length ? operationalOverview.topFailingResources.map((resource) => `${resource.label} (${resource.failureCount})`).join(", ") : "No failing resources in the current window" : `of ${getGraphCountByKind(baseGraph, "feature")} total` })
|
|
7574
|
-
]
|
|
7575
|
-
}
|
|
7576
|
-
),
|
|
7577
|
-
/* @__PURE__ */ jsxs(
|
|
7578
|
-
Card,
|
|
7579
|
-
{
|
|
7580
|
-
withBorder: true,
|
|
7581
|
-
radius: "lg",
|
|
7582
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7583
|
-
children: [
|
|
7584
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Pending approvals" : "Visible resources" }),
|
|
7585
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.pendingApprovals ?? 0 : getGraphCountByKind(graph, "resource") }),
|
|
7586
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${operationalOverview?.activeHumanCheckpoints ?? 0} active checkpoint queues` : `of ${getGraphCountByKind(baseGraph, "resource")} total` })
|
|
7587
|
-
]
|
|
7588
|
-
}
|
|
7589
|
-
)
|
|
7590
|
-
] })
|
|
7591
|
-
] }),
|
|
7592
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
7593
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", children: lens === "command-view" ? "Operations lens" : "Shared graph" }),
|
|
7594
|
-
/* @__PURE__ */ jsx(
|
|
7595
|
-
Badge,
|
|
7596
|
-
{
|
|
7597
|
-
variant: "light",
|
|
7598
|
-
color: organizationGraph.available ? "var(--color-success)" : "var(--color-text-subtle)",
|
|
7599
|
-
children: organizationGraph.available ? "Provider graph surface ready" : "Provider graph surface missing"
|
|
7600
|
-
}
|
|
7601
|
-
),
|
|
7602
|
-
/* @__PURE__ */ jsx(
|
|
7603
|
-
Badge,
|
|
7604
|
-
{
|
|
7605
|
-
variant: "light",
|
|
7606
|
-
color: commandViewData ? "var(--color-primary)" : "var(--color-text-subtle)",
|
|
7607
|
-
children: commandViewData ? "Topology bridged" : isLoading ? "Topology loading" : "Semantic only"
|
|
7608
|
-
}
|
|
7609
|
-
),
|
|
7610
|
-
error ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "var(--color-error)", children: "Topology unavailable" }) : null
|
|
7611
|
-
] }),
|
|
7774
|
+
filters,
|
|
7775
|
+
onChangeFilters: updateFilters,
|
|
7776
|
+
resetValue: toolbarResetValue,
|
|
7777
|
+
disabled: !baseGraph,
|
|
7778
|
+
commandViewData,
|
|
7779
|
+
lens,
|
|
7780
|
+
resourcesHidden,
|
|
7781
|
+
diagnosticsHidden,
|
|
7782
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
7783
|
+
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
7784
|
+
onRevealResources: revealAllResources,
|
|
7785
|
+
onResetFilters: handleResetFilters,
|
|
7786
|
+
visibilityCounts: visibilityProjection,
|
|
7787
|
+
graph: visibleGraph,
|
|
7788
|
+
baseGraph
|
|
7789
|
+
}
|
|
7790
|
+
),
|
|
7791
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2, lg: 4 }, spacing: "md", children: [
|
|
7792
|
+
/* @__PURE__ */ jsxs(
|
|
7793
|
+
Card,
|
|
7794
|
+
{
|
|
7795
|
+
withBorder: true,
|
|
7796
|
+
radius: "lg",
|
|
7797
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7798
|
+
children: [
|
|
7799
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible nodes" }),
|
|
7800
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: visibleGraph?.nodes.length ?? 0 }),
|
|
7612
7801
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7613
|
-
"
|
|
7614
|
-
|
|
7615
|
-
"
|
|
7616
|
-
graph?.edges.length ?? 0,
|
|
7617
|
-
" edges in the current projection. In map mode, single-click isolates a node neighborhood and clicking another node pivots the focus."
|
|
7802
|
+
"of ",
|
|
7803
|
+
baseGraph?.nodes.length ?? 0,
|
|
7804
|
+
" total"
|
|
7618
7805
|
] })
|
|
7619
|
-
]
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
] }) }),
|
|
7632
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "details", pt: 0, children: /* @__PURE__ */ jsx(
|
|
7633
|
-
OrganizationGraphDetailPanel,
|
|
7634
|
-
{
|
|
7635
|
-
graph,
|
|
7636
|
-
selectedElement,
|
|
7637
|
-
supplementalSummary: selectionOperationalSummary,
|
|
7638
|
-
followUpSections,
|
|
7639
|
-
onClearSelection: () => setSelectedElement(null)
|
|
7640
|
-
}
|
|
7641
|
-
) }),
|
|
7642
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "runtime", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
7643
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7644
|
-
"Active Lens: ",
|
|
7645
|
-
lens
|
|
7646
|
-
] }),
|
|
7647
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7648
|
-
"Surface ID: ",
|
|
7649
|
-
organizationGraph.surfaceId ?? "unresolved"
|
|
7650
|
-
] }),
|
|
7806
|
+
]
|
|
7807
|
+
}
|
|
7808
|
+
),
|
|
7809
|
+
/* @__PURE__ */ jsxs(
|
|
7810
|
+
Card,
|
|
7811
|
+
{
|
|
7812
|
+
withBorder: true,
|
|
7813
|
+
radius: "lg",
|
|
7814
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7815
|
+
children: [
|
|
7816
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible edges" }),
|
|
7817
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: visibleGraph?.edges.length ?? 0 }),
|
|
7651
7818
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7652
|
-
"
|
|
7653
|
-
|
|
7654
|
-
|
|
7819
|
+
"of ",
|
|
7820
|
+
baseGraph?.edges.length ?? 0,
|
|
7821
|
+
" total"
|
|
7822
|
+
] })
|
|
7823
|
+
]
|
|
7824
|
+
}
|
|
7825
|
+
),
|
|
7826
|
+
/* @__PURE__ */ jsxs(
|
|
7827
|
+
Card,
|
|
7828
|
+
{
|
|
7829
|
+
withBorder: true,
|
|
7830
|
+
radius: "lg",
|
|
7831
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7832
|
+
children: [
|
|
7833
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible features" }),
|
|
7834
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: getGraphCountByKind(visibleGraph, "feature") }),
|
|
7655
7835
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7656
|
-
"
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
" with",
|
|
7673
|
-
" ",
|
|
7674
|
-
pendingCheckpointHotspot.pendingCount,
|
|
7675
|
-
" pending approvals."
|
|
7676
|
-
] }) : null,
|
|
7677
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph Build: semantic derivation plus bridged Command View topology" }),
|
|
7836
|
+
"of ",
|
|
7837
|
+
getGraphCountByKind(baseGraph, "feature"),
|
|
7838
|
+
" total"
|
|
7839
|
+
] })
|
|
7840
|
+
]
|
|
7841
|
+
}
|
|
7842
|
+
),
|
|
7843
|
+
/* @__PURE__ */ jsxs(
|
|
7844
|
+
Card,
|
|
7845
|
+
{
|
|
7846
|
+
withBorder: true,
|
|
7847
|
+
radius: "lg",
|
|
7848
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7849
|
+
children: [
|
|
7850
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible resources" }),
|
|
7851
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: getGraphCountByKind(visibleGraph, "resource") }),
|
|
7678
7852
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7679
|
-
"
|
|
7680
|
-
|
|
7681
|
-
"
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7853
|
+
"of ",
|
|
7854
|
+
getGraphCountByKind(baseGraph, "resource"),
|
|
7855
|
+
" total"
|
|
7856
|
+
] })
|
|
7857
|
+
]
|
|
7858
|
+
}
|
|
7859
|
+
)
|
|
7860
|
+
] }),
|
|
7861
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
7862
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", children: "Command View graph" }),
|
|
7863
|
+
/* @__PURE__ */ jsx(
|
|
7864
|
+
Badge,
|
|
7865
|
+
{
|
|
7866
|
+
variant: "light",
|
|
7867
|
+
color: commandViewData ? "var(--color-primary)" : "var(--color-text-subtle)",
|
|
7868
|
+
children: commandViewData ? "Topology bridged" : isLoading ? "Topology loading" : "Semantic only"
|
|
7869
|
+
}
|
|
7870
|
+
),
|
|
7871
|
+
error ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "var(--color-error)", children: "Topology unavailable" }) : null
|
|
7872
|
+
] }),
|
|
7873
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7874
|
+
"Showing ",
|
|
7875
|
+
visibleGraph?.nodes.length ?? 0,
|
|
7876
|
+
" nodes and ",
|
|
7877
|
+
visibleGraph?.edges.length ?? 0,
|
|
7878
|
+
" edges in the current projection. In map mode, single-click isolates a node neighborhood and clicking another node pivots the focus."
|
|
7879
|
+
] })
|
|
7880
|
+
] }) }),
|
|
7881
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "trace", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
7882
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Trace mode resolves shortest directed paths inside the current filtered graph." }),
|
|
7883
|
+
visibleGraph ? /* @__PURE__ */ jsx(
|
|
7884
|
+
OrganizationGraphPathTraceControls,
|
|
7885
|
+
{
|
|
7886
|
+
graph: visibleGraph,
|
|
7887
|
+
value: pathTraceSelection,
|
|
7888
|
+
onChange: setPathTraceSelection,
|
|
7889
|
+
disabled: visibleGraph.nodes.length === 0
|
|
7692
7890
|
}
|
|
7693
|
-
)
|
|
7694
|
-
]
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7891
|
+
) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph data is not available yet." })
|
|
7892
|
+
] }) }),
|
|
7893
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "details", pt: 0, children: /* @__PURE__ */ jsx(
|
|
7894
|
+
OrganizationGraphDetailPanel,
|
|
7895
|
+
{
|
|
7896
|
+
graph: visibleGraph,
|
|
7897
|
+
selectedElement,
|
|
7898
|
+
supplementalSummary: selectionOperationalSummary,
|
|
7899
|
+
followUpSections,
|
|
7900
|
+
onClearSelection: () => {
|
|
7901
|
+
setSelectedElement(null);
|
|
7902
|
+
clearRevealedIds();
|
|
7903
|
+
}
|
|
7904
|
+
}
|
|
7905
|
+
) }),
|
|
7906
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "runtime", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
7907
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7908
|
+
"Active Lens: ",
|
|
7909
|
+
lens
|
|
7910
|
+
] }),
|
|
7911
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7912
|
+
"Active Mode: ",
|
|
7913
|
+
mode
|
|
7914
|
+
] }),
|
|
7915
|
+
lens === "command-view" ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7916
|
+
"Visualization: ",
|
|
7917
|
+
effectiveVisualizationMode
|
|
7918
|
+
] }) : null,
|
|
7919
|
+
operationalOverview ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7920
|
+
"Operational Snapshot: ",
|
|
7921
|
+
operationalOverview.trackedResources,
|
|
7922
|
+
" resources,",
|
|
7923
|
+
" ",
|
|
7924
|
+
operationalOverview.pendingApprovals,
|
|
7925
|
+
" pending approvals, generated",
|
|
7926
|
+
" ",
|
|
7927
|
+
formatGeneratedTimestamp(operationalOverview.generatedAt)
|
|
7928
|
+
] }) : null,
|
|
7929
|
+
pendingCheckpointHotspot ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7930
|
+
"Active queue hotspot: ",
|
|
7931
|
+
pendingCheckpointHotspot.resourceId,
|
|
7932
|
+
" with",
|
|
7933
|
+
" ",
|
|
7934
|
+
pendingCheckpointHotspot.pendingCount,
|
|
7935
|
+
" pending approvals."
|
|
7936
|
+
] }) : null,
|
|
7937
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph Build: semantic derivation plus bridged Command View topology" }),
|
|
7938
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7939
|
+
"Projection: ",
|
|
7940
|
+
visibleGraph?.nodes.length ?? 0,
|
|
7941
|
+
" visible nodes, ",
|
|
7942
|
+
visibleGraph?.edges.length ?? 0,
|
|
7943
|
+
" visible edges"
|
|
7944
|
+
] }),
|
|
7945
|
+
isLoading ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Topology bridge is still loading; semantic nodes remain available." }) : null,
|
|
7946
|
+
error ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red", children: [
|
|
7947
|
+
"Topology bridge error: ",
|
|
7948
|
+
error.message
|
|
7949
|
+
] }) : null
|
|
7950
|
+
] }) })
|
|
7951
|
+
]
|
|
7952
|
+
}
|
|
7953
|
+
)
|
|
7954
|
+
]
|
|
7955
|
+
}
|
|
7956
|
+
) }) });
|
|
7701
7957
|
}
|
|
7702
7958
|
function CommandViewPage({ timeRange }) {
|
|
7703
7959
|
return /* @__PURE__ */ jsx(OrganizationGraphPage, { lens: "command-view", timeRange });
|
|
7704
7960
|
}
|
|
7705
|
-
var FILTER_STATE_ICONS2 = {
|
|
7706
|
-
neutral: IconCircleDashed,
|
|
7707
|
-
include: IconCircleCheck,
|
|
7708
|
-
exclude: IconCircleX
|
|
7709
|
-
};
|
|
7710
|
-
var FILTER_STATE_COLORS2 = {
|
|
7711
|
-
neutral: "var(--color-surface-hover)",
|
|
7712
|
-
include: "var(--mantine-color-green-6)",
|
|
7713
|
-
exclude: "var(--mantine-color-red-6)"
|
|
7714
|
-
};
|
|
7715
|
-
var FILTER_STATE_LABELS2 = {
|
|
7716
|
-
neutral: "Not filtered",
|
|
7717
|
-
include: "Include only",
|
|
7718
|
-
exclude: "Exclude"
|
|
7719
|
-
};
|
|
7720
7961
|
var EXECUTION_SECTIONS = [
|
|
7721
7962
|
{ status: "failed", title: "Failed Executions", badgeColor: "red" },
|
|
7722
7963
|
{ status: "warning", title: "Warning Executions", badgeColor: "yellow" },
|
|
@@ -7770,22 +8011,21 @@ function ExecutionStatusSection({ executions, status, title, badgeColor, resourc
|
|
|
7770
8011
|
function CommandViewSidebarContent({ timeRange }) {
|
|
7771
8012
|
const theme = useMantineTheme();
|
|
7772
8013
|
const colors = useCyberColors();
|
|
7773
|
-
const
|
|
8014
|
+
const { organizationModel } = useElevasisFeatures();
|
|
8015
|
+
const lensConfig = useMemo(() => getOrganizationGraphLensConfig("command-view"), []);
|
|
8016
|
+
const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
|
|
8017
|
+
const toolbarResetValue = useMemo(
|
|
8018
|
+
() => createOrganizationGraphFilters(lensConfig.initialFilters),
|
|
8019
|
+
[lensConfig.initialFilters]
|
|
8020
|
+
);
|
|
7774
8021
|
const selectedNodeId = useCommandViewStore((s) => s.selectedNodeId);
|
|
7775
|
-
const
|
|
7776
|
-
const
|
|
7777
|
-
const
|
|
7778
|
-
const
|
|
7779
|
-
const
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
updateFilters({
|
|
7783
|
-
domainFilters: {
|
|
7784
|
-
...domainFilters,
|
|
7785
|
-
[domainId]: nextState
|
|
7786
|
-
}
|
|
7787
|
-
});
|
|
7788
|
-
};
|
|
8022
|
+
const resourcesHidden = useCommandViewStore((s) => s.resourcesHidden);
|
|
8023
|
+
const setResourcesHidden = useCommandViewStore((s) => s.setResourcesHidden);
|
|
8024
|
+
const diagnosticsHidden = useCommandViewStore((s) => s.diagnosticsHidden);
|
|
8025
|
+
const setDiagnosticsHidden = useCommandViewStore((s) => s.setDiagnosticsHidden);
|
|
8026
|
+
const diagnosticCategories = useCommandViewStore((s) => s.diagnosticCategories);
|
|
8027
|
+
const revealedIds = useCommandViewStore((s) => s.revealedIds);
|
|
8028
|
+
const clearRevealedIds = useCommandViewStore((s) => s.clearRevealedIds);
|
|
7789
8029
|
const { data, isLoading } = useCommandViewData();
|
|
7790
8030
|
const { data: statsData } = useCommandViewStats(timeRange);
|
|
7791
8031
|
const cleanData = data ?? null;
|
|
@@ -7794,30 +8034,85 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7794
8034
|
if (!statsData) return cleanData;
|
|
7795
8035
|
return mergeStatsWithTopology(cleanData, statsData);
|
|
7796
8036
|
}, [cleanData, statsData]);
|
|
8037
|
+
const baseGraph = useMemo(() => {
|
|
8038
|
+
if (!organizationModel) {
|
|
8039
|
+
return null;
|
|
8040
|
+
}
|
|
8041
|
+
return buildOrganizationGraph({
|
|
8042
|
+
organizationModel,
|
|
8043
|
+
commandViewData: cleanData ?? void 0
|
|
8044
|
+
});
|
|
8045
|
+
}, [cleanData, organizationModel]);
|
|
8046
|
+
const graph = useMemo(() => {
|
|
8047
|
+
if (!baseGraph) {
|
|
8048
|
+
return null;
|
|
8049
|
+
}
|
|
8050
|
+
return filterOrganizationGraph(baseGraph, filters, {
|
|
8051
|
+
commandViewData: cleanData
|
|
8052
|
+
});
|
|
8053
|
+
}, [baseGraph, cleanData, filters]);
|
|
8054
|
+
const visibilityProjection = useMemo(() => {
|
|
8055
|
+
if (!graph) {
|
|
8056
|
+
return {
|
|
8057
|
+
hiddenIds: /* @__PURE__ */ new Set(),
|
|
8058
|
+
hiddenEdgeIds: /* @__PURE__ */ new Set(),
|
|
8059
|
+
totalResourceCount: 0,
|
|
8060
|
+
visibleResourceCount: 0,
|
|
8061
|
+
hiddenResourceCount: 0,
|
|
8062
|
+
hiddenDiagnosticResourceCount: 0
|
|
8063
|
+
};
|
|
8064
|
+
}
|
|
8065
|
+
return getCommandViewVisibilityProjection({
|
|
8066
|
+
graph,
|
|
8067
|
+
commandViewData: cleanData,
|
|
8068
|
+
resourcesHidden,
|
|
8069
|
+
diagnosticsHidden,
|
|
8070
|
+
diagnosticCategories,
|
|
8071
|
+
revealedIds,
|
|
8072
|
+
mode: "map"
|
|
8073
|
+
});
|
|
8074
|
+
}, [cleanData, diagnosticCategories, diagnosticsHidden, graph, resourcesHidden, revealedIds]);
|
|
8075
|
+
const visibleGraph = useMemo(() => {
|
|
8076
|
+
if (!graph || visibilityProjection.hiddenIds.size === 0) {
|
|
8077
|
+
return graph;
|
|
8078
|
+
}
|
|
8079
|
+
return {
|
|
8080
|
+
...graph,
|
|
8081
|
+
nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
|
|
8082
|
+
edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
|
|
8083
|
+
};
|
|
8084
|
+
}, [graph, visibilityProjection]);
|
|
8085
|
+
const handleResetFilters = () => {
|
|
8086
|
+
resetFilters();
|
|
8087
|
+
clearRevealedIds();
|
|
8088
|
+
};
|
|
8089
|
+
const handleResourcesHiddenChange = (value) => {
|
|
8090
|
+
setResourcesHidden(value);
|
|
8091
|
+
if (value) {
|
|
8092
|
+
clearRevealedIds();
|
|
8093
|
+
}
|
|
8094
|
+
};
|
|
8095
|
+
const handleDiagnosticsHiddenChange = (value) => {
|
|
8096
|
+
setDiagnosticsHidden(value);
|
|
8097
|
+
if (value) {
|
|
8098
|
+
clearRevealedIds();
|
|
8099
|
+
}
|
|
8100
|
+
};
|
|
8101
|
+
const revealAllResources = () => {
|
|
8102
|
+
setResourcesHidden(false);
|
|
8103
|
+
setDiagnosticsHidden(false);
|
|
8104
|
+
clearRevealedIds();
|
|
8105
|
+
};
|
|
7797
8106
|
const { donutSuccessCount, donutFailedCount } = useMemo(() => {
|
|
7798
8107
|
if (!cleanData || !statsData) return { donutSuccessCount: 0, donutFailedCount: 0 };
|
|
7799
|
-
const includes = Object.entries(domainFilters).filter(([, v]) => v === "include").map(([k]) => k);
|
|
7800
|
-
const excludes = Object.entries(domainFilters).filter(([, v]) => v === "exclude").map(([k]) => k);
|
|
7801
8108
|
const allResources = [
|
|
7802
8109
|
...cleanData.agents,
|
|
7803
8110
|
...cleanData.workflows,
|
|
7804
8111
|
...cleanData.triggers,
|
|
7805
|
-
...
|
|
8112
|
+
...cleanData.integrations,
|
|
7806
8113
|
...cleanData.externalResources ?? [],
|
|
7807
8114
|
...cleanData.humanCheckpoints ?? []
|
|
7808
|
-
]
|
|
7809
|
-
const domains = resource.domains || [];
|
|
7810
|
-
if (excludes.length > 0 && domains.some((d) => excludes.includes(d))) return false;
|
|
7811
|
-
if (includes.length > 0 && !domains.some((d) => includes.includes(d))) return false;
|
|
7812
|
-
if (statusFilter !== "all" && resource.status !== statusFilter) return false;
|
|
7813
|
-
if (filters.resourceTypes.length > 0) {
|
|
7814
|
-
const normalizedResourceType = resource.type === "human" ? "human_checkpoint" : resource.type;
|
|
7815
|
-
if (!filters.resourceTypes.includes(normalizedResourceType)) {
|
|
7816
|
-
return false;
|
|
7817
|
-
}
|
|
7818
|
-
}
|
|
7819
|
-
return true;
|
|
7820
|
-
});
|
|
8115
|
+
];
|
|
7821
8116
|
const filteredIds = new Set(allResources.map((resource) => resource.resourceId));
|
|
7822
8117
|
let success = 0;
|
|
7823
8118
|
let failed = 0;
|
|
@@ -7828,8 +8123,7 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7828
8123
|
}
|
|
7829
8124
|
}
|
|
7830
8125
|
return { donutSuccessCount: success, donutFailedCount: failed };
|
|
7831
|
-
}, [cleanData,
|
|
7832
|
-
const domainDefinitions = cleanData?.domainDefinitions ?? [];
|
|
8126
|
+
}, [cleanData, statsData]);
|
|
7833
8127
|
const selectedNode = useMemo(() => {
|
|
7834
8128
|
if (!selectedNodeId || !dataWithStats) return null;
|
|
7835
8129
|
const allNodes = [
|
|
@@ -7893,17 +8187,18 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7893
8187
|
if (isLoading && !data) {
|
|
7894
8188
|
return /* @__PURE__ */ jsx(SubshellSidebarLoader, {});
|
|
7895
8189
|
}
|
|
7896
|
-
return /* @__PURE__ */
|
|
8190
|
+
return /* @__PURE__ */ jsx(
|
|
7897
8191
|
Box,
|
|
7898
8192
|
{
|
|
7899
8193
|
style: {
|
|
7900
8194
|
flex: 1,
|
|
8195
|
+
height: "100%",
|
|
7901
8196
|
minHeight: 0,
|
|
7902
8197
|
display: "flex",
|
|
7903
8198
|
flexDirection: "column",
|
|
7904
8199
|
overflow: "hidden"
|
|
7905
8200
|
},
|
|
7906
|
-
children: [
|
|
8201
|
+
children: /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", overflowX: "hidden" }, children: [
|
|
7907
8202
|
/* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconSitemap, label: "Command View" }),
|
|
7908
8203
|
/* @__PURE__ */ jsx(Box, { style: { padding: theme.spacing.sm, paddingBottom: 0 }, children: /* @__PURE__ */ jsx(Box, { pb: "xs", mb: 4, children: /* @__PURE__ */ jsx(
|
|
7909
8204
|
CyberDonut,
|
|
@@ -7917,171 +8212,105 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7917
8212
|
colors
|
|
7918
8213
|
}
|
|
7919
8214
|
) }) }),
|
|
7920
|
-
/* @__PURE__ */
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
checked: showIntegrations,
|
|
7949
|
-
onChange: (event) => updateFilters({
|
|
7950
|
-
showIntegrations: event.currentTarget.checked
|
|
7951
|
-
}),
|
|
7952
|
-
size: "sm"
|
|
7953
|
-
}
|
|
7954
|
-
),
|
|
7955
|
-
domainDefinitions.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
7956
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", mb: 8, children: "Domain" }),
|
|
7957
|
-
/* @__PURE__ */ jsx(Stack, { gap: 2, children: [...domainDefinitions].sort((a, b) => {
|
|
7958
|
-
const bottom = /* @__PURE__ */ new Set(["utility", "diagnostic"]);
|
|
7959
|
-
const aB = bottom.has(a.id) ? 1 : 0;
|
|
7960
|
-
const bB = bottom.has(b.id) ? 1 : 0;
|
|
7961
|
-
if (aB !== bB) return aB - bB;
|
|
7962
|
-
return a.name.localeCompare(b.name);
|
|
7963
|
-
}).map((domain) => {
|
|
7964
|
-
const filterState = domainFilters[domain.id] || "neutral";
|
|
7965
|
-
const StateIcon = FILTER_STATE_ICONS2[filterState];
|
|
7966
|
-
return /* @__PURE__ */ jsx(
|
|
7967
|
-
UnstyledButton,
|
|
7968
|
-
{
|
|
7969
|
-
title: FILTER_STATE_LABELS2[filterState],
|
|
7970
|
-
onClick: () => cycleDomainFilter(domain.id),
|
|
7971
|
-
py: 5,
|
|
7972
|
-
px: 6,
|
|
7973
|
-
style: {
|
|
7974
|
-
transition: "background-color var(--duration-fast) var(--easing)",
|
|
7975
|
-
"&:hover": { backgroundColor: "var(--color-surface-hover)" }
|
|
7976
|
-
},
|
|
7977
|
-
children: /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", children: [
|
|
7978
|
-
/* @__PURE__ */ jsx(
|
|
7979
|
-
StateIcon,
|
|
7980
|
-
{
|
|
7981
|
-
size: 16,
|
|
7982
|
-
style: {
|
|
7983
|
-
color: FILTER_STATE_COLORS2[filterState],
|
|
7984
|
-
flexShrink: 0,
|
|
7985
|
-
transition: "color var(--duration-fast) var(--easing)"
|
|
7986
|
-
}
|
|
7987
|
-
}
|
|
7988
|
-
),
|
|
7989
|
-
/* @__PURE__ */ jsx(
|
|
7990
|
-
Text,
|
|
7991
|
-
{
|
|
7992
|
-
size: "sm",
|
|
7993
|
-
truncate: true,
|
|
7994
|
-
fw: filterState !== "neutral" ? 500 : 400,
|
|
7995
|
-
c: filterState !== "neutral" ? void 0 : "dimmed",
|
|
7996
|
-
children: domain.name
|
|
7997
|
-
}
|
|
7998
|
-
)
|
|
7999
|
-
] })
|
|
8000
|
-
},
|
|
8001
|
-
domain.id
|
|
8002
|
-
);
|
|
8003
|
-
}) })
|
|
8004
|
-
] })
|
|
8005
|
-
] }),
|
|
8006
|
-
selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8007
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
8008
|
-
/* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
|
|
8009
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
|
|
8010
|
-
selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
|
|
8011
|
-
(isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
|
|
8012
|
-
Button,
|
|
8013
|
-
{
|
|
8014
|
-
component: "a",
|
|
8015
|
-
href: getNavigationUrl() || "#",
|
|
8016
|
-
target: "_blank",
|
|
8017
|
-
rel: "noopener noreferrer",
|
|
8018
|
-
variant: "light",
|
|
8019
|
-
size: "xs",
|
|
8020
|
-
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
|
|
8021
|
-
mt: 4,
|
|
8022
|
-
children: [
|
|
8023
|
-
"Go to",
|
|
8024
|
-
" ",
|
|
8025
|
-
selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
|
|
8026
|
-
]
|
|
8027
|
-
}
|
|
8028
|
-
),
|
|
8029
|
-
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
8030
|
-
] })
|
|
8031
|
-
] }),
|
|
8032
|
-
selectedNode && isNavigable && /* @__PURE__ */ jsx(Stack, { p: "sm", children: executionsLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : executionsError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: executionsError, title: "Failed to load executions" }) : executionsData && executionsData.executions.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8033
|
-
EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
|
|
8034
|
-
ExecutionStatusSection,
|
|
8035
|
-
{
|
|
8036
|
-
executions: executionsData.executions,
|
|
8037
|
-
status: section.status,
|
|
8038
|
-
title: section.title,
|
|
8039
|
-
badgeColor: section.badgeColor,
|
|
8040
|
-
resourceUrl
|
|
8041
|
-
},
|
|
8042
|
-
section.status
|
|
8043
|
-
)),
|
|
8044
|
-
totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
8045
|
-
Pagination,
|
|
8046
|
-
{
|
|
8047
|
-
size: "sm",
|
|
8048
|
-
total: totalExecutionPages(executionsData.totalExecutions),
|
|
8049
|
-
value: executionPage,
|
|
8050
|
-
onChange: setExecutionPage,
|
|
8051
|
-
boundaries: 1
|
|
8052
|
-
}
|
|
8053
|
-
) })
|
|
8054
|
-
] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
|
|
8055
|
-
selectedNode && isHumanCheckpoint && /* @__PURE__ */ jsx(Stack, { p: "sm", children: checkpointTasksLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : checkpointTasksError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: checkpointTasksError, title: "Failed to load pending tasks" }) : checkpointTasksData && checkpointTasksData.tasks.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
8056
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
8057
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
|
|
8058
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
|
|
8059
|
-
] }),
|
|
8060
|
-
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
8061
|
-
Card,
|
|
8215
|
+
/* @__PURE__ */ jsx(Box, { p: "sm", children: /* @__PURE__ */ jsx(
|
|
8216
|
+
FilterPanel,
|
|
8217
|
+
{
|
|
8218
|
+
filters,
|
|
8219
|
+
onChangeFilters: updateFilters,
|
|
8220
|
+
resetValue: toolbarResetValue,
|
|
8221
|
+
disabled: !baseGraph,
|
|
8222
|
+
commandViewData: cleanData,
|
|
8223
|
+
lens: "command-view",
|
|
8224
|
+
resourcesHidden,
|
|
8225
|
+
diagnosticsHidden,
|
|
8226
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
8227
|
+
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
8228
|
+
onRevealResources: revealAllResources,
|
|
8229
|
+
onResetFilters: handleResetFilters,
|
|
8230
|
+
visibilityCounts: visibilityProjection,
|
|
8231
|
+
graph: visibleGraph,
|
|
8232
|
+
baseGraph,
|
|
8233
|
+
layout: "stack"
|
|
8234
|
+
}
|
|
8235
|
+
) }),
|
|
8236
|
+
selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8237
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
8238
|
+
/* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
|
|
8239
|
+
/* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
|
|
8240
|
+
selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
|
|
8241
|
+
(isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
|
|
8242
|
+
Button,
|
|
8062
8243
|
{
|
|
8063
|
-
padding: "xs",
|
|
8064
|
-
withBorder: true,
|
|
8065
8244
|
component: "a",
|
|
8066
|
-
href:
|
|
8245
|
+
href: getNavigationUrl() || "#",
|
|
8067
8246
|
target: "_blank",
|
|
8068
8247
|
rel: "noopener noreferrer",
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8248
|
+
variant: "light",
|
|
8249
|
+
size: "xs",
|
|
8250
|
+
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
|
|
8251
|
+
mt: 4,
|
|
8072
8252
|
children: [
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
] }),
|
|
8077
|
-
task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
|
|
8253
|
+
"Go to",
|
|
8254
|
+
" ",
|
|
8255
|
+
selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
|
|
8078
8256
|
]
|
|
8079
|
-
}
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
] })
|
|
8083
|
-
] })
|
|
8084
|
-
|
|
8257
|
+
}
|
|
8258
|
+
),
|
|
8259
|
+
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
8260
|
+
] })
|
|
8261
|
+
] }),
|
|
8262
|
+
selectedNode && isNavigable && /* @__PURE__ */ jsx(Stack, { p: "sm", children: executionsLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : executionsError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: executionsError, title: "Failed to load executions" }) : executionsData && executionsData.executions.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8263
|
+
EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
|
|
8264
|
+
ExecutionStatusSection,
|
|
8265
|
+
{
|
|
8266
|
+
executions: executionsData.executions,
|
|
8267
|
+
status: section.status,
|
|
8268
|
+
title: section.title,
|
|
8269
|
+
badgeColor: section.badgeColor,
|
|
8270
|
+
resourceUrl
|
|
8271
|
+
},
|
|
8272
|
+
section.status
|
|
8273
|
+
)),
|
|
8274
|
+
totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
8275
|
+
Pagination,
|
|
8276
|
+
{
|
|
8277
|
+
size: "sm",
|
|
8278
|
+
total: totalExecutionPages(executionsData.totalExecutions),
|
|
8279
|
+
value: executionPage,
|
|
8280
|
+
onChange: setExecutionPage,
|
|
8281
|
+
boundaries: 1
|
|
8282
|
+
}
|
|
8283
|
+
) })
|
|
8284
|
+
] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
|
|
8285
|
+
selectedNode && isHumanCheckpoint && /* @__PURE__ */ jsx(Stack, { p: "sm", children: checkpointTasksLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : checkpointTasksError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: checkpointTasksError, title: "Failed to load pending tasks" }) : checkpointTasksData && checkpointTasksData.tasks.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
8286
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
8287
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
|
|
8288
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
|
|
8289
|
+
] }),
|
|
8290
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
8291
|
+
Card,
|
|
8292
|
+
{
|
|
8293
|
+
padding: "xs",
|
|
8294
|
+
withBorder: true,
|
|
8295
|
+
component: "a",
|
|
8296
|
+
href: `/operations/command-queue?task=${task.id}`,
|
|
8297
|
+
target: "_blank",
|
|
8298
|
+
rel: "noopener noreferrer",
|
|
8299
|
+
style: HOVER_CARD_STYLE,
|
|
8300
|
+
onMouseEnter: handleHoverEnter,
|
|
8301
|
+
onMouseLeave: handleHoverLeave,
|
|
8302
|
+
children: [
|
|
8303
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: task.description ? 4 : 0, children: [
|
|
8304
|
+
/* @__PURE__ */ jsx(Badge, { size: "xs", color: "orange", variant: "light", children: "pending" }),
|
|
8305
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(task.createdAt) })
|
|
8306
|
+
] }),
|
|
8307
|
+
task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
|
|
8308
|
+
]
|
|
8309
|
+
},
|
|
8310
|
+
task.id
|
|
8311
|
+
)) })
|
|
8312
|
+
] }) : checkpointTasksData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending tasks" }) : null })
|
|
8313
|
+
] })
|
|
8085
8314
|
}
|
|
8086
8315
|
);
|
|
8087
8316
|
}
|
|
@@ -9391,28 +9620,15 @@ var OperationsSidebar = () => {
|
|
|
9391
9620
|
function CommandQueueShell({ children }) {
|
|
9392
9621
|
return /* @__PURE__ */ jsx(SubshellContentContainer, { children });
|
|
9393
9622
|
}
|
|
9623
|
+
var commandViewSidebarWidth = 320;
|
|
9624
|
+
var defaultOperationsSidebarWidth = 250;
|
|
9394
9625
|
var operationsManifest = {
|
|
9395
9626
|
key: "operations",
|
|
9396
9627
|
featureId: "operations",
|
|
9397
|
-
capabilityIds: ["operations.
|
|
9628
|
+
capabilityIds: ["operations.command-view"],
|
|
9629
|
+
icon: IconCode,
|
|
9398
9630
|
sidebar: OperationsSidebar,
|
|
9399
|
-
|
|
9400
|
-
organizationGraph: {
|
|
9401
|
-
surfaceId: "operations.organization-graph"
|
|
9402
|
-
},
|
|
9403
|
-
navEntry: {
|
|
9404
|
-
label: "Operations",
|
|
9405
|
-
icon: IconCode,
|
|
9406
|
-
dataOnboardingTourId: "sidebar-operations",
|
|
9407
|
-
links: [
|
|
9408
|
-
{ label: "Overview", link: "/operations" },
|
|
9409
|
-
{ label: "Resources", link: "/operations/resources" },
|
|
9410
|
-
{ label: "Command View", link: "/operations/command-view" },
|
|
9411
|
-
{ label: "Command Queue", link: "/operations/command-queue" },
|
|
9412
|
-
{ label: "Sessions", link: "/operations/sessions" },
|
|
9413
|
-
{ label: "Task Scheduler", link: "/operations/task-scheduler" }
|
|
9414
|
-
]
|
|
9415
|
-
}
|
|
9631
|
+
sidebarWidth: ({ currentPath }) => currentPath.startsWith("/operations/command-view") ? commandViewSidebarWidth : defaultOperationsSidebarWidth
|
|
9416
9632
|
};
|
|
9417
9633
|
|
|
9418
9634
|
export { ActionModal, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionPanel, AgentSessionGroup, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, CheckpointGroup, CollapsibleJsonSection, CommandQueueDetailPage, CommandQueuePage, CommandQueueShell, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewPage, CommandViewSidebarContent, ConfigCard, ContentSections, ContextUsageBadge, ContractDisplay, ExecuteWorkflowModal, ExecutionErrorSection, ExecutionPanel, LogEntry, LogGroup, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, OperationsSidebar, OperationsSidebarMiddle, OperationsSidebarTop, OrganizationGraphPage, ResourceDefinitionSection, ResourceDetailPage, ResourceErrorState, ResourceExecuteDialog, ResourceExecuteForm, ResourceFilter, ResourceHeader, ResourceNotFoundState, ResourcesPage, ResourcesSidebar, SessionChatArea, SessionChatInterface, SessionChatPage, SessionDetailsSidebar, SessionExecutionLogs, SessionHeader, SessionListItem, SessionMemory, SessionsPage, SessionsSidebar, ToolsListDisplay, WorkflowDefinitionDisplay, WorkflowExecutionLogs, WorkflowExecutionPanel, getExecutionStatusConfig, getIcon, getLogLevelConfig, iconMap, operationsManifest, useNewKnowledgeMapLayout };
|