@elevasis/ui 2.21.0 → 2.23.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/app/index.js +2 -2
- package/dist/{chunk-DMYELNGA.js → chunk-3HEUGBOT.js} +1 -1
- package/dist/{chunk-EGKNRM6P.js → chunk-7PGEGSUM.js} +2 -2
- package/dist/{chunk-KVW56ERD.js → chunk-AXXTN44Z.js} +5 -3
- package/dist/{chunk-I5WRKH25.js → chunk-D3KQAABP.js} +1 -1
- package/dist/{chunk-S7RL77QS.js → chunk-DDZOHLHB.js} +1 -1
- package/dist/{chunk-EDX6WIN3.js → chunk-EPV7NU2E.js} +24 -10
- package/dist/{chunk-ATEHYDL3.js → chunk-FXWETLEB.js} +6 -2
- package/dist/{chunk-7GG6OSD7.js → chunk-GUJUK6EH.js} +2830 -2381
- package/dist/{chunk-GBMNCNHX.js → chunk-KVJ3LFH2.js} +3 -1
- package/dist/{chunk-VQESMHQV.js → chunk-LJWV4TWV.js} +1 -2
- package/dist/{chunk-BJWIKEQG.js → chunk-N6WLOWOD.js} +6 -14
- package/dist/{chunk-XLZZOFGM.js → chunk-PTUOINQ2.js} +275 -76
- package/dist/{chunk-CZK67OHH.js → chunk-PXGSJNBH.js} +3 -3
- package/dist/{chunk-TIIPYB2Z.js → chunk-QZJM3RYI.js} +1 -1
- package/dist/{chunk-7YQKVWSD.js → chunk-SQ5JGELM.js} +25 -5
- package/dist/{chunk-RX4UWZZR.js → chunk-TKAYX2SP.js} +8 -3
- package/dist/{chunk-Q5HC6ENG.js → chunk-XOTJNW4Q.js} +1 -1
- package/dist/{chunk-LQU62KHD.js → chunk-YU6MBDVO.js} +1993 -870
- package/dist/{chunk-ULZ2B3NC.js → chunk-ZBCTB5CA.js} +1 -1
- package/dist/components/index.css +85 -85
- package/dist/components/index.d.ts +1651 -1388
- package/dist/components/index.js +253 -40
- package/dist/components/navigation/index.css +589 -0
- package/dist/components/navigation/index.js +3 -3
- package/dist/features/auth/index.css +2 -2
- package/dist/features/auth/index.d.ts +188 -10
- package/dist/features/crm/index.css +2 -2
- package/dist/features/crm/index.d.ts +193 -10
- package/dist/features/crm/index.js +10 -10
- package/dist/features/dashboard/index.css +2 -2
- package/dist/features/dashboard/index.js +9 -9
- package/dist/features/delivery/index.css +85 -85
- package/dist/features/delivery/index.d.ts +193 -10
- package/dist/features/delivery/index.js +10 -10
- package/dist/features/lead-gen/index.css +2 -2
- package/dist/features/lead-gen/index.d.ts +5 -0
- package/dist/features/lead-gen/index.js +10 -10
- package/dist/features/monitoring/index.css +85 -85
- package/dist/features/monitoring/index.d.ts +6 -1
- package/dist/features/monitoring/index.js +11 -11
- package/dist/features/monitoring/requests/index.css +2 -2
- package/dist/features/monitoring/requests/index.d.ts +5 -0
- package/dist/features/monitoring/requests/index.js +9 -9
- package/dist/features/operations/index.css +2 -2
- package/dist/features/operations/index.d.ts +7 -4
- package/dist/features/operations/index.js +12 -12
- package/dist/features/seo/index.d.ts +5 -0
- package/dist/features/settings/index.css +2 -2
- package/dist/features/settings/index.d.ts +214 -16
- package/dist/features/settings/index.js +11 -11
- package/dist/graph/index.css +2 -2
- package/dist/hooks/delivery/index.css +2 -2
- package/dist/hooks/delivery/index.d.ts +188 -10
- package/dist/hooks/index.css +85 -85
- package/dist/hooks/index.d.ts +1843 -1538
- package/dist/hooks/index.js +8 -8
- package/dist/hooks/published.css +85 -85
- package/dist/hooks/published.d.ts +1843 -1538
- package/dist/hooks/published.js +8 -8
- package/dist/index.css +12 -12
- package/dist/index.d.ts +346 -35
- package/dist/index.js +9 -9
- package/dist/initialization/index.d.ts +188 -10
- 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 +188 -10
- package/dist/provider/index.css +384 -0
- package/dist/provider/index.d.ts +6 -0
- package/dist/provider/index.js +7 -7
- package/dist/provider/published.css +463 -0
- package/dist/provider/published.d.ts +6 -0
- package/dist/provider/published.js +4 -4
- package/dist/supabase/index.d.ts +367 -20
- package/dist/test-utils/index.d.ts +46 -2
- package/dist/test-utils/index.js +102 -1
- package/dist/theme/index.js +2 -2
- package/dist/types/index.d.ts +199 -13
- package/package.json +4 -4
- /package/dist/{chunk-6GUW5GGF.js → chunk-6Z3G4U2R.js} +0 -0
|
@@ -1,19 +1,19 @@
|
|
|
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-
|
|
3
|
+
import { BaseNode, useGraphTheme, BaseEdge, FormFieldRenderer, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-7PGEGSUM.js';
|
|
4
|
+
import { ResourceHealthPanel } from './chunk-D3KQAABP.js';
|
|
5
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, collectResourceFilterFacets, useExecuteAsync, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions } 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-GUJUK6EH.js';
|
|
12
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-
|
|
15
|
+
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-LJWV4TWV.js';
|
|
16
|
+
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
17
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';
|
|
@@ -25,7 +25,7 @@ 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, NumberInput, 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';
|
|
@@ -84,7 +84,22 @@ 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,21 +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 NodeIdPathSchema = z.string().trim().min(1).max(100).regex(/^([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node IDs must be lowercase dotted paths");
|
|
131
|
-
z.string().trim().min(1).max(200).regex(/^[a-z]+:([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node references must use kind:dotted-path");
|
|
132
|
-
var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]);
|
|
133
|
-
var FeatureSchema = z.object({
|
|
134
|
-
id: NodeIdPathSchema,
|
|
135
|
-
label: LabelSchema,
|
|
136
|
-
description: DescriptionSchema.optional(),
|
|
137
|
-
enabled: z.boolean().default(true),
|
|
138
|
-
path: PathSchema.optional(),
|
|
139
|
-
icon: IconNameSchema.optional(),
|
|
140
|
-
color: ColorTokenSchema.optional(),
|
|
141
|
-
uiPosition: UiPositionSchema.optional(),
|
|
142
|
-
requiresAdmin: z.boolean().optional(),
|
|
143
|
-
devOnly: z.boolean().optional()
|
|
144
|
-
});
|
|
145
145
|
var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
|
|
146
146
|
id: ModelIdSchema,
|
|
147
147
|
order: z.number().int().min(0)
|
|
@@ -162,6 +162,7 @@ var SurfaceDefinitionSchema = z.object({
|
|
|
162
162
|
surfaceType: SurfaceTypeSchema,
|
|
163
163
|
description: DescriptionSchema.optional(),
|
|
164
164
|
enabled: z.boolean().default(true),
|
|
165
|
+
devOnly: z.boolean().optional(),
|
|
165
166
|
icon: IconNameSchema.optional(),
|
|
166
167
|
featureId: ModelIdSchema.optional(),
|
|
167
168
|
featureIds: ReferenceIdsSchema,
|
|
@@ -562,6 +563,8 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
562
563
|
}
|
|
563
564
|
});
|
|
564
565
|
});
|
|
566
|
+
|
|
567
|
+
// ../core/src/organization-model/graph/schema.ts
|
|
565
568
|
var OrganizationGraphNodeKindSchema = z.enum([
|
|
566
569
|
"organization",
|
|
567
570
|
"feature",
|
|
@@ -4681,7 +4684,7 @@ function titleCase2(value) {
|
|
|
4681
4684
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
4682
4685
|
}
|
|
4683
4686
|
function MetricCard({ metric }) {
|
|
4684
|
-
return /* @__PURE__ */ jsx(
|
|
4687
|
+
return /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4685
4688
|
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: metric.label }),
|
|
4686
4689
|
/* @__PURE__ */ jsx(Text, { size: "lg", fw: 800, children: metric.value }),
|
|
4687
4690
|
metric.hint ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: metric.hint }) : null
|
|
@@ -4766,6 +4769,7 @@ function OrganizationGraphDetailPanel({
|
|
|
4766
4769
|
selectedElement,
|
|
4767
4770
|
supplementalSummary,
|
|
4768
4771
|
followUpSections,
|
|
4772
|
+
expandAroundPanel,
|
|
4769
4773
|
onClearSelection,
|
|
4770
4774
|
className
|
|
4771
4775
|
}) {
|
|
@@ -4803,6 +4807,7 @@ function OrganizationGraphDetailPanel({
|
|
|
4803
4807
|
onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
|
|
4804
4808
|
] }),
|
|
4805
4809
|
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: state.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, metric.label)) }),
|
|
4810
|
+
expandAroundPanel,
|
|
4806
4811
|
supplementalSummary && (supplementalSummary.metrics.length > 0 || supplementalSummary.metadata.length > 0) ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4807
4812
|
/* @__PURE__ */ jsx(
|
|
4808
4813
|
Divider,
|
|
@@ -5211,6 +5216,83 @@ function filterOrganizationGraph(graph, filters, options) {
|
|
|
5211
5216
|
edges: visibleEdges
|
|
5212
5217
|
};
|
|
5213
5218
|
}
|
|
5219
|
+
function getCommandViewResourceCategory(node, commandViewData) {
|
|
5220
|
+
return getCommandViewNodeForGraphNode(node, commandViewData)?.category ?? null;
|
|
5221
|
+
}
|
|
5222
|
+
function getConnectedHiddenResourceIds(graph, nodeId2, hiddenIds) {
|
|
5223
|
+
if (!nodeId2) {
|
|
5224
|
+
return /* @__PURE__ */ new Set();
|
|
5225
|
+
}
|
|
5226
|
+
const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
5227
|
+
const connectedIds = /* @__PURE__ */ new Set();
|
|
5228
|
+
for (const edge of graph.edges) {
|
|
5229
|
+
const neighborId = edge.sourceId === nodeId2 ? edge.targetId : edge.targetId === nodeId2 ? edge.sourceId : null;
|
|
5230
|
+
if (!neighborId || !hiddenIds.has(neighborId)) {
|
|
5231
|
+
continue;
|
|
5232
|
+
}
|
|
5233
|
+
if (nodesById.get(neighborId)?.kind === "resource") {
|
|
5234
|
+
connectedIds.add(neighborId);
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
return connectedIds;
|
|
5238
|
+
}
|
|
5239
|
+
function getCommandViewVisibilityProjection({
|
|
5240
|
+
graph,
|
|
5241
|
+
commandViewData,
|
|
5242
|
+
resourcesHidden,
|
|
5243
|
+
diagnosticsHidden,
|
|
5244
|
+
diagnosticCategories,
|
|
5245
|
+
revealedIds = /* @__PURE__ */ new Set(),
|
|
5246
|
+
mode
|
|
5247
|
+
}) {
|
|
5248
|
+
const hiddenIds = /* @__PURE__ */ new Set();
|
|
5249
|
+
const hiddenEdgeIds = /* @__PURE__ */ new Set();
|
|
5250
|
+
const diagnosticCategorySet = new Set(diagnosticCategories);
|
|
5251
|
+
let totalResourceCount = 0;
|
|
5252
|
+
let hiddenDiagnosticResourceCount = 0;
|
|
5253
|
+
if (mode === "trace" || mode === "impact") {
|
|
5254
|
+
const resourceCount = graph.nodes.filter((node) => node.kind === "resource").length;
|
|
5255
|
+
return {
|
|
5256
|
+
hiddenIds,
|
|
5257
|
+
hiddenEdgeIds,
|
|
5258
|
+
totalResourceCount: resourceCount,
|
|
5259
|
+
visibleResourceCount: resourceCount,
|
|
5260
|
+
hiddenResourceCount: 0,
|
|
5261
|
+
hiddenDiagnosticResourceCount: 0
|
|
5262
|
+
};
|
|
5263
|
+
}
|
|
5264
|
+
for (const node of graph.nodes) {
|
|
5265
|
+
if (node.kind !== "resource") {
|
|
5266
|
+
continue;
|
|
5267
|
+
}
|
|
5268
|
+
totalResourceCount += 1;
|
|
5269
|
+
const category = getCommandViewResourceCategory(node, commandViewData);
|
|
5270
|
+
const isDiagnostic = Boolean(category && diagnosticCategorySet.has(category));
|
|
5271
|
+
if (isDiagnostic && diagnosticsHidden) {
|
|
5272
|
+
hiddenDiagnosticResourceCount += 1;
|
|
5273
|
+
}
|
|
5274
|
+
if (revealedIds.has(node.id)) {
|
|
5275
|
+
continue;
|
|
5276
|
+
}
|
|
5277
|
+
if (resourcesHidden || diagnosticsHidden && isDiagnostic) {
|
|
5278
|
+
hiddenIds.add(node.id);
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
for (const edge of graph.edges) {
|
|
5282
|
+
if (hiddenIds.has(edge.sourceId) || hiddenIds.has(edge.targetId)) {
|
|
5283
|
+
hiddenEdgeIds.add(edge.id);
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
const hiddenResourceCount = hiddenIds.size;
|
|
5287
|
+
return {
|
|
5288
|
+
hiddenIds,
|
|
5289
|
+
hiddenEdgeIds,
|
|
5290
|
+
totalResourceCount,
|
|
5291
|
+
visibleResourceCount: totalResourceCount - hiddenResourceCount,
|
|
5292
|
+
hiddenResourceCount,
|
|
5293
|
+
hiddenDiagnosticResourceCount
|
|
5294
|
+
};
|
|
5295
|
+
}
|
|
5214
5296
|
function isOrganizationGraphFilterPristine(filters) {
|
|
5215
5297
|
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);
|
|
5216
5298
|
}
|
|
@@ -5418,7 +5500,14 @@ function useOrganizationGraphFilters(initialFilters) {
|
|
|
5418
5500
|
}
|
|
5419
5501
|
|
|
5420
5502
|
// src/features/operations/organization-graph/lenses.ts
|
|
5421
|
-
var COMMAND_VIEW_NODE_KINDS = [
|
|
5503
|
+
var COMMAND_VIEW_NODE_KINDS = [
|
|
5504
|
+
"organization",
|
|
5505
|
+
"feature",
|
|
5506
|
+
"surface",
|
|
5507
|
+
"entity",
|
|
5508
|
+
"capability",
|
|
5509
|
+
"resource"
|
|
5510
|
+
];
|
|
5422
5511
|
function getOrganizationGraphLensConfig(lens) {
|
|
5423
5512
|
if (lens === "command-view") {
|
|
5424
5513
|
return {
|
|
@@ -5427,9 +5516,9 @@ function getOrganizationGraphLensConfig(lens) {
|
|
|
5427
5516
|
initialMode: "map",
|
|
5428
5517
|
initialFilters: {
|
|
5429
5518
|
nodeKinds: COMMAND_VIEW_NODE_KINDS,
|
|
5430
|
-
topologyPresence: "
|
|
5519
|
+
topologyPresence: "all"
|
|
5431
5520
|
},
|
|
5432
|
-
filterSummary: "Command View lens
|
|
5521
|
+
filterSummary: "Command View lens keeps the organization structure visible while resource visibility is controlled progressively."
|
|
5433
5522
|
};
|
|
5434
5523
|
}
|
|
5435
5524
|
return {
|
|
@@ -5746,221 +5835,6 @@ function buildCommandViewDrillDownSections({
|
|
|
5746
5835
|
}
|
|
5747
5836
|
return sections;
|
|
5748
5837
|
}
|
|
5749
|
-
var cellStyle = {
|
|
5750
|
-
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
5751
|
-
borderRight: "1px solid var(--color-border)",
|
|
5752
|
-
display: "flex",
|
|
5753
|
-
alignItems: "center",
|
|
5754
|
-
gap: "var(--mantine-spacing-sm)",
|
|
5755
|
-
minWidth: 0
|
|
5756
|
-
};
|
|
5757
|
-
var lastCellStyle = {
|
|
5758
|
-
...cellStyle,
|
|
5759
|
-
borderRight: "none"
|
|
5760
|
-
};
|
|
5761
|
-
function CommandViewHealthStrip({
|
|
5762
|
-
overview,
|
|
5763
|
-
hotspots,
|
|
5764
|
-
visibleResources,
|
|
5765
|
-
selectedLabel,
|
|
5766
|
-
onFocusHotspot,
|
|
5767
|
-
onResetFocus
|
|
5768
|
-
}) {
|
|
5769
|
-
return /* @__PURE__ */ jsxs(
|
|
5770
|
-
Paper,
|
|
5771
|
-
{
|
|
5772
|
-
withBorder: true,
|
|
5773
|
-
style: {
|
|
5774
|
-
display: "grid",
|
|
5775
|
-
gridTemplateColumns: "auto 1fr auto auto",
|
|
5776
|
-
background: "var(--color-surface)",
|
|
5777
|
-
boxShadow: "var(--card-shadow)",
|
|
5778
|
-
overflow: "hidden"
|
|
5779
|
-
},
|
|
5780
|
-
children: [
|
|
5781
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5782
|
-
/* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5783
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
|
|
5784
|
-
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
5785
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
|
|
5786
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
|
|
5787
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
|
|
5788
|
-
] }),
|
|
5789
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
|
|
5790
|
-
] }),
|
|
5791
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5792
|
-
/* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5793
|
-
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(
|
|
5794
|
-
Badge,
|
|
5795
|
-
{
|
|
5796
|
-
variant: "light",
|
|
5797
|
-
color: "red",
|
|
5798
|
-
size: "xs",
|
|
5799
|
-
style: { cursor: "pointer", flexShrink: 0 },
|
|
5800
|
-
onClick: () => onFocusHotspot(hotspot.resourceId),
|
|
5801
|
-
children: hotspot.label
|
|
5802
|
-
}
|
|
5803
|
-
) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
|
|
5804
|
-
] }),
|
|
5805
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5806
|
-
/* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5807
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
|
|
5808
|
-
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
|
|
5809
|
-
"pending / ",
|
|
5810
|
-
overview?.activeHumanCheckpoints ?? 0,
|
|
5811
|
-
" queues"
|
|
5812
|
-
] })
|
|
5813
|
-
] }),
|
|
5814
|
-
/* @__PURE__ */ jsxs("div", { style: lastCellStyle, children: [
|
|
5815
|
-
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5816
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} resources` }),
|
|
5817
|
-
/* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
|
|
5818
|
-
] })
|
|
5819
|
-
]
|
|
5820
|
-
}
|
|
5821
|
-
);
|
|
5822
|
-
}
|
|
5823
|
-
|
|
5824
|
-
// src/features/operations/organization-graph/commandViewGraphHealth.ts
|
|
5825
|
-
function toResourceHealth(node, stats) {
|
|
5826
|
-
const resourceId = node.sourceId ?? node.id;
|
|
5827
|
-
if (node.resourceType === "human_checkpoint") {
|
|
5828
|
-
const checkpointStats = stats.humanCheckpoints[resourceId];
|
|
5829
|
-
if (!checkpointStats) {
|
|
5830
|
-
return {
|
|
5831
|
-
nodeId: node.id,
|
|
5832
|
-
resourceId,
|
|
5833
|
-
label: node.label,
|
|
5834
|
-
resourceType: node.resourceType,
|
|
5835
|
-
healthLevel: "inactive",
|
|
5836
|
-
summaryLabel: "No queue activity",
|
|
5837
|
-
detailLabel: "No approvals in range",
|
|
5838
|
-
successRate: null,
|
|
5839
|
-
totalRuns: 0,
|
|
5840
|
-
successCount: 0,
|
|
5841
|
-
failureCount: 0,
|
|
5842
|
-
warningCount: 0,
|
|
5843
|
-
pendingCount: 0,
|
|
5844
|
-
completedCount: 0,
|
|
5845
|
-
expiredCount: 0,
|
|
5846
|
-
lastActivityAt: null,
|
|
5847
|
-
sortScore: 0
|
|
5848
|
-
};
|
|
5849
|
-
}
|
|
5850
|
-
const totalQueueActivity = checkpointStats.pendingCount + checkpointStats.completedCount + checkpointStats.expiredCount;
|
|
5851
|
-
const healthLevel2 = checkpointStats.pendingCount > 0 ? checkpointStats.pendingCount >= 3 || checkpointStats.expiredCount > 0 ? "critical" : "warning" : totalQueueActivity > 0 ? "healthy" : "inactive";
|
|
5852
|
-
const summaryLabel2 = checkpointStats.pendingCount > 0 ? `${checkpointStats.pendingCount} pending` : checkpointStats.expiredCount > 0 ? `${checkpointStats.expiredCount} expired` : checkpointStats.completedCount > 0 ? `${checkpointStats.completedCount} completed` : "No queue activity";
|
|
5853
|
-
const detailLabel = checkpointStats.pendingCount > 0 ? `${checkpointStats.completedCount} resolved` : totalQueueActivity > 0 ? "Queue clear" : "No approvals in range";
|
|
5854
|
-
return {
|
|
5855
|
-
nodeId: node.id,
|
|
5856
|
-
resourceId,
|
|
5857
|
-
label: node.label,
|
|
5858
|
-
resourceType: node.resourceType,
|
|
5859
|
-
healthLevel: healthLevel2,
|
|
5860
|
-
summaryLabel: summaryLabel2,
|
|
5861
|
-
detailLabel,
|
|
5862
|
-
successRate: null,
|
|
5863
|
-
totalRuns: 0,
|
|
5864
|
-
successCount: 0,
|
|
5865
|
-
failureCount: 0,
|
|
5866
|
-
warningCount: 0,
|
|
5867
|
-
pendingCount: checkpointStats.pendingCount,
|
|
5868
|
-
completedCount: checkpointStats.completedCount,
|
|
5869
|
-
expiredCount: checkpointStats.expiredCount,
|
|
5870
|
-
lastActivityAt: checkpointStats.lastDecisionAt,
|
|
5871
|
-
sortScore: checkpointStats.pendingCount * 100 + checkpointStats.expiredCount * 25 + checkpointStats.completedCount
|
|
5872
|
-
};
|
|
5873
|
-
}
|
|
5874
|
-
const resourceStats = stats.resources[resourceId];
|
|
5875
|
-
if (!resourceStats || resourceStats.totalRuns <= 0) {
|
|
5876
|
-
return {
|
|
5877
|
-
nodeId: node.id,
|
|
5878
|
-
resourceId,
|
|
5879
|
-
label: node.label,
|
|
5880
|
-
resourceType: node.resourceType,
|
|
5881
|
-
healthLevel: "inactive",
|
|
5882
|
-
summaryLabel: "No runs",
|
|
5883
|
-
detailLabel: "No executions in range",
|
|
5884
|
-
successRate: null,
|
|
5885
|
-
totalRuns: 0,
|
|
5886
|
-
successCount: 0,
|
|
5887
|
-
failureCount: 0,
|
|
5888
|
-
warningCount: 0,
|
|
5889
|
-
pendingCount: 0,
|
|
5890
|
-
completedCount: 0,
|
|
5891
|
-
expiredCount: 0,
|
|
5892
|
-
lastActivityAt: resourceStats?.lastRunAt ?? null,
|
|
5893
|
-
sortScore: 0
|
|
5894
|
-
};
|
|
5895
|
-
}
|
|
5896
|
-
const successfulOutcomes = resourceStats.successCount + resourceStats.warningCount;
|
|
5897
|
-
const successRate = successfulOutcomes / resourceStats.totalRuns * 100;
|
|
5898
|
-
const healthLevel = successRate >= 95 ? "healthy" : successRate >= 80 ? "warning" : "critical";
|
|
5899
|
-
const summaryLabel = resourceStats.failureCount > 0 ? `${resourceStats.failureCount} failed` : resourceStats.warningCount > 0 ? `${resourceStats.warningCount} warnings` : `${resourceStats.totalRuns} runs`;
|
|
5900
|
-
return {
|
|
5901
|
-
nodeId: node.id,
|
|
5902
|
-
resourceId,
|
|
5903
|
-
label: node.label,
|
|
5904
|
-
resourceType: node.resourceType,
|
|
5905
|
-
healthLevel,
|
|
5906
|
-
summaryLabel,
|
|
5907
|
-
detailLabel: `${Math.round(successRate)}% healthy`,
|
|
5908
|
-
successRate,
|
|
5909
|
-
totalRuns: resourceStats.totalRuns,
|
|
5910
|
-
successCount: resourceStats.successCount,
|
|
5911
|
-
failureCount: resourceStats.failureCount,
|
|
5912
|
-
warningCount: resourceStats.warningCount,
|
|
5913
|
-
pendingCount: 0,
|
|
5914
|
-
completedCount: 0,
|
|
5915
|
-
expiredCount: 0,
|
|
5916
|
-
lastActivityAt: resourceStats.lastRunAt,
|
|
5917
|
-
sortScore: resourceStats.failureCount * 100 + resourceStats.warningCount * 25 + resourceStats.totalRuns
|
|
5918
|
-
};
|
|
5919
|
-
}
|
|
5920
|
-
function getCommandViewGraphNodeHealth(node, stats) {
|
|
5921
|
-
if (node.kind !== "resource" || !stats) {
|
|
5922
|
-
return null;
|
|
5923
|
-
}
|
|
5924
|
-
return toResourceHealth(node, stats);
|
|
5925
|
-
}
|
|
5926
|
-
function getCommandViewGraphHealthMap(graph, stats) {
|
|
5927
|
-
const healthByNodeId = /* @__PURE__ */ new Map();
|
|
5928
|
-
if (!graph || !stats) {
|
|
5929
|
-
return healthByNodeId;
|
|
5930
|
-
}
|
|
5931
|
-
for (const node of graph.nodes) {
|
|
5932
|
-
const health = getCommandViewGraphNodeHealth(node, stats);
|
|
5933
|
-
if (health) {
|
|
5934
|
-
healthByNodeId.set(node.id, health);
|
|
5935
|
-
}
|
|
5936
|
-
}
|
|
5937
|
-
return healthByNodeId;
|
|
5938
|
-
}
|
|
5939
|
-
function getHealthRank(level) {
|
|
5940
|
-
switch (level) {
|
|
5941
|
-
case "critical":
|
|
5942
|
-
return 0;
|
|
5943
|
-
case "warning":
|
|
5944
|
-
return 1;
|
|
5945
|
-
case "healthy":
|
|
5946
|
-
return 2;
|
|
5947
|
-
case "inactive":
|
|
5948
|
-
default:
|
|
5949
|
-
return 3;
|
|
5950
|
-
}
|
|
5951
|
-
}
|
|
5952
|
-
function rankCommandViewHotspots(entries, limit = 3) {
|
|
5953
|
-
return [...entries].filter((entry) => entry.healthLevel === "critical" || entry.healthLevel === "warning").sort((left, right) => {
|
|
5954
|
-
const healthRankDelta = getHealthRank(left.healthLevel) - getHealthRank(right.healthLevel);
|
|
5955
|
-
if (healthRankDelta !== 0) {
|
|
5956
|
-
return healthRankDelta;
|
|
5957
|
-
}
|
|
5958
|
-
if (right.sortScore !== left.sortScore) {
|
|
5959
|
-
return right.sortScore - left.sortScore;
|
|
5960
|
-
}
|
|
5961
|
-
return left.label.localeCompare(right.label);
|
|
5962
|
-
}).slice(0, limit);
|
|
5963
|
-
}
|
|
5964
5838
|
|
|
5965
5839
|
// src/features/operations/organization-graph/path-tracing/trace.ts
|
|
5966
5840
|
var NODE_KIND_ORDER = {
|
|
@@ -6192,15 +6066,896 @@ function resolveOrganizationGraphPathTrace(graph, selection) {
|
|
|
6192
6066
|
message: `Path found from "${source.label}" to "${target.label}" across ${pathEdges.length} edge${pathEdges.length === 1 ? "" : "s"}.`
|
|
6193
6067
|
};
|
|
6194
6068
|
}
|
|
6195
|
-
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6069
|
+
|
|
6070
|
+
// src/features/operations/organization-graph/expand-around/expandAroundGraph.ts
|
|
6071
|
+
var DEFAULT_MAX_DEPTH = 1;
|
|
6072
|
+
var DEFAULT_MAX_RESULTS = 25;
|
|
6073
|
+
var ORG_MODEL_ROOT_KINDS = /* @__PURE__ */ new Set([
|
|
6074
|
+
"feature",
|
|
6075
|
+
"surface",
|
|
6076
|
+
"entity",
|
|
6077
|
+
"capability"
|
|
6078
|
+
]);
|
|
6079
|
+
var PRESET_EDGE_KINDS = {
|
|
6080
|
+
coverage: ["contains", "exposes", "operates-on", "maps_to", "references"],
|
|
6081
|
+
"operational-dependencies": ["references"],
|
|
6082
|
+
"org-context": ["contains", "exposes", "operates-on", "maps_to"],
|
|
6083
|
+
"impact-path": ["references"]
|
|
6084
|
+
};
|
|
6085
|
+
var PRESET_RELATIONSHIP_TYPES = {
|
|
6086
|
+
"operational-dependencies": ["triggers", "uses", "approval"],
|
|
6087
|
+
"impact-path": ["triggers", "uses", "approval"]
|
|
6088
|
+
};
|
|
6089
|
+
var PRESET_DIRECTIONS = {
|
|
6090
|
+
coverage: "both",
|
|
6091
|
+
"operational-dependencies": "both",
|
|
6092
|
+
"org-context": "both",
|
|
6093
|
+
"impact-path": "both"
|
|
6094
|
+
};
|
|
6095
|
+
function toSet(values) {
|
|
6096
|
+
if (!values || values.length === 0) {
|
|
6097
|
+
return null;
|
|
6098
|
+
}
|
|
6099
|
+
return new Set(values);
|
|
6100
|
+
}
|
|
6101
|
+
function clampMaxDepth(maxDepth) {
|
|
6102
|
+
if (maxDepth === 2 || maxDepth === 3) {
|
|
6103
|
+
return maxDepth;
|
|
6104
|
+
}
|
|
6105
|
+
return 1;
|
|
6106
|
+
}
|
|
6107
|
+
function resolvePreset(rootNode, preset) {
|
|
6108
|
+
if (preset) {
|
|
6109
|
+
return preset;
|
|
6110
|
+
}
|
|
6111
|
+
if (!rootNode) {
|
|
6112
|
+
return null;
|
|
6113
|
+
}
|
|
6114
|
+
if (ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
|
|
6115
|
+
return "coverage";
|
|
6116
|
+
}
|
|
6117
|
+
if (rootNode.kind === "resource") {
|
|
6118
|
+
return "operational-dependencies";
|
|
6119
|
+
}
|
|
6120
|
+
return null;
|
|
6121
|
+
}
|
|
6122
|
+
function resolveRequest(rootNode, request) {
|
|
6123
|
+
const preset = resolvePreset(rootNode, request.preset);
|
|
6124
|
+
const maxResults = request.maxResults === void 0 || !Number.isFinite(request.maxResults) ? DEFAULT_MAX_RESULTS : Math.max(0, request.maxResults);
|
|
6125
|
+
return {
|
|
6126
|
+
rootNodeId: request.rootNodeId,
|
|
6127
|
+
direction: request.direction ?? (preset ? PRESET_DIRECTIONS[preset] : "both"),
|
|
6128
|
+
maxDepth: clampMaxDepth(request.maxDepth ?? DEFAULT_MAX_DEPTH),
|
|
6129
|
+
maxResults,
|
|
6130
|
+
edgeKinds: toSet(request.edgeKinds ?? (preset ? PRESET_EDGE_KINDS[preset] : void 0)),
|
|
6131
|
+
relationshipTypes: toSet(
|
|
6132
|
+
request.relationshipTypes ?? (preset ? PRESET_RELATIONSHIP_TYPES[preset] : void 0)
|
|
6133
|
+
),
|
|
6134
|
+
preset,
|
|
6135
|
+
nodeKinds: toSet(request.nodeKinds),
|
|
6136
|
+
resourceTypes: toSet(request.resourceTypes),
|
|
6137
|
+
includeHiddenResources: request.includeHiddenResources ?? false
|
|
6138
|
+
};
|
|
6139
|
+
}
|
|
6140
|
+
function getOppositeNodeId(edge, currentNodeId) {
|
|
6141
|
+
if (edge.sourceId === currentNodeId) {
|
|
6142
|
+
return edge.targetId;
|
|
6143
|
+
}
|
|
6144
|
+
if (edge.targetId === currentNodeId) {
|
|
6145
|
+
return edge.sourceId;
|
|
6146
|
+
}
|
|
6147
|
+
return null;
|
|
6148
|
+
}
|
|
6149
|
+
function getCandidateEdges(index, nodeId2, direction) {
|
|
6150
|
+
if (direction === "outgoing") {
|
|
6151
|
+
return index.outgoingEdgesByNodeId.get(nodeId2) ?? [];
|
|
6152
|
+
}
|
|
6153
|
+
if (direction === "incoming") {
|
|
6154
|
+
return index.incomingEdgesByNodeId.get(nodeId2) ?? [];
|
|
6155
|
+
}
|
|
6156
|
+
const seenEdgeIds = /* @__PURE__ */ new Set();
|
|
6157
|
+
const edges = [];
|
|
6158
|
+
for (const edge of [
|
|
6159
|
+
...index.outgoingEdgesByNodeId.get(nodeId2) ?? [],
|
|
6160
|
+
...index.incomingEdgesByNodeId.get(nodeId2) ?? []
|
|
6161
|
+
]) {
|
|
6162
|
+
if (seenEdgeIds.has(edge.id)) {
|
|
6163
|
+
continue;
|
|
6164
|
+
}
|
|
6165
|
+
seenEdgeIds.add(edge.id);
|
|
6166
|
+
edges.push(edge);
|
|
6167
|
+
}
|
|
6168
|
+
return edges;
|
|
6169
|
+
}
|
|
6170
|
+
function matchesPresetTraversalDirection(edge, currentNodeId, request) {
|
|
6171
|
+
if (request.preset === "coverage" && (edge.kind === "contains" || edge.kind === "exposes")) {
|
|
6172
|
+
return edge.sourceId === currentNodeId;
|
|
6173
|
+
}
|
|
6174
|
+
return true;
|
|
6175
|
+
}
|
|
6176
|
+
function matchesEdgeFilters(edge, currentNodeId, request) {
|
|
6177
|
+
if (request.edgeKinds && !request.edgeKinds.has(edge.kind)) {
|
|
6178
|
+
return false;
|
|
6179
|
+
}
|
|
6180
|
+
if (request.relationshipTypes && (!edge.relationshipType || !request.relationshipTypes.has(edge.relationshipType))) {
|
|
6181
|
+
return false;
|
|
6182
|
+
}
|
|
6183
|
+
return matchesPresetTraversalDirection(edge, currentNodeId, request);
|
|
6184
|
+
}
|
|
6185
|
+
function matchesNodeFilters(node, request) {
|
|
6186
|
+
if (request.nodeKinds && !request.nodeKinds.has(node.kind)) {
|
|
6187
|
+
return false;
|
|
6188
|
+
}
|
|
6189
|
+
if (request.resourceTypes) {
|
|
6190
|
+
if (node.kind !== "resource") {
|
|
6191
|
+
return false;
|
|
6192
|
+
}
|
|
6193
|
+
if (!node.resourceType || !request.resourceTypes.has(node.resourceType)) {
|
|
6194
|
+
return false;
|
|
6195
|
+
}
|
|
6196
|
+
}
|
|
6197
|
+
return true;
|
|
6198
|
+
}
|
|
6199
|
+
function pluralize(count, singular, plural = `${singular}s`) {
|
|
6200
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
6201
|
+
}
|
|
6202
|
+
function getNodeDisplayName(node) {
|
|
6203
|
+
return node.label || node.sourceId || node.id;
|
|
6204
|
+
}
|
|
6205
|
+
function buildSummaryMessages(input) {
|
|
6206
|
+
const { rootNode, preset, expandedNodes, counts, truncated } = input;
|
|
6207
|
+
if (!rootNode) {
|
|
6208
|
+
return ["Select an available node to expand around."];
|
|
6209
|
+
}
|
|
6210
|
+
if (!preset && rootNode.kind === "organization") {
|
|
6211
|
+
return ["Choose a feature, surface, capability, entity, or resource before expanding."];
|
|
6212
|
+
}
|
|
6213
|
+
if (expandedNodes.length === 0) {
|
|
6214
|
+
return [`No matching graph context found around "${getNodeDisplayName(rootNode)}".`];
|
|
6215
|
+
}
|
|
6216
|
+
const resourceCount = expandedNodes.filter((node) => node.kind === "resource").length;
|
|
6217
|
+
const semanticContextCount = expandedNodes.length - resourceCount;
|
|
6218
|
+
const rootLabel = getNodeDisplayName(rootNode);
|
|
6219
|
+
const messages = [];
|
|
6220
|
+
if (preset === "coverage" && ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
|
|
6221
|
+
if (resourceCount > 0 && semanticContextCount > 0) {
|
|
6222
|
+
messages.push(
|
|
6223
|
+
`${pluralize(resourceCount, "resource")} and ${pluralize(
|
|
6224
|
+
semanticContextCount,
|
|
6225
|
+
"semantic context node"
|
|
6226
|
+
)} support "${rootLabel}".`
|
|
6227
|
+
);
|
|
6228
|
+
} else if (resourceCount > 0) {
|
|
6229
|
+
messages.push(`${pluralize(resourceCount, "resource")} support "${rootLabel}".`);
|
|
6230
|
+
} else {
|
|
6231
|
+
messages.push(
|
|
6232
|
+
`${pluralize(semanticContextCount, "semantic context node")} found around "${rootLabel}"; no mapped resources matched this coverage preset.`
|
|
6233
|
+
);
|
|
6234
|
+
}
|
|
6235
|
+
} else if (preset === "operational-dependencies") {
|
|
6236
|
+
messages.push(`${pluralize(resourceCount, "operational dependency resource")} found around "${rootLabel}".`);
|
|
6237
|
+
} else if (preset === "org-context") {
|
|
6238
|
+
messages.push(`${pluralize(expandedNodes.length, "semantic context node")} found around "${rootLabel}".`);
|
|
6239
|
+
} else if (preset === "impact-path") {
|
|
6240
|
+
messages.push(`${pluralize(resourceCount, "resource")} can call or be affected by "${rootLabel}".`);
|
|
6241
|
+
} else {
|
|
6242
|
+
messages.push(`${pluralize(expandedNodes.length, "node")} found around "${rootLabel}".`);
|
|
6243
|
+
}
|
|
6244
|
+
if (counts.hiddenResourceNodes > 0) {
|
|
6245
|
+
messages.push(`${pluralize(counts.hiddenResourceNodes, "hidden resource")} matched current visibility settings.`);
|
|
6246
|
+
}
|
|
6247
|
+
if (counts.alreadyVisibleNodes > 0) {
|
|
6248
|
+
messages.push(`${pluralize(counts.alreadyVisibleNodes, "node")} already visible in the graph.`);
|
|
6249
|
+
}
|
|
6250
|
+
if (truncated) {
|
|
6251
|
+
messages.push(`Results were limited to ${pluralize(expandedNodes.length, "node")}.`);
|
|
6252
|
+
}
|
|
6253
|
+
return messages;
|
|
6254
|
+
}
|
|
6255
|
+
function expandAroundGraph(graph, request, options = {}) {
|
|
6256
|
+
const index = buildOrganizationGraphTraceIndex(graph);
|
|
6257
|
+
const rootNode = index.nodesById.get(request.rootNodeId) ?? null;
|
|
6258
|
+
const resolved = resolveRequest(rootNode, request);
|
|
6259
|
+
const alreadyVisibleNodeIds = new Set(options.alreadyVisibleNodeIds ?? []);
|
|
6260
|
+
const hiddenResourceNodeIds = new Set(options.hiddenResourceNodeIds ?? []);
|
|
6261
|
+
const expandedNodeIds = /* @__PURE__ */ new Set();
|
|
6262
|
+
const expandedEdgeIds = /* @__PURE__ */ new Set();
|
|
6263
|
+
const frontierNodeIds = /* @__PURE__ */ new Set();
|
|
6264
|
+
const visitedDepthByNodeId = /* @__PURE__ */ new Map([[resolved.rootNodeId, 0]]);
|
|
6265
|
+
const hasExplicitTraversalFilter = Boolean(
|
|
6266
|
+
request.preset || request.edgeKinds?.length || request.relationshipTypes?.length || request.nodeKinds?.length || request.resourceTypes?.length
|
|
6267
|
+
);
|
|
6268
|
+
const queue = rootNode && (resolved.preset || hasExplicitTraversalFilter) ? [{ nodeId: rootNode.id, depth: 0 }] : [];
|
|
6269
|
+
let truncated = false;
|
|
6270
|
+
for (let queueIndex = 0; queueIndex < queue.length; queueIndex += 1) {
|
|
6271
|
+
const current = queue[queueIndex];
|
|
6272
|
+
if (current.depth >= resolved.maxDepth) {
|
|
6273
|
+
if (current.nodeId !== resolved.rootNodeId) {
|
|
6274
|
+
frontierNodeIds.add(current.nodeId);
|
|
6275
|
+
}
|
|
6276
|
+
continue;
|
|
6277
|
+
}
|
|
6278
|
+
for (const edge of getCandidateEdges(index, current.nodeId, resolved.direction)) {
|
|
6279
|
+
if (!matchesEdgeFilters(edge, current.nodeId, resolved)) {
|
|
6280
|
+
continue;
|
|
6281
|
+
}
|
|
6282
|
+
const nextNodeId = getOppositeNodeId(edge, current.nodeId);
|
|
6283
|
+
if (!nextNodeId) {
|
|
6284
|
+
continue;
|
|
6285
|
+
}
|
|
6286
|
+
const nextNode = index.nodesById.get(nextNodeId);
|
|
6287
|
+
if (!nextNode || !matchesNodeFilters(nextNode, resolved)) {
|
|
6288
|
+
continue;
|
|
6289
|
+
}
|
|
6290
|
+
if (!resolved.includeHiddenResources && hiddenResourceNodeIds.has(nextNode.id)) {
|
|
6291
|
+
continue;
|
|
6292
|
+
}
|
|
6293
|
+
const nextDepth = current.depth + 1;
|
|
6294
|
+
const previousDepth = visitedDepthByNodeId.get(nextNode.id);
|
|
6295
|
+
if (previousDepth !== void 0) {
|
|
6296
|
+
if (nextNode.id === resolved.rootNodeId || expandedNodeIds.has(nextNode.id)) {
|
|
6297
|
+
expandedEdgeIds.add(edge.id);
|
|
6298
|
+
}
|
|
6299
|
+
continue;
|
|
6300
|
+
}
|
|
6301
|
+
if (expandedNodeIds.size >= resolved.maxResults) {
|
|
6302
|
+
truncated = true;
|
|
6303
|
+
frontierNodeIds.add(nextNode.id);
|
|
6304
|
+
continue;
|
|
6305
|
+
}
|
|
6306
|
+
visitedDepthByNodeId.set(nextNode.id, nextDepth);
|
|
6307
|
+
expandedNodeIds.add(nextNode.id);
|
|
6308
|
+
expandedEdgeIds.add(edge.id);
|
|
6309
|
+
if (nextDepth >= resolved.maxDepth) {
|
|
6310
|
+
frontierNodeIds.add(nextNode.id);
|
|
6311
|
+
continue;
|
|
6312
|
+
}
|
|
6313
|
+
queue.push({ nodeId: nextNode.id, depth: nextDepth });
|
|
6314
|
+
}
|
|
6315
|
+
}
|
|
6316
|
+
const expandedNodes = [...expandedNodeIds].map((nodeId2) => index.nodesById.get(nodeId2)).filter((node) => Boolean(node));
|
|
6317
|
+
const hiddenResourceNodes = expandedNodes.filter((node) => hiddenResourceNodeIds.has(node.id)).length;
|
|
6318
|
+
const alreadyVisibleNodes = expandedNodes.filter((node) => alreadyVisibleNodeIds.has(node.id)).length;
|
|
6319
|
+
const newNodes = expandedNodes.filter(
|
|
6320
|
+
(node) => !hiddenResourceNodeIds.has(node.id) && !alreadyVisibleNodeIds.has(node.id)
|
|
6321
|
+
).length;
|
|
6322
|
+
const counts = {
|
|
6323
|
+
newNodes,
|
|
6324
|
+
newEdges: expandedEdgeIds.size,
|
|
6325
|
+
alreadyVisibleNodes,
|
|
6326
|
+
hiddenResourceNodes
|
|
6327
|
+
};
|
|
6328
|
+
const summaryMessages = buildSummaryMessages({
|
|
6329
|
+
rootNode,
|
|
6330
|
+
preset: resolved.preset,
|
|
6331
|
+
expandedNodes,
|
|
6332
|
+
counts,
|
|
6333
|
+
truncated
|
|
6334
|
+
});
|
|
6335
|
+
return {
|
|
6336
|
+
rootNodeId: request.rootNodeId,
|
|
6337
|
+
rootNode,
|
|
6338
|
+
preset: resolved.preset,
|
|
6339
|
+
direction: resolved.direction,
|
|
6340
|
+
maxDepth: resolved.maxDepth,
|
|
6341
|
+
maxResults: resolved.maxResults,
|
|
6342
|
+
expandedNodeIds: [...expandedNodeIds],
|
|
6343
|
+
expandedEdgeIds: [...expandedEdgeIds],
|
|
6344
|
+
frontierNodeIds: [...frontierNodeIds].filter((nodeId2) => nodeId2 !== resolved.rootNodeId),
|
|
6345
|
+
truncated,
|
|
6346
|
+
counts,
|
|
6347
|
+
summaryMessages,
|
|
6348
|
+
message: summaryMessages[0] ?? ""
|
|
6349
|
+
};
|
|
6350
|
+
}
|
|
6351
|
+
var PRESET_OPTIONS = [
|
|
6352
|
+
{ value: "coverage", label: "Coverage" },
|
|
6353
|
+
{ value: "operational-dependencies", label: "Operational dependencies" },
|
|
6354
|
+
{ value: "org-context", label: "Org context" },
|
|
6355
|
+
{ value: "impact-path", label: "Impact path" }
|
|
6356
|
+
];
|
|
6357
|
+
var DIRECTION_OPTIONS = [
|
|
6358
|
+
{ value: "both", label: "Both" },
|
|
6359
|
+
{ value: "outgoing", label: "Outgoing" },
|
|
6360
|
+
{ value: "incoming", label: "Incoming" }
|
|
6361
|
+
];
|
|
6362
|
+
var EDGE_KIND_OPTIONS = [
|
|
6363
|
+
{ value: "contains", label: "Containment" },
|
|
6364
|
+
{ value: "references", label: "References" },
|
|
6365
|
+
{ value: "exposes", label: "Exposes" },
|
|
6366
|
+
{ value: "maps_to", label: "Maps to" },
|
|
6367
|
+
{ value: "operates-on", label: "Operates on" },
|
|
6368
|
+
{ value: "uses", label: "Uses" }
|
|
6369
|
+
];
|
|
6370
|
+
var RELATIONSHIP_OPTIONS = [
|
|
6371
|
+
{ value: "triggers", label: "Triggers" },
|
|
6372
|
+
{ value: "uses", label: "Uses" },
|
|
6373
|
+
{ value: "approval", label: "Approval" }
|
|
6374
|
+
];
|
|
6375
|
+
var RESOURCE_TYPE_OPTIONS = [
|
|
6376
|
+
{ value: "workflow", label: "Workflow" },
|
|
6377
|
+
{ value: "agent", label: "Agent" },
|
|
6378
|
+
{ value: "trigger", label: "Trigger" },
|
|
6379
|
+
{ value: "integration", label: "Integration" },
|
|
6380
|
+
{ value: "external", label: "External" },
|
|
6381
|
+
{ value: "human_checkpoint", label: "Human checkpoint" }
|
|
6382
|
+
];
|
|
6383
|
+
function updateValue(value, key, nextValue, onChange) {
|
|
6384
|
+
onChange({
|
|
6385
|
+
...value,
|
|
6386
|
+
[key]: nextValue
|
|
6387
|
+
});
|
|
6388
|
+
}
|
|
6389
|
+
function toOptionalArray(values) {
|
|
6390
|
+
return values.length > 0 ? values : void 0;
|
|
6391
|
+
}
|
|
6392
|
+
function toMaxDepth(value) {
|
|
6393
|
+
const numeric = typeof value === "number" ? value : Number.parseInt(value, 10);
|
|
6394
|
+
if (numeric === 3) return 3;
|
|
6395
|
+
if (numeric === 2) return 2;
|
|
6396
|
+
return 1;
|
|
6397
|
+
}
|
|
6398
|
+
function ExpandAroundPanel({
|
|
6399
|
+
selectedNode,
|
|
6400
|
+
value,
|
|
6401
|
+
result,
|
|
6402
|
+
appliedNodeCount,
|
|
6403
|
+
appliedEdgeCount,
|
|
6404
|
+
onChange,
|
|
6405
|
+
onPreview,
|
|
6406
|
+
onApply,
|
|
6407
|
+
onClear
|
|
6408
|
+
}) {
|
|
6409
|
+
const disabled = !selectedNode;
|
|
6410
|
+
const canApply = Boolean(result && result.expandedNodeIds.length > 0);
|
|
6411
|
+
const rootIsTooBroad = selectedNode?.kind === "organization" && !value.preset;
|
|
6412
|
+
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6413
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "wrap", children: [
|
|
6414
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
6415
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 800, children: "Expand Around" }),
|
|
6416
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode ? `Preview typed graph context around ${selectedNode.label}.` : "Select a graph node to preview nearby operational context." })
|
|
6417
|
+
] }),
|
|
6418
|
+
appliedNodeCount > 0 || appliedEdgeCount > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
|
|
6419
|
+
appliedNodeCount,
|
|
6420
|
+
" nodes / ",
|
|
6421
|
+
appliedEdgeCount,
|
|
6422
|
+
" edges applied"
|
|
6423
|
+
] }) : null
|
|
6424
|
+
] }),
|
|
6425
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
|
|
6426
|
+
/* @__PURE__ */ jsx(
|
|
6427
|
+
Select,
|
|
6428
|
+
{
|
|
6429
|
+
label: "Preset",
|
|
6430
|
+
placeholder: "Auto",
|
|
6431
|
+
data: PRESET_OPTIONS,
|
|
6432
|
+
value: value.preset ?? null,
|
|
6433
|
+
onChange: (preset) => updateValue(value, "preset", preset ?? void 0, onChange),
|
|
6434
|
+
disabled,
|
|
6435
|
+
clearable: true
|
|
6436
|
+
}
|
|
6437
|
+
),
|
|
6438
|
+
/* @__PURE__ */ jsx(
|
|
6439
|
+
Select,
|
|
6440
|
+
{
|
|
6441
|
+
label: "Direction",
|
|
6442
|
+
data: DIRECTION_OPTIONS,
|
|
6443
|
+
value: value.direction ?? "both",
|
|
6444
|
+
onChange: (direction) => updateValue(value, "direction", direction ?? "both", onChange),
|
|
6445
|
+
disabled
|
|
6446
|
+
}
|
|
6447
|
+
),
|
|
6448
|
+
/* @__PURE__ */ jsx(
|
|
6449
|
+
NumberInput,
|
|
6450
|
+
{
|
|
6451
|
+
label: "Depth",
|
|
6452
|
+
min: 1,
|
|
6453
|
+
max: 3,
|
|
6454
|
+
value: value.maxDepth ?? 1,
|
|
6455
|
+
onChange: (maxDepth) => updateValue(value, "maxDepth", toMaxDepth(maxDepth), onChange),
|
|
6456
|
+
disabled
|
|
6457
|
+
}
|
|
6458
|
+
),
|
|
6459
|
+
/* @__PURE__ */ jsx(
|
|
6460
|
+
NumberInput,
|
|
6461
|
+
{
|
|
6462
|
+
label: "Max results",
|
|
6463
|
+
min: 1,
|
|
6464
|
+
max: 100,
|
|
6465
|
+
value: value.maxResults ?? 25,
|
|
6466
|
+
onChange: (maxResults) => updateValue(
|
|
6467
|
+
value,
|
|
6468
|
+
"maxResults",
|
|
6469
|
+
Math.max(1, typeof maxResults === "number" ? maxResults : Number.parseInt(maxResults, 10) || 25),
|
|
6470
|
+
onChange
|
|
6471
|
+
),
|
|
6472
|
+
disabled
|
|
6473
|
+
}
|
|
6474
|
+
)
|
|
6475
|
+
] }),
|
|
6476
|
+
/* @__PURE__ */ jsx(
|
|
6477
|
+
MultiSelect,
|
|
6478
|
+
{
|
|
6479
|
+
label: "Relationship filters",
|
|
6480
|
+
placeholder: "Preset defaults",
|
|
6481
|
+
data: RELATIONSHIP_OPTIONS,
|
|
6482
|
+
value: value.relationshipTypes ?? [],
|
|
6483
|
+
onChange: (relationshipTypes) => updateValue(value, "relationshipTypes", toOptionalArray(relationshipTypes), onChange),
|
|
6484
|
+
disabled,
|
|
6485
|
+
clearable: true
|
|
6486
|
+
}
|
|
6487
|
+
),
|
|
6488
|
+
/* @__PURE__ */ jsx(
|
|
6489
|
+
MultiSelect,
|
|
6490
|
+
{
|
|
6491
|
+
label: "Edge kind filters",
|
|
6492
|
+
placeholder: "Preset defaults",
|
|
6493
|
+
data: EDGE_KIND_OPTIONS,
|
|
6494
|
+
value: value.edgeKinds ?? [],
|
|
6495
|
+
onChange: (edgeKinds) => updateValue(value, "edgeKinds", toOptionalArray(edgeKinds), onChange),
|
|
6496
|
+
disabled,
|
|
6497
|
+
clearable: true
|
|
6498
|
+
}
|
|
6499
|
+
),
|
|
6500
|
+
/* @__PURE__ */ jsx(
|
|
6501
|
+
MultiSelect,
|
|
6502
|
+
{
|
|
6503
|
+
label: "Resource type filters",
|
|
6504
|
+
placeholder: "All resource types",
|
|
6505
|
+
data: RESOURCE_TYPE_OPTIONS,
|
|
6506
|
+
value: value.resourceTypes ?? [],
|
|
6507
|
+
onChange: (resourceTypes) => updateValue(value, "resourceTypes", toOptionalArray(resourceTypes), onChange),
|
|
6508
|
+
disabled,
|
|
6509
|
+
clearable: true
|
|
6510
|
+
}
|
|
6511
|
+
),
|
|
6512
|
+
/* @__PURE__ */ jsx(
|
|
6513
|
+
Switch,
|
|
6514
|
+
{
|
|
6515
|
+
label: "Include hidden resources",
|
|
6516
|
+
checked: value.includeHiddenResources ?? true,
|
|
6517
|
+
onChange: (event) => updateValue(value, "includeHiddenResources", event.currentTarget.checked, onChange),
|
|
6518
|
+
disabled
|
|
6519
|
+
}
|
|
6520
|
+
),
|
|
6521
|
+
rootIsTooBroad ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "orange", children: "The organization root is broad. Choose a narrower node or a semantic preset before previewing." }) : null,
|
|
6522
|
+
result ? /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
6523
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
6524
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
6525
|
+
result.counts.newNodes,
|
|
6526
|
+
" new"
|
|
6527
|
+
] }),
|
|
6528
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
6529
|
+
result.counts.alreadyVisibleNodes,
|
|
6530
|
+
" visible"
|
|
6531
|
+
] }),
|
|
6532
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: result.counts.hiddenResourceNodes > 0 ? "orange" : "gray", children: [
|
|
6533
|
+
result.counts.hiddenResourceNodes,
|
|
6534
|
+
" hidden"
|
|
6535
|
+
] }),
|
|
6536
|
+
result.truncated ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", children: "Truncated" }) : null
|
|
6537
|
+
] }),
|
|
6538
|
+
result.summaryMessages.map((message) => /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: message }, message))
|
|
6539
|
+
] }) }) : null,
|
|
6540
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "wrap", children: [
|
|
6541
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
6542
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: onPreview, disabled: disabled || rootIsTooBroad, children: "Preview" }),
|
|
6543
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", onClick: onApply, disabled: !canApply, children: "Apply" })
|
|
6544
|
+
] }),
|
|
6545
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClear, disabled: !result && appliedNodeCount === 0, children: "Clear expansion" })
|
|
6546
|
+
] })
|
|
6547
|
+
] }) });
|
|
6548
|
+
}
|
|
6549
|
+
var cellStyle = {
|
|
6550
|
+
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
6551
|
+
display: "flex",
|
|
6552
|
+
alignItems: "center",
|
|
6553
|
+
gap: "var(--mantine-spacing-sm)",
|
|
6554
|
+
minWidth: 0
|
|
6555
|
+
};
|
|
6556
|
+
function CommandViewHealthStrip({
|
|
6557
|
+
overview,
|
|
6558
|
+
hotspots,
|
|
6559
|
+
visibleResources,
|
|
6560
|
+
hiddenResources = 0,
|
|
6561
|
+
resourcesHidden,
|
|
6562
|
+
selectedLabel,
|
|
6563
|
+
onFocusHotspot,
|
|
6564
|
+
onResourcesHiddenChange,
|
|
6565
|
+
onResetFocus
|
|
6566
|
+
}) {
|
|
6567
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
6568
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
6569
|
+
/* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
6570
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
|
|
6571
|
+
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
6572
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
|
|
6573
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
|
|
6574
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
|
|
6575
|
+
] }),
|
|
6576
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
|
|
6577
|
+
] }),
|
|
6578
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
6579
|
+
/* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
6580
|
+
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(
|
|
6581
|
+
Badge,
|
|
6582
|
+
{
|
|
6583
|
+
variant: "light",
|
|
6584
|
+
color: "red",
|
|
6585
|
+
size: "xs",
|
|
6586
|
+
style: { cursor: "pointer", flexShrink: 0 },
|
|
6587
|
+
onClick: () => onFocusHotspot(hotspot.resourceId),
|
|
6588
|
+
children: hotspot.label
|
|
6589
|
+
}
|
|
6590
|
+
) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
|
|
6591
|
+
] }),
|
|
6592
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
6593
|
+
/* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
6594
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
|
|
6595
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
|
|
6596
|
+
"pending / ",
|
|
6597
|
+
overview?.activeHumanCheckpoints ?? 0,
|
|
6598
|
+
" queues"
|
|
6599
|
+
] })
|
|
6600
|
+
] }),
|
|
6601
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
6602
|
+
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
6603
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
|
|
6604
|
+
/* @__PURE__ */ jsx(
|
|
6605
|
+
Button,
|
|
6606
|
+
{
|
|
6607
|
+
size: "compact-xs",
|
|
6608
|
+
variant: resourcesHidden ? "light" : "subtle",
|
|
6609
|
+
onClick: () => onResourcesHiddenChange(!resourcesHidden),
|
|
6610
|
+
style: { flexShrink: 0 },
|
|
6611
|
+
children: resourcesHidden ? "Show resources" : "Hide resources"
|
|
6612
|
+
}
|
|
6613
|
+
),
|
|
6614
|
+
/* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
|
|
6615
|
+
] })
|
|
6616
|
+
] });
|
|
6617
|
+
}
|
|
6618
|
+
var FILTER_STATE_ICONS2 = {
|
|
6619
|
+
neutral: IconCircleDashed,
|
|
6620
|
+
include: IconCircleCheck,
|
|
6621
|
+
exclude: IconCircleX
|
|
6622
|
+
};
|
|
6623
|
+
var FILTER_STATE_COLORS2 = {
|
|
6624
|
+
neutral: "var(--color-text-dimmed)",
|
|
6625
|
+
include: "var(--mantine-color-green-6)",
|
|
6626
|
+
exclude: "var(--mantine-color-red-6)"
|
|
6627
|
+
};
|
|
6628
|
+
var FILTER_STATE_LABELS2 = {
|
|
6629
|
+
neutral: "Not filtered",
|
|
6630
|
+
include: "Include only",
|
|
6631
|
+
exclude: "Exclude"
|
|
6632
|
+
};
|
|
6633
|
+
function getCommandViewResources(commandViewData) {
|
|
6634
|
+
if (!commandViewData) {
|
|
6635
|
+
return [];
|
|
6636
|
+
}
|
|
6637
|
+
return [
|
|
6638
|
+
...commandViewData.agents,
|
|
6639
|
+
...commandViewData.workflows,
|
|
6640
|
+
...commandViewData.triggers,
|
|
6641
|
+
...commandViewData.integrations,
|
|
6642
|
+
...commandViewData.externalResources,
|
|
6643
|
+
...commandViewData.humanCheckpoints
|
|
6644
|
+
];
|
|
6645
|
+
}
|
|
6646
|
+
function nextDomainFilterState(current) {
|
|
6647
|
+
if (current === "neutral") return "include";
|
|
6648
|
+
if (current === "include") return "exclude";
|
|
6649
|
+
return "neutral";
|
|
6650
|
+
}
|
|
6651
|
+
function FilterPanel({
|
|
6652
|
+
filters,
|
|
6653
|
+
onChangeFilters,
|
|
6654
|
+
resetValue,
|
|
6655
|
+
disabled = false,
|
|
6656
|
+
commandViewData,
|
|
6657
|
+
lens,
|
|
6658
|
+
resourcesHidden,
|
|
6659
|
+
diagnosticsHidden,
|
|
6660
|
+
onResourcesHiddenChange,
|
|
6661
|
+
onDiagnosticsHiddenChange,
|
|
6662
|
+
onRevealResources,
|
|
6663
|
+
onResetFilters,
|
|
6664
|
+
visibilityCounts,
|
|
6665
|
+
graph,
|
|
6666
|
+
baseGraph,
|
|
6667
|
+
layout = "grid"
|
|
6668
|
+
}) {
|
|
6669
|
+
const resourceFacets = collectResourceFilterFacets(getCommandViewResources(commandViewData));
|
|
6670
|
+
const Section = ({ children }) => layout === "stack" ? /* @__PURE__ */ jsx(
|
|
6671
|
+
Stack,
|
|
6672
|
+
{
|
|
6673
|
+
gap: "sm",
|
|
6674
|
+
pb: "sm",
|
|
6675
|
+
style: {
|
|
6676
|
+
borderBottom: "1px solid var(--color-border)"
|
|
6677
|
+
},
|
|
6678
|
+
children
|
|
6679
|
+
}
|
|
6680
|
+
) : /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", style: { background: "var(--color-surface)" }, children });
|
|
6681
|
+
const updateDomainFilter = (domainId) => {
|
|
6682
|
+
const current = filters.domainFilters[domainId] ?? "neutral";
|
|
6683
|
+
onChangeFilters({
|
|
6684
|
+
...filters,
|
|
6685
|
+
domainFilters: {
|
|
6686
|
+
...filters.domainFilters,
|
|
6687
|
+
[domainId]: nextDomainFilterState(current)
|
|
6688
|
+
}
|
|
6689
|
+
});
|
|
6690
|
+
};
|
|
6691
|
+
const handleResourceVisibilityAction = () => {
|
|
6692
|
+
if (resourcesHidden) {
|
|
6693
|
+
onRevealResources();
|
|
6694
|
+
return;
|
|
6695
|
+
}
|
|
6696
|
+
onResourcesHiddenChange(true);
|
|
6697
|
+
};
|
|
6698
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6699
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6700
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Filters" }),
|
|
6701
|
+
/* @__PURE__ */ jsx(
|
|
6702
|
+
OrganizationGraphFilterToolbar,
|
|
6703
|
+
{
|
|
6704
|
+
value: filters,
|
|
6705
|
+
onChange: onChangeFilters,
|
|
6706
|
+
disabled,
|
|
6707
|
+
resetValue
|
|
6708
|
+
}
|
|
6709
|
+
)
|
|
6710
|
+
] }) }),
|
|
6711
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6712
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
|
|
6713
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Visibility" }),
|
|
6714
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
6715
|
+
visibilityCounts.visibleResourceCount,
|
|
6716
|
+
"/",
|
|
6717
|
+
visibilityCounts.totalResourceCount,
|
|
6718
|
+
" resources"
|
|
6719
|
+
] })
|
|
6720
|
+
] }),
|
|
6721
|
+
lens === "command-view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6722
|
+
/* @__PURE__ */ jsx(
|
|
6723
|
+
Checkbox,
|
|
6724
|
+
{
|
|
6725
|
+
label: "Hide resource nodes",
|
|
6726
|
+
description: "Keep the organization structure readable and reveal resource nodes as needed.",
|
|
6727
|
+
checked: resourcesHidden,
|
|
6728
|
+
onChange: (event) => onResourcesHiddenChange(event.currentTarget.checked),
|
|
6729
|
+
disabled
|
|
6730
|
+
}
|
|
6731
|
+
),
|
|
6732
|
+
/* @__PURE__ */ jsx(
|
|
6733
|
+
Checkbox,
|
|
6734
|
+
{
|
|
6735
|
+
label: "Hide diagnostic and testing resources",
|
|
6736
|
+
description: "Diagnostics stay available through filters, trace, impact, and contextual reveal.",
|
|
6737
|
+
checked: diagnosticsHidden,
|
|
6738
|
+
onChange: (event) => onDiagnosticsHiddenChange(event.currentTarget.checked),
|
|
6739
|
+
disabled
|
|
6740
|
+
}
|
|
6741
|
+
),
|
|
6742
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
6743
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenResourceCount > 0 ? "yellow" : "green", children: [
|
|
6744
|
+
visibilityCounts.hiddenResourceCount,
|
|
6745
|
+
" hidden"
|
|
6746
|
+
] }),
|
|
6747
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenDiagnosticResourceCount > 0 ? "yellow" : "gray", children: [
|
|
6748
|
+
visibilityCounts.hiddenDiagnosticResourceCount,
|
|
6749
|
+
" diagnostic/testing"
|
|
6750
|
+
] })
|
|
6751
|
+
] }),
|
|
6752
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
6753
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: handleResourceVisibilityAction, disabled, children: resourcesHidden ? "Reveal resources" : "Hide resources" }),
|
|
6754
|
+
/* @__PURE__ */ jsx(
|
|
6755
|
+
Button,
|
|
6756
|
+
{
|
|
6757
|
+
size: "xs",
|
|
6758
|
+
variant: "subtle",
|
|
6759
|
+
leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
|
|
6760
|
+
onClick: onResetFilters,
|
|
6761
|
+
disabled,
|
|
6762
|
+
children: "Reset filters"
|
|
6763
|
+
}
|
|
6764
|
+
)
|
|
6765
|
+
] })
|
|
6766
|
+
] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Visibility controls are available in the Command View lens." })
|
|
6767
|
+
] }) }),
|
|
6768
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6769
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Resource Facets" }),
|
|
6770
|
+
resourceFacets.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: resourceFacets.map((facet) => {
|
|
6771
|
+
const filterState = filters.domainFilters[facet.id] ?? "neutral";
|
|
6772
|
+
const StateIcon = FILTER_STATE_ICONS2[filterState];
|
|
6773
|
+
return /* @__PURE__ */ jsx(
|
|
6774
|
+
UnstyledButton,
|
|
6775
|
+
{
|
|
6776
|
+
title: FILTER_STATE_LABELS2[filterState],
|
|
6777
|
+
onClick: () => updateDomainFilter(facet.id),
|
|
6778
|
+
disabled,
|
|
6779
|
+
style: {
|
|
6780
|
+
border: "1px solid var(--color-border)",
|
|
6781
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
6782
|
+
padding: "6px 8px"
|
|
6783
|
+
},
|
|
6784
|
+
children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
|
|
6785
|
+
/* @__PURE__ */ jsx(StateIcon, { size: 16, style: { color: FILTER_STATE_COLORS2[filterState], flexShrink: 0 } }),
|
|
6786
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, c: filterState === "neutral" ? "dimmed" : void 0, children: facet.label })
|
|
6787
|
+
] })
|
|
6788
|
+
},
|
|
6789
|
+
facet.id
|
|
6790
|
+
);
|
|
6791
|
+
}) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No resource facets are available for the current topology." }),
|
|
6792
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
6793
|
+
"Showing ",
|
|
6794
|
+
graph?.nodes.length ?? 0,
|
|
6795
|
+
" nodes and ",
|
|
6796
|
+
graph?.edges.length ?? 0,
|
|
6797
|
+
" edges from",
|
|
6798
|
+
" ",
|
|
6799
|
+
baseGraph?.nodes.length ?? 0,
|
|
6800
|
+
" total nodes."
|
|
6801
|
+
] })
|
|
6802
|
+
] }) })
|
|
6803
|
+
] });
|
|
6804
|
+
if (layout === "stack") {
|
|
6805
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: content });
|
|
6806
|
+
}
|
|
6807
|
+
return /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, lg: 3 }, spacing: "md", children: content });
|
|
6808
|
+
}
|
|
6809
|
+
|
|
6810
|
+
// src/features/operations/organization-graph/commandViewGraphHealth.ts
|
|
6811
|
+
function toResourceHealth(node, stats) {
|
|
6812
|
+
const resourceId = node.sourceId ?? node.id;
|
|
6813
|
+
if (node.resourceType === "human_checkpoint") {
|
|
6814
|
+
const checkpointStats = stats.humanCheckpoints[resourceId];
|
|
6815
|
+
if (!checkpointStats) {
|
|
6816
|
+
return {
|
|
6817
|
+
nodeId: node.id,
|
|
6818
|
+
resourceId,
|
|
6819
|
+
label: node.label,
|
|
6820
|
+
resourceType: node.resourceType,
|
|
6821
|
+
healthLevel: "inactive",
|
|
6822
|
+
summaryLabel: "No queue activity",
|
|
6823
|
+
detailLabel: "No approvals in range",
|
|
6824
|
+
successRate: null,
|
|
6825
|
+
totalRuns: 0,
|
|
6826
|
+
successCount: 0,
|
|
6827
|
+
failureCount: 0,
|
|
6828
|
+
warningCount: 0,
|
|
6829
|
+
pendingCount: 0,
|
|
6830
|
+
completedCount: 0,
|
|
6831
|
+
expiredCount: 0,
|
|
6832
|
+
lastActivityAt: null,
|
|
6833
|
+
sortScore: 0
|
|
6834
|
+
};
|
|
6835
|
+
}
|
|
6836
|
+
const totalQueueActivity = checkpointStats.pendingCount + checkpointStats.completedCount + checkpointStats.expiredCount;
|
|
6837
|
+
const healthLevel2 = checkpointStats.pendingCount > 0 ? checkpointStats.pendingCount >= 3 || checkpointStats.expiredCount > 0 ? "critical" : "warning" : totalQueueActivity > 0 ? "healthy" : "inactive";
|
|
6838
|
+
const summaryLabel2 = checkpointStats.pendingCount > 0 ? `${checkpointStats.pendingCount} pending` : checkpointStats.expiredCount > 0 ? `${checkpointStats.expiredCount} expired` : checkpointStats.completedCount > 0 ? `${checkpointStats.completedCount} completed` : "No queue activity";
|
|
6839
|
+
const detailLabel = checkpointStats.pendingCount > 0 ? `${checkpointStats.completedCount} resolved` : totalQueueActivity > 0 ? "Queue clear" : "No approvals in range";
|
|
6840
|
+
return {
|
|
6841
|
+
nodeId: node.id,
|
|
6842
|
+
resourceId,
|
|
6843
|
+
label: node.label,
|
|
6844
|
+
resourceType: node.resourceType,
|
|
6845
|
+
healthLevel: healthLevel2,
|
|
6846
|
+
summaryLabel: summaryLabel2,
|
|
6847
|
+
detailLabel,
|
|
6848
|
+
successRate: null,
|
|
6849
|
+
totalRuns: 0,
|
|
6850
|
+
successCount: 0,
|
|
6851
|
+
failureCount: 0,
|
|
6852
|
+
warningCount: 0,
|
|
6853
|
+
pendingCount: checkpointStats.pendingCount,
|
|
6854
|
+
completedCount: checkpointStats.completedCount,
|
|
6855
|
+
expiredCount: checkpointStats.expiredCount,
|
|
6856
|
+
lastActivityAt: checkpointStats.lastDecisionAt,
|
|
6857
|
+
sortScore: checkpointStats.pendingCount * 100 + checkpointStats.expiredCount * 25 + checkpointStats.completedCount
|
|
6858
|
+
};
|
|
6859
|
+
}
|
|
6860
|
+
const resourceStats = stats.resources[resourceId];
|
|
6861
|
+
if (!resourceStats || resourceStats.totalRuns <= 0) {
|
|
6862
|
+
return {
|
|
6863
|
+
nodeId: node.id,
|
|
6864
|
+
resourceId,
|
|
6865
|
+
label: node.label,
|
|
6866
|
+
resourceType: node.resourceType,
|
|
6867
|
+
healthLevel: "inactive",
|
|
6868
|
+
summaryLabel: "No runs",
|
|
6869
|
+
detailLabel: "No executions in range",
|
|
6870
|
+
successRate: null,
|
|
6871
|
+
totalRuns: 0,
|
|
6872
|
+
successCount: 0,
|
|
6873
|
+
failureCount: 0,
|
|
6874
|
+
warningCount: 0,
|
|
6875
|
+
pendingCount: 0,
|
|
6876
|
+
completedCount: 0,
|
|
6877
|
+
expiredCount: 0,
|
|
6878
|
+
lastActivityAt: resourceStats?.lastRunAt ?? null,
|
|
6879
|
+
sortScore: 0
|
|
6880
|
+
};
|
|
6881
|
+
}
|
|
6882
|
+
const successfulOutcomes = resourceStats.successCount + resourceStats.warningCount;
|
|
6883
|
+
const successRate = successfulOutcomes / resourceStats.totalRuns * 100;
|
|
6884
|
+
const healthLevel = successRate >= 95 ? "healthy" : successRate >= 80 ? "warning" : "critical";
|
|
6885
|
+
const summaryLabel = resourceStats.failureCount > 0 ? `${resourceStats.failureCount} failed` : resourceStats.warningCount > 0 ? `${resourceStats.warningCount} warnings` : `${resourceStats.totalRuns} runs`;
|
|
6886
|
+
return {
|
|
6887
|
+
nodeId: node.id,
|
|
6888
|
+
resourceId,
|
|
6889
|
+
label: node.label,
|
|
6890
|
+
resourceType: node.resourceType,
|
|
6891
|
+
healthLevel,
|
|
6892
|
+
summaryLabel,
|
|
6893
|
+
detailLabel: `${Math.round(successRate)}% healthy`,
|
|
6894
|
+
successRate,
|
|
6895
|
+
totalRuns: resourceStats.totalRuns,
|
|
6896
|
+
successCount: resourceStats.successCount,
|
|
6897
|
+
failureCount: resourceStats.failureCount,
|
|
6898
|
+
warningCount: resourceStats.warningCount,
|
|
6899
|
+
pendingCount: 0,
|
|
6900
|
+
completedCount: 0,
|
|
6901
|
+
expiredCount: 0,
|
|
6902
|
+
lastActivityAt: resourceStats.lastRunAt,
|
|
6903
|
+
sortScore: resourceStats.failureCount * 100 + resourceStats.warningCount * 25 + resourceStats.totalRuns
|
|
6904
|
+
};
|
|
6905
|
+
}
|
|
6906
|
+
function getCommandViewGraphNodeHealth(node, stats) {
|
|
6907
|
+
if (node.kind !== "resource" || !stats) {
|
|
6908
|
+
return null;
|
|
6909
|
+
}
|
|
6910
|
+
return toResourceHealth(node, stats);
|
|
6911
|
+
}
|
|
6912
|
+
function getCommandViewGraphHealthMap(graph, stats) {
|
|
6913
|
+
const healthByNodeId = /* @__PURE__ */ new Map();
|
|
6914
|
+
if (!graph || !stats) {
|
|
6915
|
+
return healthByNodeId;
|
|
6916
|
+
}
|
|
6917
|
+
for (const node of graph.nodes) {
|
|
6918
|
+
const health = getCommandViewGraphNodeHealth(node, stats);
|
|
6919
|
+
if (health) {
|
|
6920
|
+
healthByNodeId.set(node.id, health);
|
|
6921
|
+
}
|
|
6922
|
+
}
|
|
6923
|
+
return healthByNodeId;
|
|
6924
|
+
}
|
|
6925
|
+
function getHealthRank(level) {
|
|
6926
|
+
switch (level) {
|
|
6927
|
+
case "critical":
|
|
6928
|
+
return 0;
|
|
6929
|
+
case "warning":
|
|
6930
|
+
return 1;
|
|
6931
|
+
case "healthy":
|
|
6932
|
+
return 2;
|
|
6933
|
+
case "inactive":
|
|
6934
|
+
default:
|
|
6935
|
+
return 3;
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
function rankCommandViewHotspots(entries, limit = 3) {
|
|
6939
|
+
return [...entries].filter((entry) => entry.healthLevel === "critical" || entry.healthLevel === "warning").sort((left, right) => {
|
|
6940
|
+
const healthRankDelta = getHealthRank(left.healthLevel) - getHealthRank(right.healthLevel);
|
|
6941
|
+
if (healthRankDelta !== 0) {
|
|
6942
|
+
return healthRankDelta;
|
|
6943
|
+
}
|
|
6944
|
+
if (right.sortScore !== left.sortScore) {
|
|
6945
|
+
return right.sortScore - left.sortScore;
|
|
6946
|
+
}
|
|
6947
|
+
return left.label.localeCompare(right.label);
|
|
6948
|
+
}).slice(0, limit);
|
|
6949
|
+
}
|
|
6950
|
+
var STATUS_LABELS = {
|
|
6951
|
+
idle: "Idle",
|
|
6952
|
+
incomplete: "Incomplete",
|
|
6953
|
+
"missing-node": "Missing node",
|
|
6954
|
+
"not-found": "No path",
|
|
6955
|
+
found: "Path found"
|
|
6956
|
+
};
|
|
6957
|
+
var STATUS_COLORS = {
|
|
6958
|
+
idle: "gray",
|
|
6204
6959
|
incomplete: "yellow",
|
|
6205
6960
|
"missing-node": "red",
|
|
6206
6961
|
"not-found": "orange",
|
|
@@ -6312,6 +7067,16 @@ var EMPTY_TRACE_SELECTION = {
|
|
|
6312
7067
|
sourceId: null,
|
|
6313
7068
|
targetId: null
|
|
6314
7069
|
};
|
|
7070
|
+
var EMPTY_GRAPH_HIDDEN_IDS = /* @__PURE__ */ new Set();
|
|
7071
|
+
var EMPTY_GRAPH_HIDDEN_EDGE_IDS = /* @__PURE__ */ new Set();
|
|
7072
|
+
var EMPTY_EXPANDED_NODE_IDS = /* @__PURE__ */ new Set();
|
|
7073
|
+
var EMPTY_EXPANDED_EDGE_IDS = /* @__PURE__ */ new Set();
|
|
7074
|
+
var DEFAULT_EXPAND_AROUND_VALUE = {
|
|
7075
|
+
direction: "both",
|
|
7076
|
+
maxDepth: 1,
|
|
7077
|
+
maxResults: 25,
|
|
7078
|
+
includeHiddenResources: true
|
|
7079
|
+
};
|
|
6315
7080
|
var FALLBACK_GRAPH_THEME = {
|
|
6316
7081
|
primary: "#4a6e8e",
|
|
6317
7082
|
background: "#030507",
|
|
@@ -6324,6 +7089,12 @@ var FALLBACK_GRAPH_THEME = {
|
|
|
6324
7089
|
warning: "#ffb74d",
|
|
6325
7090
|
error: "#ff5252"
|
|
6326
7091
|
};
|
|
7092
|
+
function truncateGraphLabel(value, maxLength) {
|
|
7093
|
+
if (value.length <= maxLength) {
|
|
7094
|
+
return value;
|
|
7095
|
+
}
|
|
7096
|
+
return `${value.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
7097
|
+
}
|
|
6327
7098
|
function parseColor(input) {
|
|
6328
7099
|
const value = input.trim();
|
|
6329
7100
|
if (value.startsWith("#")) {
|
|
@@ -6455,12 +7226,12 @@ function getEdgeColor(edge, tokens) {
|
|
|
6455
7226
|
}
|
|
6456
7227
|
function getNodeSize(kind) {
|
|
6457
7228
|
if (kind === "organization") {
|
|
6458
|
-
return { width:
|
|
7229
|
+
return { width: 230, height: 88 };
|
|
6459
7230
|
}
|
|
6460
7231
|
if (kind === "resource") {
|
|
6461
|
-
return { width:
|
|
7232
|
+
return { width: 154, height: 54 };
|
|
6462
7233
|
}
|
|
6463
|
-
return { width:
|
|
7234
|
+
return { width: 174, height: 66 };
|
|
6464
7235
|
}
|
|
6465
7236
|
function getNodeScore(node, graph) {
|
|
6466
7237
|
const relationshipCount = graph.edges.filter((edge) => edge.sourceId === node.id || edge.targetId === node.id).length;
|
|
@@ -6479,8 +7250,13 @@ function getCommandViewRingColor(level, tokens) {
|
|
|
6479
7250
|
return mixColors(tokens.textDimmed, tokens.border, 0.6);
|
|
6480
7251
|
}
|
|
6481
7252
|
}
|
|
6482
|
-
function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId) {
|
|
7253
|
+
function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId, visualizationMode, selectedElement) {
|
|
6483
7254
|
const nodeThemeByKind = getNodeThemeByKind(tokens);
|
|
7255
|
+
const presetPositions = getCommandViewGraphPositions({
|
|
7256
|
+
graph,
|
|
7257
|
+
visualizationMode,
|
|
7258
|
+
selectedNodeId: selectedElement?.type === "node" ? selectedElement.id : null
|
|
7259
|
+
});
|
|
6484
7260
|
return [
|
|
6485
7261
|
...graph.nodes.map((node) => {
|
|
6486
7262
|
const size = getNodeSize(node.kind);
|
|
@@ -6488,19 +7264,22 @@ function toCytoscapeElementsWithHealth(graph, tokens, commandViewHealthByNodeId)
|
|
|
6488
7264
|
const health = commandViewHealthByNodeId?.get(node.id) ?? null;
|
|
6489
7265
|
const fillColor = health && node.kind === "resource" ? mixColors(tokens.surfaceHover, tokens.background, 0.76) : theme.background;
|
|
6490
7266
|
const borderColor = health ? getCommandViewRingColor(health.healthLevel, tokens) : theme.border;
|
|
6491
|
-
const
|
|
6492
|
-
|
|
7267
|
+
const maxLabelLength = node.kind === "resource" ? 22 : 30;
|
|
7268
|
+
const label = truncateGraphLabel(node.label, maxLabelLength);
|
|
7269
|
+
const displayLabel = health ? `${label}
|
|
7270
|
+
${health.summaryLabel}` : label;
|
|
6493
7271
|
return {
|
|
6494
7272
|
data: {
|
|
6495
7273
|
...node,
|
|
6496
7274
|
width: size.width,
|
|
6497
7275
|
height: size.height,
|
|
6498
7276
|
score: getNodeScore(node, graph),
|
|
6499
|
-
label,
|
|
7277
|
+
label: displayLabel,
|
|
6500
7278
|
fillColor,
|
|
6501
7279
|
borderColor,
|
|
6502
7280
|
textColor: health ? tokens.text : theme.color
|
|
6503
|
-
}
|
|
7281
|
+
},
|
|
7282
|
+
position: presetPositions.get(node.id)
|
|
6504
7283
|
};
|
|
6505
7284
|
}),
|
|
6506
7285
|
...graph.edges.map((edge) => ({
|
|
@@ -6526,9 +7305,9 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
6526
7305
|
name: "concentric",
|
|
6527
7306
|
fit: true,
|
|
6528
7307
|
animate: true,
|
|
6529
|
-
animationDuration:
|
|
6530
|
-
padding:
|
|
6531
|
-
spacingFactor: 1
|
|
7308
|
+
animationDuration: 220,
|
|
7309
|
+
padding: 48,
|
|
7310
|
+
spacingFactor: 1,
|
|
6532
7311
|
concentric: (node) => {
|
|
6533
7312
|
if (node.id() === impactRootId) {
|
|
6534
7313
|
return 20;
|
|
@@ -6543,24 +7322,19 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
6543
7322
|
name: "breadthfirst",
|
|
6544
7323
|
fit: true,
|
|
6545
7324
|
animate: true,
|
|
6546
|
-
animationDuration:
|
|
7325
|
+
animationDuration: 220,
|
|
6547
7326
|
directed: true,
|
|
6548
7327
|
circle: false,
|
|
6549
|
-
spacingFactor: 1.
|
|
6550
|
-
padding:
|
|
7328
|
+
spacingFactor: 1.08,
|
|
7329
|
+
padding: 48,
|
|
6551
7330
|
roots
|
|
6552
7331
|
};
|
|
6553
7332
|
}
|
|
6554
7333
|
return {
|
|
6555
|
-
name: "
|
|
7334
|
+
name: "preset",
|
|
6556
7335
|
fit: true,
|
|
6557
|
-
animate:
|
|
6558
|
-
|
|
6559
|
-
padding: 56,
|
|
6560
|
-
nodeRepulsion: 72e4,
|
|
6561
|
-
idealEdgeLength: 160,
|
|
6562
|
-
edgeElasticity: 120,
|
|
6563
|
-
gravity: 0.3
|
|
7336
|
+
animate: false,
|
|
7337
|
+
padding: 48
|
|
6564
7338
|
};
|
|
6565
7339
|
}
|
|
6566
7340
|
function createCytoscapeStyle(tokens) {
|
|
@@ -6580,13 +7354,13 @@ function createCytoscapeStyle(tokens) {
|
|
|
6580
7354
|
"border-style": "solid",
|
|
6581
7355
|
"border-color": "data(borderColor)",
|
|
6582
7356
|
color: "data(textColor)",
|
|
6583
|
-
"font-size":
|
|
7357
|
+
"font-size": 10,
|
|
6584
7358
|
"font-weight": 700,
|
|
6585
7359
|
"text-wrap": "wrap",
|
|
6586
|
-
"text-max-width": "
|
|
7360
|
+
"text-max-width": "120px",
|
|
6587
7361
|
"text-valign": "center",
|
|
6588
7362
|
"text-halign": "center",
|
|
6589
|
-
padding: "
|
|
7363
|
+
padding: "10px",
|
|
6590
7364
|
"overlay-opacity": 0,
|
|
6591
7365
|
"text-outline-width": 0
|
|
6592
7366
|
}
|
|
@@ -6596,14 +7370,25 @@ function createCytoscapeStyle(tokens) {
|
|
|
6596
7370
|
style: {
|
|
6597
7371
|
shape: "cut-rectangle",
|
|
6598
7372
|
"border-width": 3,
|
|
6599
|
-
"font-size":
|
|
7373
|
+
"font-size": 13
|
|
7374
|
+
}
|
|
7375
|
+
},
|
|
7376
|
+
{
|
|
7377
|
+
selector: 'node[kind = "resource"]',
|
|
7378
|
+
style: {
|
|
7379
|
+
"border-width": 1.5,
|
|
7380
|
+
"font-size": 8,
|
|
7381
|
+
"font-weight": 650,
|
|
7382
|
+
"text-max-width": "104px",
|
|
7383
|
+
"background-opacity": 0.82,
|
|
7384
|
+
"min-zoomed-font-size": 7
|
|
6600
7385
|
}
|
|
6601
7386
|
},
|
|
6602
7387
|
{
|
|
6603
7388
|
selector: "edge",
|
|
6604
7389
|
style: {
|
|
6605
|
-
width:
|
|
6606
|
-
label: "
|
|
7390
|
+
width: 1.25,
|
|
7391
|
+
label: "",
|
|
6607
7392
|
color: tokens.text,
|
|
6608
7393
|
"font-size": 10,
|
|
6609
7394
|
"font-weight": 700,
|
|
@@ -6618,20 +7403,26 @@ function createCytoscapeStyle(tokens) {
|
|
|
6618
7403
|
"text-border-opacity": 0,
|
|
6619
7404
|
"text-rotation": "autorotate",
|
|
6620
7405
|
"overlay-opacity": 0,
|
|
6621
|
-
"line-opacity": 0.
|
|
7406
|
+
"line-opacity": 0.38
|
|
7407
|
+
}
|
|
7408
|
+
},
|
|
7409
|
+
{
|
|
7410
|
+
selector: ".is-hidden",
|
|
7411
|
+
style: {
|
|
7412
|
+
display: "none"
|
|
6622
7413
|
}
|
|
6623
7414
|
},
|
|
6624
7415
|
{
|
|
6625
7416
|
selector: 'edge[relationshipType = "triggers"]',
|
|
6626
7417
|
style: {
|
|
6627
|
-
width:
|
|
7418
|
+
width: 1.9,
|
|
6628
7419
|
"line-style": "dashed"
|
|
6629
7420
|
}
|
|
6630
7421
|
},
|
|
6631
7422
|
{
|
|
6632
7423
|
selector: ".is-faded",
|
|
6633
7424
|
style: {
|
|
6634
|
-
opacity: 0.
|
|
7425
|
+
opacity: 0.1
|
|
6635
7426
|
}
|
|
6636
7427
|
},
|
|
6637
7428
|
{
|
|
@@ -6644,7 +7435,8 @@ function createCytoscapeStyle(tokens) {
|
|
|
6644
7435
|
selector: "edge.is-connected",
|
|
6645
7436
|
style: {
|
|
6646
7437
|
opacity: 1,
|
|
6647
|
-
width:
|
|
7438
|
+
width: 2.9,
|
|
7439
|
+
"line-opacity": 0.9
|
|
6648
7440
|
}
|
|
6649
7441
|
},
|
|
6650
7442
|
{
|
|
@@ -6652,7 +7444,8 @@ function createCytoscapeStyle(tokens) {
|
|
|
6652
7444
|
style: {
|
|
6653
7445
|
opacity: 1,
|
|
6654
7446
|
"border-color": selectedBorder,
|
|
6655
|
-
"border-width": 3
|
|
7447
|
+
"border-width": 3.5,
|
|
7448
|
+
"background-opacity": 1
|
|
6656
7449
|
}
|
|
6657
7450
|
},
|
|
6658
7451
|
{
|
|
@@ -6675,7 +7468,9 @@ function createCytoscapeStyle(tokens) {
|
|
|
6675
7468
|
selector: "edge.is-selected",
|
|
6676
7469
|
style: {
|
|
6677
7470
|
opacity: 1,
|
|
6678
|
-
width: 4.2
|
|
7471
|
+
width: 4.2,
|
|
7472
|
+
"line-opacity": 1,
|
|
7473
|
+
label: "data(label)"
|
|
6679
7474
|
}
|
|
6680
7475
|
},
|
|
6681
7476
|
{
|
|
@@ -6683,25 +7478,81 @@ function createCytoscapeStyle(tokens) {
|
|
|
6683
7478
|
style: {
|
|
6684
7479
|
opacity: 1,
|
|
6685
7480
|
width: 4.6,
|
|
7481
|
+
"line-opacity": 1,
|
|
7482
|
+
label: "data(label)",
|
|
6686
7483
|
"line-color": traceBorder,
|
|
6687
7484
|
"target-arrow-color": traceBorder,
|
|
6688
7485
|
"line-style": "solid"
|
|
6689
7486
|
}
|
|
7487
|
+
},
|
|
7488
|
+
{
|
|
7489
|
+
selector: "node.is-expanded-node",
|
|
7490
|
+
style: {
|
|
7491
|
+
opacity: 1,
|
|
7492
|
+
"border-color": mixColors(tokens.primary, tokens.warning, 0.72),
|
|
7493
|
+
"border-width": 3.4,
|
|
7494
|
+
"background-opacity": 1
|
|
7495
|
+
}
|
|
7496
|
+
},
|
|
7497
|
+
{
|
|
7498
|
+
selector: "edge.is-expanded-edge",
|
|
7499
|
+
style: {
|
|
7500
|
+
opacity: 1,
|
|
7501
|
+
width: 3.4,
|
|
7502
|
+
"line-opacity": 0.94,
|
|
7503
|
+
label: "data(label)"
|
|
7504
|
+
}
|
|
6690
7505
|
}
|
|
6691
7506
|
];
|
|
6692
7507
|
}
|
|
6693
|
-
function syncGraphClasses(cy, selectedElement, traceResult) {
|
|
7508
|
+
function syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds, expandedNodeIds, expandedEdgeIds) {
|
|
6694
7509
|
cy.batch(() => {
|
|
6695
7510
|
cy.elements().removeClass(
|
|
6696
|
-
"is-faded is-context is-selected is-connected is-trace-node is-trace-edge is-trace-endpoint"
|
|
7511
|
+
"is-hidden is-faded is-context is-selected is-connected is-trace-node is-trace-edge is-trace-endpoint is-expanded-node is-expanded-edge"
|
|
6697
7512
|
);
|
|
7513
|
+
for (const nodeId2 of hiddenIds) {
|
|
7514
|
+
const node = cy.getElementById(nodeId2);
|
|
7515
|
+
if (!node.empty()) {
|
|
7516
|
+
node.addClass("is-hidden");
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7519
|
+
for (const edgeId2 of hiddenEdgeIds) {
|
|
7520
|
+
const edge2 = cy.getElementById(edgeId2);
|
|
7521
|
+
if (!edge2.empty()) {
|
|
7522
|
+
edge2.addClass("is-hidden");
|
|
7523
|
+
}
|
|
7524
|
+
}
|
|
6698
7525
|
const hasTrace = Boolean(
|
|
6699
7526
|
traceResult && (traceResult.highlightNodeIds.length > 0 || traceResult.highlightEdgeIds.length > 0)
|
|
6700
7527
|
);
|
|
6701
7528
|
if (!selectedElement && !hasTrace) {
|
|
7529
|
+
for (const nodeId2 of expandedNodeIds) {
|
|
7530
|
+
const node = cy.getElementById(nodeId2);
|
|
7531
|
+
if (!node.empty()) {
|
|
7532
|
+
node.addClass("is-expanded-node");
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
for (const edgeId2 of expandedEdgeIds) {
|
|
7536
|
+
const edge2 = cy.getElementById(edgeId2);
|
|
7537
|
+
if (!edge2.empty()) {
|
|
7538
|
+
edge2.addClass("is-expanded-edge");
|
|
7539
|
+
}
|
|
7540
|
+
}
|
|
6702
7541
|
return;
|
|
6703
7542
|
}
|
|
6704
7543
|
cy.elements().addClass("is-faded");
|
|
7544
|
+
for (const nodeId2 of expandedNodeIds) {
|
|
7545
|
+
const node = cy.getElementById(nodeId2);
|
|
7546
|
+
if (!node.empty()) {
|
|
7547
|
+
node.removeClass("is-faded").addClass("is-context is-expanded-node");
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7550
|
+
for (const edgeId2 of expandedEdgeIds) {
|
|
7551
|
+
const edge2 = cy.getElementById(edgeId2);
|
|
7552
|
+
if (!edge2.empty()) {
|
|
7553
|
+
edge2.removeClass("is-faded").addClass("is-connected is-expanded-edge");
|
|
7554
|
+
}
|
|
7555
|
+
}
|
|
6705
7556
|
if (traceResult) {
|
|
6706
7557
|
for (const nodeId2 of traceResult.highlightNodeIds) {
|
|
6707
7558
|
const node = cy.getElementById(nodeId2);
|
|
@@ -6748,24 +7599,58 @@ function syncGraphClasses(cy, selectedElement, traceResult) {
|
|
|
6748
7599
|
edge.connectedNodes().addClass("is-selected");
|
|
6749
7600
|
});
|
|
6750
7601
|
}
|
|
7602
|
+
function syncCytoscapeElements(cy, elements) {
|
|
7603
|
+
const nextIds = new Set(elements.map((element) => element.data.id));
|
|
7604
|
+
cy.batch(() => {
|
|
7605
|
+
cy.elements().forEach((element) => {
|
|
7606
|
+
if (!nextIds.has(element.id())) {
|
|
7607
|
+
element.remove();
|
|
7608
|
+
}
|
|
7609
|
+
});
|
|
7610
|
+
for (const element of elements) {
|
|
7611
|
+
const id = element.data.id;
|
|
7612
|
+
const existing = cy.getElementById(id);
|
|
7613
|
+
if (existing.empty()) {
|
|
7614
|
+
cy.add(element);
|
|
7615
|
+
continue;
|
|
7616
|
+
}
|
|
7617
|
+
existing.data(element.data);
|
|
7618
|
+
if ("position" in element && element.position && existing.isNode()) {
|
|
7619
|
+
existing.position(element.position);
|
|
7620
|
+
}
|
|
7621
|
+
}
|
|
7622
|
+
});
|
|
7623
|
+
}
|
|
6751
7624
|
function OrganizationGraphCanvas({
|
|
6752
7625
|
graph,
|
|
6753
7626
|
mode,
|
|
7627
|
+
visualizationMode,
|
|
6754
7628
|
selectedElement,
|
|
6755
7629
|
traceResult,
|
|
7630
|
+
hiddenIds,
|
|
7631
|
+
hiddenEdgeIds,
|
|
7632
|
+
expandedNodeIds,
|
|
7633
|
+
expandedEdgeIds,
|
|
6756
7634
|
themeTokens,
|
|
6757
7635
|
commandViewHealthByNodeId,
|
|
6758
7636
|
focusRequest,
|
|
7637
|
+
toolbar,
|
|
6759
7638
|
onSelectElement
|
|
6760
7639
|
}) {
|
|
6761
7640
|
const containerRef = useRef(null);
|
|
6762
7641
|
const cytoscapeRef = useRef(null);
|
|
6763
7642
|
const previousModeRef = useRef(mode);
|
|
7643
|
+
const onSelectElementRef = useRef(onSelectElement);
|
|
7644
|
+
const lastSizeRef = useRef(null);
|
|
7645
|
+
const layoutSelectedElement = visualizationMode === "focus" ? selectedElement : null;
|
|
6764
7646
|
const elements = useMemo(
|
|
6765
|
-
() => toCytoscapeElementsWithHealth(graph, themeTokens, commandViewHealthByNodeId),
|
|
6766
|
-
[commandViewHealthByNodeId, graph, themeTokens]
|
|
7647
|
+
() => toCytoscapeElementsWithHealth(graph, themeTokens, commandViewHealthByNodeId, visualizationMode, layoutSelectedElement),
|
|
7648
|
+
[commandViewHealthByNodeId, graph, layoutSelectedElement, themeTokens, visualizationMode]
|
|
6767
7649
|
);
|
|
6768
7650
|
const cytoscapeStyle = useMemo(() => createCytoscapeStyle(themeTokens), [themeTokens]);
|
|
7651
|
+
useEffect(() => {
|
|
7652
|
+
onSelectElementRef.current = onSelectElement;
|
|
7653
|
+
}, [onSelectElement]);
|
|
6769
7654
|
useEffect(() => {
|
|
6770
7655
|
if (!containerRef.current) {
|
|
6771
7656
|
return;
|
|
@@ -6777,32 +7662,52 @@ function OrganizationGraphCanvas({
|
|
|
6777
7662
|
layout: getLayoutOptions(mode, null, traceResult),
|
|
6778
7663
|
minZoom: 0.22,
|
|
6779
7664
|
maxZoom: 1.6,
|
|
6780
|
-
wheelSensitivity:
|
|
7665
|
+
wheelSensitivity: 1.35
|
|
6781
7666
|
});
|
|
6782
7667
|
cytoscapeRef.current = cy;
|
|
6783
7668
|
cy.on("tap", "node", (event) => {
|
|
6784
|
-
|
|
7669
|
+
onSelectElementRef.current({ type: "node", id: event.target.id() });
|
|
6785
7670
|
});
|
|
6786
7671
|
cy.on("tap", "edge", (event) => {
|
|
6787
|
-
|
|
7672
|
+
onSelectElementRef.current({ type: "edge", id: event.target.id() });
|
|
6788
7673
|
});
|
|
6789
7674
|
cy.on("tap", (event) => {
|
|
6790
7675
|
if (event.target === cy) {
|
|
6791
|
-
|
|
7676
|
+
onSelectElementRef.current(null);
|
|
6792
7677
|
}
|
|
6793
7678
|
});
|
|
6794
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
6795
|
-
|
|
6796
|
-
|
|
7679
|
+
const resizeObserver = new ResizeObserver(([entry]) => {
|
|
7680
|
+
const { width, height } = entry.contentRect;
|
|
7681
|
+
const lastSize = lastSizeRef.current;
|
|
7682
|
+
if (lastSize && Math.abs(lastSize.width - width) < 1 && Math.abs(lastSize.height - height) < 1) {
|
|
7683
|
+
return;
|
|
7684
|
+
}
|
|
7685
|
+
lastSizeRef.current = { width, height };
|
|
7686
|
+
window.requestAnimationFrame(() => {
|
|
7687
|
+
if (cy.destroyed()) {
|
|
7688
|
+
return;
|
|
7689
|
+
}
|
|
7690
|
+
cy.resize();
|
|
7691
|
+
cy.fit(void 0, 44);
|
|
7692
|
+
});
|
|
6797
7693
|
});
|
|
6798
7694
|
resizeObserver.observe(containerRef.current);
|
|
6799
|
-
syncGraphClasses(cy, selectedElement, traceResult);
|
|
7695
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds, expandedNodeIds, expandedEdgeIds);
|
|
6800
7696
|
return () => {
|
|
6801
7697
|
resizeObserver.disconnect();
|
|
6802
7698
|
cy.destroy();
|
|
6803
7699
|
cytoscapeRef.current = null;
|
|
6804
7700
|
};
|
|
6805
|
-
}, [cytoscapeStyle
|
|
7701
|
+
}, [cytoscapeStyle]);
|
|
7702
|
+
useEffect(() => {
|
|
7703
|
+
const cy = cytoscapeRef.current;
|
|
7704
|
+
if (!cy) {
|
|
7705
|
+
return;
|
|
7706
|
+
}
|
|
7707
|
+
syncCytoscapeElements(cy, elements);
|
|
7708
|
+
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
7709
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds, expandedNodeIds, expandedEdgeIds);
|
|
7710
|
+
}, [elements]);
|
|
6806
7711
|
useEffect(() => {
|
|
6807
7712
|
const cy = cytoscapeRef.current;
|
|
6808
7713
|
if (!cy) {
|
|
@@ -6810,7 +7715,7 @@ function OrganizationGraphCanvas({
|
|
|
6810
7715
|
}
|
|
6811
7716
|
const modeChanged = previousModeRef.current !== mode;
|
|
6812
7717
|
previousModeRef.current = mode;
|
|
6813
|
-
if (!modeChanged && mode === "map"
|
|
7718
|
+
if (!modeChanged && mode === "map") {
|
|
6814
7719
|
return;
|
|
6815
7720
|
}
|
|
6816
7721
|
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
@@ -6820,8 +7725,27 @@ function OrganizationGraphCanvas({
|
|
|
6820
7725
|
if (!cy) {
|
|
6821
7726
|
return;
|
|
6822
7727
|
}
|
|
6823
|
-
syncGraphClasses(cy, selectedElement, traceResult);
|
|
6824
|
-
|
|
7728
|
+
syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds, expandedNodeIds, expandedEdgeIds);
|
|
7729
|
+
if (mode === "map" && selectedElement?.type === "node") {
|
|
7730
|
+
const node = cy.getElementById(selectedElement.id);
|
|
7731
|
+
if (!node.empty()) {
|
|
7732
|
+
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
7733
|
+
cy.stop();
|
|
7734
|
+
cy.animate(
|
|
7735
|
+
{
|
|
7736
|
+
fit: {
|
|
7737
|
+
eles: visibleNeighborhood.empty() ? node : visibleNeighborhood,
|
|
7738
|
+
padding: 72
|
|
7739
|
+
},
|
|
7740
|
+
duration: 220
|
|
7741
|
+
},
|
|
7742
|
+
{
|
|
7743
|
+
easing: "ease-out-cubic"
|
|
7744
|
+
}
|
|
7745
|
+
);
|
|
7746
|
+
}
|
|
7747
|
+
}
|
|
7748
|
+
}, [expandedEdgeIds, expandedNodeIds, hiddenEdgeIds, hiddenIds, mode, selectedElement, traceResult]);
|
|
6825
7749
|
useEffect(() => {
|
|
6826
7750
|
const cy = cytoscapeRef.current;
|
|
6827
7751
|
if (!cy || !focusRequest) {
|
|
@@ -6831,13 +7755,15 @@ function OrganizationGraphCanvas({
|
|
|
6831
7755
|
if (node.empty()) {
|
|
6832
7756
|
return;
|
|
6833
7757
|
}
|
|
7758
|
+
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
7759
|
+
cy.stop();
|
|
6834
7760
|
cy.animate(
|
|
6835
7761
|
{
|
|
6836
7762
|
fit: {
|
|
6837
|
-
eles:
|
|
6838
|
-
padding:
|
|
7763
|
+
eles: visibleNeighborhood.empty() ? node : visibleNeighborhood,
|
|
7764
|
+
padding: 72
|
|
6839
7765
|
},
|
|
6840
|
-
duration:
|
|
7766
|
+
duration: 220
|
|
6841
7767
|
},
|
|
6842
7768
|
{
|
|
6843
7769
|
easing: "ease-out-cubic"
|
|
@@ -6858,25 +7784,39 @@ function OrganizationGraphCanvas({
|
|
|
6858
7784
|
},
|
|
6859
7785
|
children: [
|
|
6860
7786
|
/* @__PURE__ */ jsx(Box, { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
6861
|
-
/* @__PURE__ */
|
|
6862
|
-
|
|
7787
|
+
/* @__PURE__ */ jsxs(
|
|
7788
|
+
Group,
|
|
6863
7789
|
{
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
size: "lg",
|
|
7790
|
+
gap: "xs",
|
|
7791
|
+
wrap: "nowrap",
|
|
6867
7792
|
style: {
|
|
6868
7793
|
position: "absolute",
|
|
6869
7794
|
top: 12,
|
|
6870
7795
|
right: 12,
|
|
6871
7796
|
zIndex: 2,
|
|
6872
|
-
|
|
6873
|
-
backdropFilter: "var(--glass-blur)",
|
|
6874
|
-
color: "var(--color-text)"
|
|
7797
|
+
maxWidth: "calc(100% - 24px)"
|
|
6875
7798
|
},
|
|
6876
|
-
|
|
6877
|
-
|
|
7799
|
+
children: [
|
|
7800
|
+
toolbar,
|
|
7801
|
+
/* @__PURE__ */ jsx(Tooltip, { label: "Fit graph to view", children: /* @__PURE__ */ jsx(
|
|
7802
|
+
ActionIcon,
|
|
7803
|
+
{
|
|
7804
|
+
variant: "light",
|
|
7805
|
+
radius: "xl",
|
|
7806
|
+
size: "lg",
|
|
7807
|
+
style: {
|
|
7808
|
+
background: "var(--glass-background)",
|
|
7809
|
+
backdropFilter: "var(--glass-blur)",
|
|
7810
|
+
color: "var(--color-text)",
|
|
7811
|
+
flexShrink: 0
|
|
7812
|
+
},
|
|
7813
|
+
onClick: () => cytoscapeRef.current?.fit(void 0, 44),
|
|
7814
|
+
children: /* @__PURE__ */ jsx(IconArrowsMaximize, { size: 18 })
|
|
7815
|
+
}
|
|
7816
|
+
) })
|
|
7817
|
+
]
|
|
6878
7818
|
}
|
|
6879
|
-
)
|
|
7819
|
+
)
|
|
6880
7820
|
]
|
|
6881
7821
|
}
|
|
6882
7822
|
);
|
|
@@ -6884,6 +7824,38 @@ function OrganizationGraphCanvas({
|
|
|
6884
7824
|
function getGraphCountByKind(graph, kind) {
|
|
6885
7825
|
return graph?.nodes.filter((node) => node.kind === kind).length ?? 0;
|
|
6886
7826
|
}
|
|
7827
|
+
function getCommandViewRenderableGraph(graph) {
|
|
7828
|
+
if (!graph) {
|
|
7829
|
+
return null;
|
|
7830
|
+
}
|
|
7831
|
+
const hasSpecificParentByNodeId = /* @__PURE__ */ new Set();
|
|
7832
|
+
const hasOperationalEdgeByResourceId = /* @__PURE__ */ new Set();
|
|
7833
|
+
for (const edge of graph.edges) {
|
|
7834
|
+
if (edge.kind === "contains" && edge.sourceId !== ORGANIZATION_NODE_ID) {
|
|
7835
|
+
hasSpecificParentByNodeId.add(edge.targetId);
|
|
7836
|
+
}
|
|
7837
|
+
if (edge.kind !== "contains") {
|
|
7838
|
+
hasOperationalEdgeByResourceId.add(edge.sourceId);
|
|
7839
|
+
hasOperationalEdgeByResourceId.add(edge.targetId);
|
|
7840
|
+
}
|
|
7841
|
+
}
|
|
7842
|
+
return {
|
|
7843
|
+
...graph,
|
|
7844
|
+
edges: graph.edges.filter((edge) => {
|
|
7845
|
+
if (edge.kind !== "contains" || edge.sourceId !== ORGANIZATION_NODE_ID) {
|
|
7846
|
+
return true;
|
|
7847
|
+
}
|
|
7848
|
+
const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
|
|
7849
|
+
if (!targetNode) {
|
|
7850
|
+
return false;
|
|
7851
|
+
}
|
|
7852
|
+
if (targetNode.kind === "resource") {
|
|
7853
|
+
return !hasOperationalEdgeByResourceId.has(targetNode.id);
|
|
7854
|
+
}
|
|
7855
|
+
return !hasSpecificParentByNodeId.has(targetNode.id);
|
|
7856
|
+
})
|
|
7857
|
+
};
|
|
7858
|
+
}
|
|
6887
7859
|
function formatGeneratedTimestamp(value) {
|
|
6888
7860
|
if (!value) return "unavailable";
|
|
6889
7861
|
return new Intl.DateTimeFormat("en-US", {
|
|
@@ -6894,16 +7866,32 @@ function formatGeneratedTimestamp(value) {
|
|
|
6894
7866
|
}).format(new Date(value));
|
|
6895
7867
|
}
|
|
6896
7868
|
function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
6897
|
-
const { organizationModel
|
|
7869
|
+
const { organizationModel } = useElevasisFeatures();
|
|
6898
7870
|
const { data: commandViewData, isLoading, error } = useCommandViewData();
|
|
6899
7871
|
const { data: commandViewStats } = useCommandViewStats(timeRange, { enabled: lens === "command-view" });
|
|
6900
7872
|
const setSelectedNodeId = useCommandViewStore((state) => state.setSelectedNodeId);
|
|
7873
|
+
const visualizationMode = useCommandViewStore((state) => state.visualizationMode);
|
|
7874
|
+
const setVisualizationMode = useCommandViewStore((state) => state.setVisualizationMode);
|
|
7875
|
+
const effectiveVisualizationMode = visualizationMode === "spatial" ? "network" : visualizationMode;
|
|
7876
|
+
const resourcesHidden = useCommandViewStore((state) => state.resourcesHidden);
|
|
7877
|
+
const setResourcesHidden = useCommandViewStore((state) => state.setResourcesHidden);
|
|
7878
|
+
const diagnosticsHidden = useCommandViewStore((state) => state.diagnosticsHidden);
|
|
7879
|
+
const setDiagnosticsHidden = useCommandViewStore((state) => state.setDiagnosticsHidden);
|
|
7880
|
+
const diagnosticCategories = useCommandViewStore((state) => state.diagnosticCategories);
|
|
7881
|
+
const revealedIds = useCommandViewStore((state) => state.revealedIds);
|
|
7882
|
+
const setRevealedIds = useCommandViewStore((state) => state.setRevealedIds);
|
|
7883
|
+
const clearRevealedIds = useCommandViewStore((state) => state.clearRevealedIds);
|
|
7884
|
+
const markVisibilityInteraction = useCommandViewStore((state) => state.markVisibilityInteraction);
|
|
6901
7885
|
const lensConfig = useMemo(() => getOrganizationGraphLensConfig(lens), [lens]);
|
|
6902
7886
|
const [mode, setMode] = useState(lensConfig.initialMode);
|
|
6903
|
-
const [activePanelTab, setActivePanelTab] = useState("controls");
|
|
7887
|
+
const [activePanelTab, setActivePanelTab] = useState(lens === "command-view" ? "details" : "controls");
|
|
6904
7888
|
const [selectedElement, setSelectedElement] = useState(null);
|
|
6905
7889
|
const [focusRequest, setFocusRequest] = useState(null);
|
|
6906
7890
|
const [pathTraceSelection, setPathTraceSelection] = useState(EMPTY_TRACE_SELECTION);
|
|
7891
|
+
const [expandAroundValue, setExpandAroundValue] = useState(DEFAULT_EXPAND_AROUND_VALUE);
|
|
7892
|
+
const [expandAroundPreview, setExpandAroundPreview] = useState(null);
|
|
7893
|
+
const [appliedExpandAroundNodeIds, setAppliedExpandAroundNodeIds] = useState(EMPTY_EXPANDED_NODE_IDS);
|
|
7894
|
+
const [appliedExpandAroundEdgeIds, setAppliedExpandAroundEdgeIds] = useState(EMPTY_EXPANDED_EDGE_IDS);
|
|
6907
7895
|
const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
|
|
6908
7896
|
const toolbarResetValue = useMemo(
|
|
6909
7897
|
() => createOrganizationGraphFilters(lensConfig.initialFilters),
|
|
@@ -6913,6 +7901,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6913
7901
|
const rawThemeTokens = readGraphThemeTokens();
|
|
6914
7902
|
const themeSignature = Object.values(rawThemeTokens).join("|");
|
|
6915
7903
|
const themeTokens = useMemo(() => rawThemeTokens, [themeSignature]);
|
|
7904
|
+
useEffect(() => {
|
|
7905
|
+
if (visualizationMode === "spatial") {
|
|
7906
|
+
setVisualizationMode("network");
|
|
7907
|
+
}
|
|
7908
|
+
}, [setVisualizationMode, visualizationMode]);
|
|
6916
7909
|
const baseGraph = useMemo(() => {
|
|
6917
7910
|
if (!organizationModel) {
|
|
6918
7911
|
return null;
|
|
@@ -6930,12 +7923,54 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6930
7923
|
commandViewData
|
|
6931
7924
|
});
|
|
6932
7925
|
}, [baseGraph, commandViewData, deferredFilters]);
|
|
7926
|
+
const commandViewRevealIds = useMemo(() => {
|
|
7927
|
+
if (appliedExpandAroundNodeIds.size === 0) {
|
|
7928
|
+
return revealedIds;
|
|
7929
|
+
}
|
|
7930
|
+
return /* @__PURE__ */ new Set([...revealedIds, ...appliedExpandAroundNodeIds]);
|
|
7931
|
+
}, [appliedExpandAroundNodeIds, revealedIds]);
|
|
7932
|
+
const visibilityProjection = useMemo(() => {
|
|
7933
|
+
if (!graph || lens !== "command-view") {
|
|
7934
|
+
const resourceCount = getGraphCountByKind(graph, "resource");
|
|
7935
|
+
return {
|
|
7936
|
+
hiddenIds: /* @__PURE__ */ new Set(),
|
|
7937
|
+
hiddenEdgeIds: /* @__PURE__ */ new Set(),
|
|
7938
|
+
totalResourceCount: resourceCount,
|
|
7939
|
+
visibleResourceCount: resourceCount,
|
|
7940
|
+
hiddenResourceCount: 0,
|
|
7941
|
+
hiddenDiagnosticResourceCount: 0
|
|
7942
|
+
};
|
|
7943
|
+
}
|
|
7944
|
+
return getCommandViewVisibilityProjection({
|
|
7945
|
+
graph,
|
|
7946
|
+
commandViewData,
|
|
7947
|
+
resourcesHidden,
|
|
7948
|
+
diagnosticsHidden,
|
|
7949
|
+
diagnosticCategories,
|
|
7950
|
+
revealedIds: commandViewRevealIds,
|
|
7951
|
+
mode
|
|
7952
|
+
});
|
|
7953
|
+
}, [commandViewData, commandViewRevealIds, diagnosticCategories, diagnosticsHidden, graph, lens, mode, resourcesHidden]);
|
|
7954
|
+
const visibleGraph = useMemo(() => {
|
|
7955
|
+
if (!graph || visibilityProjection.hiddenIds.size === 0) {
|
|
7956
|
+
return graph;
|
|
7957
|
+
}
|
|
7958
|
+
return {
|
|
7959
|
+
...graph,
|
|
7960
|
+
nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
|
|
7961
|
+
edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
|
|
7962
|
+
};
|
|
7963
|
+
}, [graph, visibilityProjection]);
|
|
7964
|
+
const renderGraph = useMemo(
|
|
7965
|
+
() => lens === "command-view" ? getCommandViewRenderableGraph(visibleGraph) : visibleGraph,
|
|
7966
|
+
[lens, visibleGraph]
|
|
7967
|
+
);
|
|
6933
7968
|
const selectedGraphNode = useMemo(() => {
|
|
6934
|
-
if (!
|
|
7969
|
+
if (!visibleGraph || !selectedElement || selectedElement.type !== "node") {
|
|
6935
7970
|
return null;
|
|
6936
7971
|
}
|
|
6937
|
-
return
|
|
6938
|
-
}, [
|
|
7972
|
+
return visibleGraph.nodes.find((node) => node.id === selectedElement.id) ?? null;
|
|
7973
|
+
}, [selectedElement, visibleGraph]);
|
|
6939
7974
|
const selectedCommandViewResourceId = selectedGraphNode?.kind === "resource" ? selectedGraphNode.sourceId ?? null : null;
|
|
6940
7975
|
const isExecutableSelection = lens === "command-view" && selectedGraphNode?.kind === "resource" && (selectedGraphNode.resourceType === "agent" || selectedGraphNode.resourceType === "workflow") && Boolean(selectedCommandViewResourceId);
|
|
6941
7976
|
const isCheckpointSelection = lens === "command-view" && selectedGraphNode?.kind === "resource" && selectedGraphNode.resourceType === "human_checkpoint" && Boolean(selectedCommandViewResourceId);
|
|
@@ -6949,11 +7984,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6949
7984
|
enabled: isCheckpointSelection
|
|
6950
7985
|
});
|
|
6951
7986
|
const traceResult = useMemo(() => {
|
|
6952
|
-
if (!
|
|
7987
|
+
if (!visibleGraph) {
|
|
6953
7988
|
return null;
|
|
6954
7989
|
}
|
|
6955
|
-
return resolveOrganizationGraphPathTrace(
|
|
6956
|
-
}, [
|
|
7990
|
+
return resolveOrganizationGraphPathTrace(visibleGraph, pathTraceSelection);
|
|
7991
|
+
}, [pathTraceSelection, visibleGraph]);
|
|
6957
7992
|
const activeTraceResult = mode === "trace" ? traceResult : null;
|
|
6958
7993
|
const operationalOverview = useMemo(
|
|
6959
7994
|
() => lens === "command-view" ? getCommandViewOperationalOverview(commandViewData, commandViewStats) : null,
|
|
@@ -6977,8 +8012,8 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6977
8012
|
[baseGraph, commandViewStats, lens]
|
|
6978
8013
|
);
|
|
6979
8014
|
const visibleCommandViewHealth = useMemo(
|
|
6980
|
-
() =>
|
|
6981
|
-
[commandViewHealthByNodeId,
|
|
8015
|
+
() => visibleGraph && commandViewHealthByNodeId ? visibleGraph.nodes.map((node) => commandViewHealthByNodeId.get(node.id) ?? null).filter((entry) => entry !== null) : [],
|
|
8016
|
+
[commandViewHealthByNodeId, visibleGraph]
|
|
6982
8017
|
);
|
|
6983
8018
|
const visibleHotspots = useMemo(() => rankCommandViewHotspots(visibleCommandViewHealth), [visibleCommandViewHealth]);
|
|
6984
8019
|
const pendingCheckpointHotspot = useMemo(
|
|
@@ -6986,11 +8021,11 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6986
8021
|
[visibleCommandViewHealth]
|
|
6987
8022
|
);
|
|
6988
8023
|
const jumpToResourceOptions = useMemo(
|
|
6989
|
-
() => (
|
|
8024
|
+
() => (visibleGraph?.nodes ?? []).filter((node) => node.kind === "resource").map((node) => ({
|
|
6990
8025
|
value: node.id,
|
|
6991
8026
|
label: node.label
|
|
6992
8027
|
})).sort((left, right) => left.label.localeCompare(right.label)),
|
|
6993
|
-
[
|
|
8028
|
+
[visibleGraph]
|
|
6994
8029
|
);
|
|
6995
8030
|
const focusGraphNode = useEffectEvent((nodeId2) => {
|
|
6996
8031
|
setFocusRequest({
|
|
@@ -6998,8 +8033,45 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
6998
8033
|
nonce: Date.now()
|
|
6999
8034
|
});
|
|
7000
8035
|
});
|
|
8036
|
+
const clearExpandAroundState = useEffectEvent(() => {
|
|
8037
|
+
setExpandAroundPreview(null);
|
|
8038
|
+
setAppliedExpandAroundNodeIds(EMPTY_EXPANDED_NODE_IDS);
|
|
8039
|
+
setAppliedExpandAroundEdgeIds(EMPTY_EXPANDED_EDGE_IDS);
|
|
8040
|
+
});
|
|
8041
|
+
const previewExpandAround = useEffectEvent(() => {
|
|
8042
|
+
if (lens !== "command-view" || !graph || selectedElement?.type !== "node") {
|
|
8043
|
+
setExpandAroundPreview(null);
|
|
8044
|
+
return;
|
|
8045
|
+
}
|
|
8046
|
+
setExpandAroundPreview(
|
|
8047
|
+
expandAroundGraph(
|
|
8048
|
+
graph,
|
|
8049
|
+
{
|
|
8050
|
+
rootNodeId: selectedElement.id,
|
|
8051
|
+
...expandAroundValue
|
|
8052
|
+
},
|
|
8053
|
+
{
|
|
8054
|
+
alreadyVisibleNodeIds: visibleGraph?.nodes.map((node) => node.id) ?? [],
|
|
8055
|
+
hiddenResourceNodeIds: visibilityProjection.hiddenIds
|
|
8056
|
+
}
|
|
8057
|
+
)
|
|
8058
|
+
);
|
|
8059
|
+
});
|
|
8060
|
+
const applyExpandAroundPreview = useEffectEvent(() => {
|
|
8061
|
+
if (!expandAroundPreview || selectedElement?.type !== "node") {
|
|
8062
|
+
return;
|
|
8063
|
+
}
|
|
8064
|
+
setAppliedExpandAroundNodeIds(new Set(expandAroundPreview.expandedNodeIds));
|
|
8065
|
+
setAppliedExpandAroundEdgeIds(new Set(expandAroundPreview.expandedEdgeIds));
|
|
8066
|
+
setMode("map");
|
|
8067
|
+
setSelectedElement({ type: "node", id: selectedElement.id });
|
|
8068
|
+
focusGraphNode(selectedElement.id);
|
|
8069
|
+
if (expandAroundPreview.counts.hiddenResourceNodes > 0) {
|
|
8070
|
+
markVisibilityInteraction();
|
|
8071
|
+
}
|
|
8072
|
+
});
|
|
7001
8073
|
const focusCommandViewResource = useEffectEvent((resourceId) => {
|
|
7002
|
-
const focusNode =
|
|
8074
|
+
const focusNode = visibleGraph?.nodes.find((node) => node.kind === "resource" && node.sourceId === resourceId);
|
|
7003
8075
|
if (!focusNode) {
|
|
7004
8076
|
return;
|
|
7005
8077
|
}
|
|
@@ -7007,26 +8079,82 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7007
8079
|
setSelectedElement({ type: "node", id: focusNode.id });
|
|
7008
8080
|
focusGraphNode(focusNode.id);
|
|
7009
8081
|
});
|
|
8082
|
+
const handleResetFilters = useEffectEvent(() => {
|
|
8083
|
+
resetFilters();
|
|
8084
|
+
clearRevealedIds();
|
|
8085
|
+
clearExpandAroundState();
|
|
8086
|
+
setSelectedElement(null);
|
|
8087
|
+
setPathTraceSelection(EMPTY_TRACE_SELECTION);
|
|
8088
|
+
});
|
|
8089
|
+
const handleResourcesHiddenChange = useEffectEvent((value) => {
|
|
8090
|
+
setResourcesHidden(value);
|
|
8091
|
+
if (value) {
|
|
8092
|
+
clearRevealedIds();
|
|
8093
|
+
clearExpandAroundState();
|
|
8094
|
+
setSelectedElement(null);
|
|
8095
|
+
}
|
|
8096
|
+
});
|
|
8097
|
+
const handleDiagnosticsHiddenChange = useEffectEvent((value) => {
|
|
8098
|
+
setDiagnosticsHidden(value);
|
|
8099
|
+
if (value) {
|
|
8100
|
+
clearRevealedIds();
|
|
8101
|
+
clearExpandAroundState();
|
|
8102
|
+
}
|
|
8103
|
+
});
|
|
8104
|
+
const revealAllResources = useEffectEvent(() => {
|
|
8105
|
+
setResourcesHidden(false);
|
|
8106
|
+
setDiagnosticsHidden(false);
|
|
8107
|
+
clearRevealedIds();
|
|
8108
|
+
clearExpandAroundState();
|
|
8109
|
+
});
|
|
7010
8110
|
const handleSelectElement = useEffectEvent((element) => {
|
|
7011
8111
|
if (!element) {
|
|
8112
|
+
if (!selectedElement && revealedIds.size === 0 && appliedExpandAroundNodeIds.size === 0) {
|
|
8113
|
+
return;
|
|
8114
|
+
}
|
|
7012
8115
|
setSelectedElement(null);
|
|
8116
|
+
clearRevealedIds();
|
|
8117
|
+
clearExpandAroundState();
|
|
7013
8118
|
return;
|
|
7014
8119
|
}
|
|
7015
8120
|
if (mode === "map" && element.type === "node" && selectedElement?.type === "node" && selectedElement.id === element.id) {
|
|
7016
8121
|
setActivePanelTab("details");
|
|
7017
8122
|
return;
|
|
7018
8123
|
}
|
|
8124
|
+
if (lens === "command-view" && element.type === "node" && graph) {
|
|
8125
|
+
const connectedHiddenIds = getConnectedHiddenResourceIds(graph, element.id, visibilityProjection.hiddenIds);
|
|
8126
|
+
setRevealedIds(connectedHiddenIds);
|
|
8127
|
+
if (connectedHiddenIds.size > 0) {
|
|
8128
|
+
markVisibilityInteraction();
|
|
8129
|
+
}
|
|
8130
|
+
} else {
|
|
8131
|
+
clearRevealedIds();
|
|
8132
|
+
clearExpandAroundState();
|
|
8133
|
+
}
|
|
8134
|
+
setExpandAroundPreview(null);
|
|
7019
8135
|
setSelectedElement(element);
|
|
7020
8136
|
});
|
|
7021
8137
|
useEffect(() => {
|
|
7022
8138
|
if (!graph || !selectedElement) {
|
|
7023
8139
|
return;
|
|
7024
8140
|
}
|
|
7025
|
-
const elementExists = selectedElement.type === "node" ?
|
|
8141
|
+
const elementExists = selectedElement.type === "node" ? Boolean(visibleGraph?.nodes.some((node) => node.id === selectedElement.id)) : Boolean(visibleGraph?.edges.some((edge) => edge.id === selectedElement.id));
|
|
7026
8142
|
if (!elementExists) {
|
|
7027
8143
|
setSelectedElement(null);
|
|
8144
|
+
clearRevealedIds();
|
|
8145
|
+
clearExpandAroundState();
|
|
8146
|
+
}
|
|
8147
|
+
}, [clearExpandAroundState, clearRevealedIds, selectedElement, visibleGraph]);
|
|
8148
|
+
useEffect(() => {
|
|
8149
|
+
if (lens !== "command-view" || !graph || appliedExpandAroundNodeIds.size === 0) {
|
|
8150
|
+
return;
|
|
8151
|
+
}
|
|
8152
|
+
const graphNodeIds = new Set(graph.nodes.map((node) => node.id));
|
|
8153
|
+
const expansionStillExists = [...appliedExpandAroundNodeIds].some((nodeId2) => graphNodeIds.has(nodeId2));
|
|
8154
|
+
if (!expansionStillExists) {
|
|
8155
|
+
clearExpandAroundState();
|
|
7028
8156
|
}
|
|
7029
|
-
}, [graph,
|
|
8157
|
+
}, [appliedExpandAroundNodeIds, clearExpandAroundState, graph, lens]);
|
|
7030
8158
|
useEffect(() => {
|
|
7031
8159
|
if (lens !== "command-view") {
|
|
7032
8160
|
return;
|
|
@@ -7049,7 +8177,7 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7049
8177
|
});
|
|
7050
8178
|
return;
|
|
7051
8179
|
}
|
|
7052
|
-
const visibleNodeIds = new Set(
|
|
8180
|
+
const visibleNodeIds = new Set(visibleGraph?.nodes.map((node) => node.id) ?? []);
|
|
7053
8181
|
setPathTraceSelection((current) => {
|
|
7054
8182
|
const sourceId = current.sourceId && visibleNodeIds.has(current.sourceId) ? current.sourceId : null;
|
|
7055
8183
|
const targetId = current.targetId && visibleNodeIds.has(current.targetId) ? current.targetId : null;
|
|
@@ -7058,14 +8186,14 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7058
8186
|
}
|
|
7059
8187
|
return { sourceId, targetId };
|
|
7060
8188
|
});
|
|
7061
|
-
}, [graph]);
|
|
8189
|
+
}, [graph, visibleGraph]);
|
|
7062
8190
|
if (!organizationModel) {
|
|
7063
8191
|
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
7064
8192
|
/* @__PURE__ */ jsx(
|
|
7065
8193
|
PageTitleCaption,
|
|
7066
8194
|
{
|
|
7067
|
-
title: "
|
|
7068
|
-
caption: "
|
|
8195
|
+
title: lens === "command-view" ? "Command View" : "Operations Graph",
|
|
8196
|
+
caption: "This surface needs an organization model before it can render."
|
|
7069
8197
|
}
|
|
7070
8198
|
),
|
|
7071
8199
|
/* @__PURE__ */ jsx(Paper, { withBorder: true, p: "xl", children: /* @__PURE__ */ jsx(
|
|
@@ -7078,363 +8206,377 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7078
8206
|
) })
|
|
7079
8207
|
] });
|
|
7080
8208
|
}
|
|
7081
|
-
return /* @__PURE__ */ jsx(Stack, { gap: "lg", style: { flex: 1, minHeight: 0
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
8209
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "lg", style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsx(Tabs, { value: activePanelTab, onChange: setActivePanelTab, keepMounted: false, children: /* @__PURE__ */ jsxs(
|
|
8210
|
+
Paper,
|
|
8211
|
+
{
|
|
8212
|
+
withBorder: true,
|
|
8213
|
+
radius: "md",
|
|
8214
|
+
style: {
|
|
8215
|
+
display: "flex",
|
|
8216
|
+
flexDirection: "column",
|
|
8217
|
+
minHeight: 0,
|
|
8218
|
+
background: "var(--color-surface)",
|
|
8219
|
+
boxShadow: "var(--card-shadow)",
|
|
8220
|
+
overflow: "hidden"
|
|
8221
|
+
},
|
|
8222
|
+
children: [
|
|
8223
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
8224
|
+
CommandViewHealthStrip,
|
|
8225
|
+
{
|
|
8226
|
+
overview: operationalOverview,
|
|
8227
|
+
hotspots: visibleHotspots,
|
|
8228
|
+
visibleResources: visibilityProjection.visibleResourceCount,
|
|
8229
|
+
hiddenResources: visibilityProjection.hiddenResourceCount,
|
|
8230
|
+
resourcesHidden,
|
|
8231
|
+
selectedLabel: selectedGraphNode?.label ?? null,
|
|
8232
|
+
onFocusHotspot: focusCommandViewResource,
|
|
8233
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
8234
|
+
onResetFocus: () => {
|
|
8235
|
+
setMode("map");
|
|
8236
|
+
setSelectedElement(null);
|
|
8237
|
+
clearRevealedIds();
|
|
8238
|
+
}
|
|
8239
|
+
}
|
|
8240
|
+
) : null,
|
|
8241
|
+
/* @__PURE__ */ jsx(
|
|
8242
|
+
Box,
|
|
8243
|
+
{
|
|
8244
|
+
style: {
|
|
8245
|
+
height: lens === "command-view" ? "54vh" : "62vh",
|
|
8246
|
+
minHeight: lens === "command-view" ? 420 : 520,
|
|
8247
|
+
maxHeight: lens === "command-view" ? 620 : void 0,
|
|
8248
|
+
position: "relative"
|
|
8249
|
+
},
|
|
8250
|
+
children: renderGraph && renderGraph.nodes.length > 0 ? /* @__PURE__ */ jsx(
|
|
7110
8251
|
OrganizationGraphCanvas,
|
|
7111
8252
|
{
|
|
7112
|
-
graph,
|
|
8253
|
+
graph: renderGraph,
|
|
7113
8254
|
mode,
|
|
8255
|
+
visualizationMode: lens === "command-view" ? effectiveVisualizationMode : "network",
|
|
7114
8256
|
selectedElement,
|
|
7115
8257
|
traceResult: activeTraceResult,
|
|
8258
|
+
hiddenIds: EMPTY_GRAPH_HIDDEN_IDS,
|
|
8259
|
+
hiddenEdgeIds: EMPTY_GRAPH_HIDDEN_EDGE_IDS,
|
|
8260
|
+
expandedNodeIds: lens === "command-view" ? appliedExpandAroundNodeIds : EMPTY_EXPANDED_NODE_IDS,
|
|
8261
|
+
expandedEdgeIds: lens === "command-view" ? appliedExpandAroundEdgeIds : EMPTY_EXPANDED_EDGE_IDS,
|
|
7116
8262
|
themeTokens,
|
|
7117
8263
|
commandViewHealthByNodeId,
|
|
7118
8264
|
focusRequest,
|
|
8265
|
+
toolbar: /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
8266
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
8267
|
+
SegmentedControl,
|
|
8268
|
+
{
|
|
8269
|
+
value: effectiveVisualizationMode,
|
|
8270
|
+
onChange: (value) => setVisualizationMode(value),
|
|
8271
|
+
size: "xs",
|
|
8272
|
+
data: COMMAND_VIEW_VISUALIZATION_MODES
|
|
8273
|
+
}
|
|
8274
|
+
) : null,
|
|
8275
|
+
/* @__PURE__ */ jsx(
|
|
8276
|
+
SegmentedControl,
|
|
8277
|
+
{
|
|
8278
|
+
value: mode,
|
|
8279
|
+
onChange: (value) => setMode(value),
|
|
8280
|
+
size: "xs",
|
|
8281
|
+
data: [
|
|
8282
|
+
{ label: "Map", value: "map" },
|
|
8283
|
+
{ label: "Trace", value: "trace" },
|
|
8284
|
+
{ label: "Impact", value: "impact" }
|
|
8285
|
+
]
|
|
8286
|
+
}
|
|
8287
|
+
)
|
|
8288
|
+
] }),
|
|
7119
8289
|
onSelectElement: handleSelectElement
|
|
7120
8290
|
}
|
|
8291
|
+
) : /* @__PURE__ */ jsx(
|
|
8292
|
+
EmptyState,
|
|
8293
|
+
{
|
|
8294
|
+
icon: IconTopologyStar3,
|
|
8295
|
+
title: "No graph elements match the current filters",
|
|
8296
|
+
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."
|
|
8297
|
+
}
|
|
8298
|
+
)
|
|
8299
|
+
}
|
|
8300
|
+
),
|
|
8301
|
+
/* @__PURE__ */ jsx(Box, { p: "xs", children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "wrap", children: [
|
|
8302
|
+
/* @__PURE__ */ jsxs(Group, { gap: "sm", wrap: "wrap", children: [
|
|
8303
|
+
/* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", children: lens === "command-view" ? "Command View" : lensConfig.title }),
|
|
8304
|
+
/* @__PURE__ */ jsxs(Tabs.List, { children: [
|
|
8305
|
+
lens === "command-view" ? null : /* @__PURE__ */ jsx(Tabs.Tab, { value: "controls", children: "Controls" }),
|
|
8306
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "trace", children: "Trace" }),
|
|
8307
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "details", children: "Details" }),
|
|
8308
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" })
|
|
8309
|
+
] })
|
|
8310
|
+
] }),
|
|
8311
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
8312
|
+
/* @__PURE__ */ jsx(
|
|
8313
|
+
Select,
|
|
8314
|
+
{
|
|
8315
|
+
placeholder: "Jump to resource",
|
|
8316
|
+
searchable: true,
|
|
8317
|
+
clearable: true,
|
|
8318
|
+
size: "xs",
|
|
8319
|
+
data: jumpToResourceOptions,
|
|
8320
|
+
value: selectedElement?.type === "node" ? selectedElement.id : null,
|
|
8321
|
+
onChange: (value) => {
|
|
8322
|
+
if (!value) {
|
|
8323
|
+
return;
|
|
8324
|
+
}
|
|
8325
|
+
setMode("map");
|
|
8326
|
+
setSelectedElement({ type: "node", id: value });
|
|
8327
|
+
focusGraphNode(value);
|
|
8328
|
+
},
|
|
8329
|
+
styles: {
|
|
8330
|
+
root: { minWidth: 220 }
|
|
8331
|
+
},
|
|
8332
|
+
nothingFoundMessage: "No matching resource"
|
|
8333
|
+
}
|
|
7121
8334
|
),
|
|
7122
8335
|
/* @__PURE__ */ jsx(
|
|
7123
|
-
|
|
8336
|
+
Button,
|
|
7124
8337
|
{
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
maxWidth: "calc(100% - 320px)"
|
|
8338
|
+
size: "xs",
|
|
8339
|
+
variant: "subtle",
|
|
8340
|
+
onClick: () => {
|
|
8341
|
+
setSelectedElement(null);
|
|
8342
|
+
clearRevealedIds();
|
|
7131
8343
|
},
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
{
|
|
7135
|
-
value: mode,
|
|
7136
|
-
onChange: (value) => setMode(value),
|
|
7137
|
-
size: "xs",
|
|
7138
|
-
data: [
|
|
7139
|
-
{ label: "Map", value: "map" },
|
|
7140
|
-
{ label: "Trace", value: "trace" },
|
|
7141
|
-
{ label: "Impact", value: "impact" }
|
|
7142
|
-
]
|
|
7143
|
-
}
|
|
7144
|
-
)
|
|
8344
|
+
disabled: !selectedElement,
|
|
8345
|
+
children: "Clear selection"
|
|
7145
8346
|
}
|
|
7146
|
-
)
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
{
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" })
|
|
7174
|
-
] })
|
|
7175
|
-
] }),
|
|
7176
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
7177
|
-
/* @__PURE__ */ jsx(
|
|
7178
|
-
Select,
|
|
7179
|
-
{
|
|
7180
|
-
placeholder: "Jump to resource",
|
|
7181
|
-
searchable: true,
|
|
7182
|
-
clearable: true,
|
|
7183
|
-
size: "xs",
|
|
7184
|
-
data: jumpToResourceOptions,
|
|
7185
|
-
value: selectedElement?.type === "node" ? selectedElement.id : null,
|
|
7186
|
-
onChange: (value) => {
|
|
7187
|
-
if (!value) {
|
|
7188
|
-
return;
|
|
7189
|
-
}
|
|
7190
|
-
setMode("map");
|
|
7191
|
-
setSelectedElement({ type: "node", id: value });
|
|
7192
|
-
focusGraphNode(value);
|
|
7193
|
-
},
|
|
7194
|
-
styles: {
|
|
7195
|
-
root: { minWidth: 220 }
|
|
7196
|
-
},
|
|
7197
|
-
nothingFoundMessage: "No matching resource"
|
|
7198
|
-
}
|
|
7199
|
-
),
|
|
7200
|
-
/* @__PURE__ */ jsx(
|
|
7201
|
-
Button,
|
|
7202
|
-
{
|
|
7203
|
-
size: "xs",
|
|
7204
|
-
variant: "subtle",
|
|
7205
|
-
onClick: () => setSelectedElement(null),
|
|
7206
|
-
disabled: !selectedElement,
|
|
7207
|
-
children: "Clear selection"
|
|
7208
|
-
}
|
|
7209
|
-
),
|
|
7210
|
-
/* @__PURE__ */ jsx(
|
|
7211
|
-
Button,
|
|
7212
|
-
{
|
|
7213
|
-
size: "xs",
|
|
7214
|
-
variant: "subtle",
|
|
7215
|
-
onClick: () => setPathTraceSelection(EMPTY_TRACE_SELECTION),
|
|
7216
|
-
disabled: !pathTraceSelection.sourceId && !pathTraceSelection.targetId,
|
|
7217
|
-
children: "Clear trace"
|
|
7218
|
-
}
|
|
7219
|
-
),
|
|
7220
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: resetFilters, children: "Reset filters" })
|
|
7221
|
-
] })
|
|
7222
|
-
] }) }),
|
|
7223
|
-
/* @__PURE__ */ jsxs(
|
|
7224
|
-
Box,
|
|
8347
|
+
),
|
|
8348
|
+
/* @__PURE__ */ jsx(
|
|
8349
|
+
Button,
|
|
8350
|
+
{
|
|
8351
|
+
size: "xs",
|
|
8352
|
+
variant: "subtle",
|
|
8353
|
+
onClick: () => setPathTraceSelection(EMPTY_TRACE_SELECTION),
|
|
8354
|
+
disabled: !pathTraceSelection.sourceId && !pathTraceSelection.targetId,
|
|
8355
|
+
children: "Clear trace"
|
|
8356
|
+
}
|
|
8357
|
+
),
|
|
8358
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: handleResetFilters, children: "Reset filters" })
|
|
8359
|
+
] })
|
|
8360
|
+
] }) }),
|
|
8361
|
+
/* @__PURE__ */ jsxs(
|
|
8362
|
+
Box,
|
|
8363
|
+
{
|
|
8364
|
+
p: "xs",
|
|
8365
|
+
className: HIDE_SCROLLBAR_CLASS_NAME,
|
|
8366
|
+
style: {
|
|
8367
|
+
padding: "var(--mantine-spacing-md)",
|
|
8368
|
+
paddingTop: 0
|
|
8369
|
+
},
|
|
8370
|
+
children: [
|
|
8371
|
+
lens === "command-view" ? null : /* @__PURE__ */ jsx(Tabs.Panel, { value: "controls", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
8372
|
+
/* @__PURE__ */ jsx(
|
|
8373
|
+
FilterPanel,
|
|
7225
8374
|
{
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7233
|
-
|
|
7234
|
-
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
}
|
|
7254
|
-
),
|
|
7255
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "md", style: { gridColumn: "span 2" }, children: [
|
|
7256
|
-
/* @__PURE__ */ jsxs(
|
|
7257
|
-
Card,
|
|
7258
|
-
{
|
|
7259
|
-
withBorder: true,
|
|
7260
|
-
radius: "lg",
|
|
7261
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7262
|
-
children: [
|
|
7263
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Tracked runs" : "Visible nodes" }),
|
|
7264
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.totalRuns ?? 0 : graph?.nodes.length ?? 0 }),
|
|
7265
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${timeRange} execution window` : `of ${baseGraph?.nodes.length ?? 0} total` })
|
|
7266
|
-
]
|
|
7267
|
-
}
|
|
7268
|
-
),
|
|
7269
|
-
/* @__PURE__ */ jsxs(
|
|
7270
|
-
Card,
|
|
7271
|
-
{
|
|
7272
|
-
withBorder: true,
|
|
7273
|
-
radius: "lg",
|
|
7274
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7275
|
-
children: [
|
|
7276
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Success rate" : "Visible edges" }),
|
|
7277
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? `${Math.round(operationalOverview?.successRate ?? 0)}%` : graph?.edges.length ?? 0 }),
|
|
7278
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${operationalOverview?.successCount ?? 0} successful runs` : `of ${baseGraph?.edges.length ?? 0} total` })
|
|
7279
|
-
]
|
|
7280
|
-
}
|
|
7281
|
-
),
|
|
7282
|
-
/* @__PURE__ */ jsxs(
|
|
7283
|
-
Card,
|
|
7284
|
-
{
|
|
7285
|
-
withBorder: true,
|
|
7286
|
-
radius: "lg",
|
|
7287
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7288
|
-
children: [
|
|
7289
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Failing resources" : "Visible features" }),
|
|
7290
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.topFailingResources.length ?? 0 : getGraphCountByKind(graph, "feature") }),
|
|
7291
|
-
/* @__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` })
|
|
7292
|
-
]
|
|
7293
|
-
}
|
|
7294
|
-
),
|
|
7295
|
-
/* @__PURE__ */ jsxs(
|
|
7296
|
-
Card,
|
|
7297
|
-
{
|
|
7298
|
-
withBorder: true,
|
|
7299
|
-
radius: "lg",
|
|
7300
|
-
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
7301
|
-
children: [
|
|
7302
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: lens === "command-view" ? "Pending approvals" : "Visible resources" }),
|
|
7303
|
-
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: lens === "command-view" ? operationalOverview?.pendingApprovals ?? 0 : getGraphCountByKind(graph, "resource") }),
|
|
7304
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: lens === "command-view" ? `${operationalOverview?.activeHumanCheckpoints ?? 0} active checkpoint queues` : `of ${getGraphCountByKind(baseGraph, "resource")} total` })
|
|
7305
|
-
]
|
|
7306
|
-
}
|
|
7307
|
-
)
|
|
7308
|
-
] })
|
|
7309
|
-
] }),
|
|
7310
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
7311
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", children: lens === "command-view" ? "Operations lens" : "Shared graph" }),
|
|
7312
|
-
/* @__PURE__ */ jsx(
|
|
7313
|
-
Badge,
|
|
7314
|
-
{
|
|
7315
|
-
variant: "light",
|
|
7316
|
-
color: organizationGraph.available ? "var(--color-success)" : "var(--color-text-subtle)",
|
|
7317
|
-
children: organizationGraph.available ? "Provider graph surface ready" : "Provider graph surface missing"
|
|
7318
|
-
}
|
|
7319
|
-
),
|
|
7320
|
-
/* @__PURE__ */ jsx(
|
|
7321
|
-
Badge,
|
|
7322
|
-
{
|
|
7323
|
-
variant: "light",
|
|
7324
|
-
color: commandViewData ? "var(--color-primary)" : "var(--color-text-subtle)",
|
|
7325
|
-
children: commandViewData ? "Topology bridged" : isLoading ? "Topology loading" : "Semantic only"
|
|
7326
|
-
}
|
|
7327
|
-
),
|
|
7328
|
-
error ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "var(--color-error)", children: "Topology unavailable" }) : null
|
|
7329
|
-
] }),
|
|
8375
|
+
filters,
|
|
8376
|
+
onChangeFilters: updateFilters,
|
|
8377
|
+
resetValue: toolbarResetValue,
|
|
8378
|
+
disabled: !baseGraph,
|
|
8379
|
+
commandViewData,
|
|
8380
|
+
lens,
|
|
8381
|
+
resourcesHidden,
|
|
8382
|
+
diagnosticsHidden,
|
|
8383
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
8384
|
+
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
8385
|
+
onRevealResources: revealAllResources,
|
|
8386
|
+
onResetFilters: handleResetFilters,
|
|
8387
|
+
visibilityCounts: visibilityProjection,
|
|
8388
|
+
graph: visibleGraph,
|
|
8389
|
+
baseGraph
|
|
8390
|
+
}
|
|
8391
|
+
),
|
|
8392
|
+
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2, lg: 4 }, spacing: "md", children: [
|
|
8393
|
+
/* @__PURE__ */ jsxs(
|
|
8394
|
+
Card,
|
|
8395
|
+
{
|
|
8396
|
+
withBorder: true,
|
|
8397
|
+
radius: "lg",
|
|
8398
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
8399
|
+
children: [
|
|
8400
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible nodes" }),
|
|
8401
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: visibleGraph?.nodes.length ?? 0 }),
|
|
7330
8402
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7331
|
-
"
|
|
7332
|
-
|
|
7333
|
-
"
|
|
7334
|
-
graph?.edges.length ?? 0,
|
|
7335
|
-
" edges in the current projection. In map mode, single-click isolates a node neighborhood and clicking another node pivots the focus."
|
|
8403
|
+
"of ",
|
|
8404
|
+
baseGraph?.nodes.length ?? 0,
|
|
8405
|
+
" total"
|
|
7336
8406
|
] })
|
|
7337
|
-
]
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
] }) }),
|
|
7350
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "details", pt: 0, children: /* @__PURE__ */ jsx(
|
|
7351
|
-
OrganizationGraphDetailPanel,
|
|
7352
|
-
{
|
|
7353
|
-
graph,
|
|
7354
|
-
selectedElement,
|
|
7355
|
-
supplementalSummary: selectionOperationalSummary,
|
|
7356
|
-
followUpSections,
|
|
7357
|
-
onClearSelection: () => setSelectedElement(null)
|
|
7358
|
-
}
|
|
7359
|
-
) }),
|
|
7360
|
-
/* @__PURE__ */ jsx(Tabs.Panel, { value: "runtime", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
7361
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7362
|
-
"Active Lens: ",
|
|
7363
|
-
lens
|
|
7364
|
-
] }),
|
|
7365
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7366
|
-
"Feature ID: ",
|
|
7367
|
-
organizationGraph.featureId ?? "unresolved"
|
|
7368
|
-
] }),
|
|
8407
|
+
]
|
|
8408
|
+
}
|
|
8409
|
+
),
|
|
8410
|
+
/* @__PURE__ */ jsxs(
|
|
8411
|
+
Card,
|
|
8412
|
+
{
|
|
8413
|
+
withBorder: true,
|
|
8414
|
+
radius: "lg",
|
|
8415
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
8416
|
+
children: [
|
|
8417
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible edges" }),
|
|
8418
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: visibleGraph?.edges.length ?? 0 }),
|
|
7369
8419
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7370
|
-
"
|
|
7371
|
-
|
|
7372
|
-
|
|
8420
|
+
"of ",
|
|
8421
|
+
baseGraph?.edges.length ?? 0,
|
|
8422
|
+
" total"
|
|
8423
|
+
] })
|
|
8424
|
+
]
|
|
8425
|
+
}
|
|
8426
|
+
),
|
|
8427
|
+
/* @__PURE__ */ jsxs(
|
|
8428
|
+
Card,
|
|
8429
|
+
{
|
|
8430
|
+
withBorder: true,
|
|
8431
|
+
radius: "lg",
|
|
8432
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
8433
|
+
children: [
|
|
8434
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible features" }),
|
|
8435
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: getGraphCountByKind(visibleGraph, "feature") }),
|
|
7373
8436
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7374
|
-
"
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
" with",
|
|
7391
|
-
" ",
|
|
7392
|
-
pendingCheckpointHotspot.pendingCount,
|
|
7393
|
-
" pending approvals."
|
|
7394
|
-
] }) : null,
|
|
7395
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph Build: semantic derivation plus bridged Command View topology" }),
|
|
8437
|
+
"of ",
|
|
8438
|
+
getGraphCountByKind(baseGraph, "feature"),
|
|
8439
|
+
" total"
|
|
8440
|
+
] })
|
|
8441
|
+
]
|
|
8442
|
+
}
|
|
8443
|
+
),
|
|
8444
|
+
/* @__PURE__ */ jsxs(
|
|
8445
|
+
Card,
|
|
8446
|
+
{
|
|
8447
|
+
withBorder: true,
|
|
8448
|
+
radius: "lg",
|
|
8449
|
+
style: { background: "var(--color-surface)", boxShadow: "var(--card-shadow)" },
|
|
8450
|
+
children: [
|
|
8451
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Visible resources" }),
|
|
8452
|
+
/* @__PURE__ */ jsx(Text, { size: "xl", fw: 700, children: getGraphCountByKind(visibleGraph, "resource") }),
|
|
7396
8453
|
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
7397
|
-
"
|
|
7398
|
-
|
|
7399
|
-
"
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
8454
|
+
"of ",
|
|
8455
|
+
getGraphCountByKind(baseGraph, "resource"),
|
|
8456
|
+
" total"
|
|
8457
|
+
] })
|
|
8458
|
+
]
|
|
8459
|
+
}
|
|
8460
|
+
)
|
|
8461
|
+
] }),
|
|
8462
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
8463
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", children: "Command View graph" }),
|
|
8464
|
+
/* @__PURE__ */ jsx(
|
|
8465
|
+
Badge,
|
|
8466
|
+
{
|
|
8467
|
+
variant: "light",
|
|
8468
|
+
color: commandViewData ? "var(--color-primary)" : "var(--color-text-subtle)",
|
|
8469
|
+
children: commandViewData ? "Topology bridged" : isLoading ? "Topology loading" : "Semantic only"
|
|
8470
|
+
}
|
|
8471
|
+
),
|
|
8472
|
+
error ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "var(--color-error)", children: "Topology unavailable" }) : null
|
|
8473
|
+
] }),
|
|
8474
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8475
|
+
"Showing ",
|
|
8476
|
+
visibleGraph?.nodes.length ?? 0,
|
|
8477
|
+
" nodes and ",
|
|
8478
|
+
visibleGraph?.edges.length ?? 0,
|
|
8479
|
+
" edges in the current projection. In map mode, single-click isolates a node neighborhood and clicking another node pivots the focus."
|
|
8480
|
+
] })
|
|
8481
|
+
] }) }),
|
|
8482
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "trace", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
8483
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Trace mode resolves shortest directed paths inside the current filtered graph." }),
|
|
8484
|
+
visibleGraph ? /* @__PURE__ */ jsx(
|
|
8485
|
+
OrganizationGraphPathTraceControls,
|
|
8486
|
+
{
|
|
8487
|
+
graph: visibleGraph,
|
|
8488
|
+
value: pathTraceSelection,
|
|
8489
|
+
onChange: setPathTraceSelection,
|
|
8490
|
+
disabled: visibleGraph.nodes.length === 0
|
|
7410
8491
|
}
|
|
7411
|
-
)
|
|
7412
|
-
]
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
8492
|
+
) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph data is not available yet." })
|
|
8493
|
+
] }) }),
|
|
8494
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "details", pt: 0, children: /* @__PURE__ */ jsx(
|
|
8495
|
+
OrganizationGraphDetailPanel,
|
|
8496
|
+
{
|
|
8497
|
+
graph: visibleGraph,
|
|
8498
|
+
selectedElement,
|
|
8499
|
+
supplementalSummary: selectionOperationalSummary,
|
|
8500
|
+
followUpSections,
|
|
8501
|
+
expandAroundPanel: lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
8502
|
+
ExpandAroundPanel,
|
|
8503
|
+
{
|
|
8504
|
+
selectedNode: selectedGraphNode,
|
|
8505
|
+
value: expandAroundValue,
|
|
8506
|
+
result: expandAroundPreview,
|
|
8507
|
+
appliedNodeCount: appliedExpandAroundNodeIds.size,
|
|
8508
|
+
appliedEdgeCount: appliedExpandAroundEdgeIds.size,
|
|
8509
|
+
onChange: (next) => {
|
|
8510
|
+
setExpandAroundValue(next);
|
|
8511
|
+
setExpandAroundPreview(null);
|
|
8512
|
+
},
|
|
8513
|
+
onPreview: previewExpandAround,
|
|
8514
|
+
onApply: applyExpandAroundPreview,
|
|
8515
|
+
onClear: clearExpandAroundState
|
|
8516
|
+
}
|
|
8517
|
+
) : null,
|
|
8518
|
+
onClearSelection: () => {
|
|
8519
|
+
setSelectedElement(null);
|
|
8520
|
+
clearRevealedIds();
|
|
8521
|
+
clearExpandAroundState();
|
|
8522
|
+
}
|
|
8523
|
+
}
|
|
8524
|
+
) }),
|
|
8525
|
+
/* @__PURE__ */ jsx(Tabs.Panel, { value: "runtime", pt: 0, children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
8526
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8527
|
+
"Active Lens: ",
|
|
8528
|
+
lens
|
|
8529
|
+
] }),
|
|
8530
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8531
|
+
"Active Mode: ",
|
|
8532
|
+
mode
|
|
8533
|
+
] }),
|
|
8534
|
+
lens === "command-view" ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8535
|
+
"Visualization: ",
|
|
8536
|
+
effectiveVisualizationMode
|
|
8537
|
+
] }) : null,
|
|
8538
|
+
operationalOverview ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8539
|
+
"Operational Snapshot: ",
|
|
8540
|
+
operationalOverview.trackedResources,
|
|
8541
|
+
" resources,",
|
|
8542
|
+
" ",
|
|
8543
|
+
operationalOverview.pendingApprovals,
|
|
8544
|
+
" pending approvals, generated",
|
|
8545
|
+
" ",
|
|
8546
|
+
formatGeneratedTimestamp(operationalOverview.generatedAt)
|
|
8547
|
+
] }) : null,
|
|
8548
|
+
pendingCheckpointHotspot ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8549
|
+
"Active queue hotspot: ",
|
|
8550
|
+
pendingCheckpointHotspot.resourceId,
|
|
8551
|
+
" with",
|
|
8552
|
+
" ",
|
|
8553
|
+
pendingCheckpointHotspot.pendingCount,
|
|
8554
|
+
" pending approvals."
|
|
8555
|
+
] }) : null,
|
|
8556
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Graph Build: semantic derivation plus bridged Command View topology" }),
|
|
8557
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", children: [
|
|
8558
|
+
"Projection: ",
|
|
8559
|
+
visibleGraph?.nodes.length ?? 0,
|
|
8560
|
+
" visible nodes, ",
|
|
8561
|
+
visibleGraph?.edges.length ?? 0,
|
|
8562
|
+
" visible edges"
|
|
8563
|
+
] }),
|
|
8564
|
+
isLoading ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Topology bridge is still loading; semantic nodes remain available." }) : null,
|
|
8565
|
+
error ? /* @__PURE__ */ jsxs(Text, { size: "sm", c: "red", children: [
|
|
8566
|
+
"Topology bridge error: ",
|
|
8567
|
+
error.message
|
|
8568
|
+
] }) : null
|
|
8569
|
+
] }) })
|
|
8570
|
+
]
|
|
8571
|
+
}
|
|
8572
|
+
)
|
|
8573
|
+
]
|
|
8574
|
+
}
|
|
8575
|
+
) }) });
|
|
7419
8576
|
}
|
|
7420
8577
|
function CommandViewPage({ timeRange }) {
|
|
7421
8578
|
return /* @__PURE__ */ jsx(OrganizationGraphPage, { lens: "command-view", timeRange });
|
|
7422
8579
|
}
|
|
7423
|
-
var FILTER_STATE_ICONS2 = {
|
|
7424
|
-
neutral: IconCircleDashed,
|
|
7425
|
-
include: IconCircleCheck,
|
|
7426
|
-
exclude: IconCircleX
|
|
7427
|
-
};
|
|
7428
|
-
var FILTER_STATE_COLORS2 = {
|
|
7429
|
-
neutral: "var(--color-surface-hover)",
|
|
7430
|
-
include: "var(--mantine-color-green-6)",
|
|
7431
|
-
exclude: "var(--mantine-color-red-6)"
|
|
7432
|
-
};
|
|
7433
|
-
var FILTER_STATE_LABELS2 = {
|
|
7434
|
-
neutral: "Not filtered",
|
|
7435
|
-
include: "Include only",
|
|
7436
|
-
exclude: "Exclude"
|
|
7437
|
-
};
|
|
7438
8580
|
var EXECUTION_SECTIONS = [
|
|
7439
8581
|
{ status: "failed", title: "Failed Executions", badgeColor: "red" },
|
|
7440
8582
|
{ status: "warning", title: "Warning Executions", badgeColor: "yellow" },
|
|
@@ -7488,22 +8630,21 @@ function ExecutionStatusSection({ executions, status, title, badgeColor, resourc
|
|
|
7488
8630
|
function CommandViewSidebarContent({ timeRange }) {
|
|
7489
8631
|
const theme = useMantineTheme();
|
|
7490
8632
|
const colors = useCyberColors();
|
|
7491
|
-
const
|
|
8633
|
+
const { organizationModel } = useElevasisFeatures();
|
|
8634
|
+
const lensConfig = useMemo(() => getOrganizationGraphLensConfig("command-view"), []);
|
|
8635
|
+
const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
|
|
8636
|
+
const toolbarResetValue = useMemo(
|
|
8637
|
+
() => createOrganizationGraphFilters(lensConfig.initialFilters),
|
|
8638
|
+
[lensConfig.initialFilters]
|
|
8639
|
+
);
|
|
7492
8640
|
const selectedNodeId = useCommandViewStore((s) => s.selectedNodeId);
|
|
7493
|
-
const
|
|
7494
|
-
const
|
|
7495
|
-
const
|
|
7496
|
-
const
|
|
7497
|
-
const
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
updateFilters({
|
|
7501
|
-
domainFilters: {
|
|
7502
|
-
...domainFilters,
|
|
7503
|
-
[domainId]: nextState
|
|
7504
|
-
}
|
|
7505
|
-
});
|
|
7506
|
-
};
|
|
8641
|
+
const resourcesHidden = useCommandViewStore((s) => s.resourcesHidden);
|
|
8642
|
+
const setResourcesHidden = useCommandViewStore((s) => s.setResourcesHidden);
|
|
8643
|
+
const diagnosticsHidden = useCommandViewStore((s) => s.diagnosticsHidden);
|
|
8644
|
+
const setDiagnosticsHidden = useCommandViewStore((s) => s.setDiagnosticsHidden);
|
|
8645
|
+
const diagnosticCategories = useCommandViewStore((s) => s.diagnosticCategories);
|
|
8646
|
+
const revealedIds = useCommandViewStore((s) => s.revealedIds);
|
|
8647
|
+
const clearRevealedIds = useCommandViewStore((s) => s.clearRevealedIds);
|
|
7507
8648
|
const { data, isLoading } = useCommandViewData();
|
|
7508
8649
|
const { data: statsData } = useCommandViewStats(timeRange);
|
|
7509
8650
|
const cleanData = data ?? null;
|
|
@@ -7512,33 +8653,85 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7512
8653
|
if (!statsData) return cleanData;
|
|
7513
8654
|
return mergeStatsWithTopology(cleanData, statsData);
|
|
7514
8655
|
}, [cleanData, statsData]);
|
|
8656
|
+
const baseGraph = useMemo(() => {
|
|
8657
|
+
if (!organizationModel) {
|
|
8658
|
+
return null;
|
|
8659
|
+
}
|
|
8660
|
+
return buildOrganizationGraph({
|
|
8661
|
+
organizationModel,
|
|
8662
|
+
commandViewData: cleanData ?? void 0
|
|
8663
|
+
});
|
|
8664
|
+
}, [cleanData, organizationModel]);
|
|
8665
|
+
const graph = useMemo(() => {
|
|
8666
|
+
if (!baseGraph) {
|
|
8667
|
+
return null;
|
|
8668
|
+
}
|
|
8669
|
+
return filterOrganizationGraph(baseGraph, filters, {
|
|
8670
|
+
commandViewData: cleanData
|
|
8671
|
+
});
|
|
8672
|
+
}, [baseGraph, cleanData, filters]);
|
|
8673
|
+
const visibilityProjection = useMemo(() => {
|
|
8674
|
+
if (!graph) {
|
|
8675
|
+
return {
|
|
8676
|
+
hiddenIds: /* @__PURE__ */ new Set(),
|
|
8677
|
+
hiddenEdgeIds: /* @__PURE__ */ new Set(),
|
|
8678
|
+
totalResourceCount: 0,
|
|
8679
|
+
visibleResourceCount: 0,
|
|
8680
|
+
hiddenResourceCount: 0,
|
|
8681
|
+
hiddenDiagnosticResourceCount: 0
|
|
8682
|
+
};
|
|
8683
|
+
}
|
|
8684
|
+
return getCommandViewVisibilityProjection({
|
|
8685
|
+
graph,
|
|
8686
|
+
commandViewData: cleanData,
|
|
8687
|
+
resourcesHidden,
|
|
8688
|
+
diagnosticsHidden,
|
|
8689
|
+
diagnosticCategories,
|
|
8690
|
+
revealedIds,
|
|
8691
|
+
mode: "map"
|
|
8692
|
+
});
|
|
8693
|
+
}, [cleanData, diagnosticCategories, diagnosticsHidden, graph, resourcesHidden, revealedIds]);
|
|
8694
|
+
const visibleGraph = useMemo(() => {
|
|
8695
|
+
if (!graph || visibilityProjection.hiddenIds.size === 0) {
|
|
8696
|
+
return graph;
|
|
8697
|
+
}
|
|
8698
|
+
return {
|
|
8699
|
+
...graph,
|
|
8700
|
+
nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
|
|
8701
|
+
edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
|
|
8702
|
+
};
|
|
8703
|
+
}, [graph, visibilityProjection]);
|
|
8704
|
+
const handleResetFilters = () => {
|
|
8705
|
+
resetFilters();
|
|
8706
|
+
clearRevealedIds();
|
|
8707
|
+
};
|
|
8708
|
+
const handleResourcesHiddenChange = (value) => {
|
|
8709
|
+
setResourcesHidden(value);
|
|
8710
|
+
if (value) {
|
|
8711
|
+
clearRevealedIds();
|
|
8712
|
+
}
|
|
8713
|
+
};
|
|
8714
|
+
const handleDiagnosticsHiddenChange = (value) => {
|
|
8715
|
+
setDiagnosticsHidden(value);
|
|
8716
|
+
if (value) {
|
|
8717
|
+
clearRevealedIds();
|
|
8718
|
+
}
|
|
8719
|
+
};
|
|
8720
|
+
const revealAllResources = () => {
|
|
8721
|
+
setResourcesHidden(false);
|
|
8722
|
+
setDiagnosticsHidden(false);
|
|
8723
|
+
clearRevealedIds();
|
|
8724
|
+
};
|
|
7515
8725
|
const { donutSuccessCount, donutFailedCount } = useMemo(() => {
|
|
7516
8726
|
if (!cleanData || !statsData) return { donutSuccessCount: 0, donutFailedCount: 0 };
|
|
7517
|
-
const includes = Object.entries(domainFilters).filter(([, v]) => v === "include").map(([k]) => k);
|
|
7518
|
-
const excludes = Object.entries(domainFilters).filter(([, v]) => v === "exclude").map(([k]) => k);
|
|
7519
8727
|
const allResources = [
|
|
7520
8728
|
...cleanData.agents,
|
|
7521
8729
|
...cleanData.workflows,
|
|
7522
8730
|
...cleanData.triggers,
|
|
7523
|
-
...
|
|
8731
|
+
...cleanData.integrations,
|
|
7524
8732
|
...cleanData.externalResources ?? [],
|
|
7525
8733
|
...cleanData.humanCheckpoints ?? []
|
|
7526
|
-
]
|
|
7527
|
-
const facets = [
|
|
7528
|
-
...resource.category ? [`category:${resource.category}`] : [],
|
|
7529
|
-
...resource.links?.map((link) => link.nodeId) ?? []
|
|
7530
|
-
];
|
|
7531
|
-
if (excludes.length > 0 && facets.some((d) => excludes.includes(d))) return false;
|
|
7532
|
-
if (includes.length > 0 && !facets.some((d) => includes.includes(d))) return false;
|
|
7533
|
-
if (statusFilter !== "all" && resource.status !== statusFilter) return false;
|
|
7534
|
-
if (filters.resourceTypes.length > 0) {
|
|
7535
|
-
const normalizedResourceType = resource.type === "human" ? "human_checkpoint" : resource.type;
|
|
7536
|
-
if (!filters.resourceTypes.includes(normalizedResourceType)) {
|
|
7537
|
-
return false;
|
|
7538
|
-
}
|
|
7539
|
-
}
|
|
7540
|
-
return true;
|
|
7541
|
-
});
|
|
8734
|
+
];
|
|
7542
8735
|
const filteredIds = new Set(allResources.map((resource) => resource.resourceId));
|
|
7543
8736
|
let success = 0;
|
|
7544
8737
|
let failed = 0;
|
|
@@ -7549,18 +8742,7 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7549
8742
|
}
|
|
7550
8743
|
}
|
|
7551
8744
|
return { donutSuccessCount: success, donutFailedCount: failed };
|
|
7552
|
-
}, [cleanData,
|
|
7553
|
-
const resourceFacets = useMemo(() => {
|
|
7554
|
-
if (!cleanData) return [];
|
|
7555
|
-
return collectResourceFilterFacets([
|
|
7556
|
-
...cleanData.agents,
|
|
7557
|
-
...cleanData.workflows,
|
|
7558
|
-
...cleanData.triggers,
|
|
7559
|
-
...cleanData.integrations,
|
|
7560
|
-
...cleanData.externalResources ?? [],
|
|
7561
|
-
...cleanData.humanCheckpoints ?? []
|
|
7562
|
-
]);
|
|
7563
|
-
}, [cleanData]);
|
|
8745
|
+
}, [cleanData, statsData]);
|
|
7564
8746
|
const selectedNode = useMemo(() => {
|
|
7565
8747
|
if (!selectedNodeId || !dataWithStats) return null;
|
|
7566
8748
|
const allNodes = [
|
|
@@ -7624,17 +8806,18 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7624
8806
|
if (isLoading && !data) {
|
|
7625
8807
|
return /* @__PURE__ */ jsx(SubshellSidebarLoader, {});
|
|
7626
8808
|
}
|
|
7627
|
-
return /* @__PURE__ */
|
|
8809
|
+
return /* @__PURE__ */ jsx(
|
|
7628
8810
|
Box,
|
|
7629
8811
|
{
|
|
7630
8812
|
style: {
|
|
7631
8813
|
flex: 1,
|
|
8814
|
+
height: "100%",
|
|
7632
8815
|
minHeight: 0,
|
|
7633
8816
|
display: "flex",
|
|
7634
8817
|
flexDirection: "column",
|
|
7635
8818
|
overflow: "hidden"
|
|
7636
8819
|
},
|
|
7637
|
-
children: [
|
|
8820
|
+
children: /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", overflowX: "hidden" }, children: [
|
|
7638
8821
|
/* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconSitemap, label: "Command View" }),
|
|
7639
8822
|
/* @__PURE__ */ jsx(Box, { style: { padding: theme.spacing.sm, paddingBottom: 0 }, children: /* @__PURE__ */ jsx(Box, { pb: "xs", mb: 4, children: /* @__PURE__ */ jsx(
|
|
7640
8823
|
CyberDonut,
|
|
@@ -7648,165 +8831,105 @@ function CommandViewSidebarContent({ timeRange }) {
|
|
|
7648
8831
|
colors
|
|
7649
8832
|
}
|
|
7650
8833
|
) }) }),
|
|
7651
|
-
/* @__PURE__ */
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
checked: showIntegrations,
|
|
7680
|
-
onChange: (event) => updateFilters({
|
|
7681
|
-
showIntegrations: event.currentTarget.checked
|
|
7682
|
-
}),
|
|
7683
|
-
size: "sm"
|
|
7684
|
-
}
|
|
7685
|
-
),
|
|
7686
|
-
resourceFacets.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
7687
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", mb: 8, children: "Resource Facet" }),
|
|
7688
|
-
/* @__PURE__ */ jsx(Stack, { gap: 2, children: resourceFacets.map((facet) => {
|
|
7689
|
-
const filterState = domainFilters[facet.id] || "neutral";
|
|
7690
|
-
const StateIcon = FILTER_STATE_ICONS2[filterState];
|
|
7691
|
-
return /* @__PURE__ */ jsx(
|
|
7692
|
-
UnstyledButton,
|
|
7693
|
-
{
|
|
7694
|
-
title: FILTER_STATE_LABELS2[filterState],
|
|
7695
|
-
onClick: () => cycleDomainFilter(facet.id),
|
|
7696
|
-
py: 5,
|
|
7697
|
-
px: 6,
|
|
7698
|
-
style: {
|
|
7699
|
-
transition: "background-color var(--duration-fast) var(--easing)",
|
|
7700
|
-
"&:hover": { backgroundColor: "var(--color-surface-hover)" }
|
|
7701
|
-
},
|
|
7702
|
-
children: /* @__PURE__ */ jsxs(Group, { gap: 10, wrap: "nowrap", children: [
|
|
7703
|
-
/* @__PURE__ */ jsx(
|
|
7704
|
-
StateIcon,
|
|
7705
|
-
{
|
|
7706
|
-
size: 16,
|
|
7707
|
-
style: {
|
|
7708
|
-
color: FILTER_STATE_COLORS2[filterState],
|
|
7709
|
-
flexShrink: 0,
|
|
7710
|
-
transition: "color var(--duration-fast) var(--easing)"
|
|
7711
|
-
}
|
|
7712
|
-
}
|
|
7713
|
-
),
|
|
7714
|
-
/* @__PURE__ */ jsx(
|
|
7715
|
-
Text,
|
|
7716
|
-
{
|
|
7717
|
-
size: "sm",
|
|
7718
|
-
truncate: true,
|
|
7719
|
-
fw: filterState !== "neutral" ? 500 : 400,
|
|
7720
|
-
c: filterState !== "neutral" ? void 0 : "dimmed",
|
|
7721
|
-
children: facet.label
|
|
7722
|
-
}
|
|
7723
|
-
)
|
|
7724
|
-
] })
|
|
7725
|
-
},
|
|
7726
|
-
facet.id
|
|
7727
|
-
);
|
|
7728
|
-
}) })
|
|
7729
|
-
] })
|
|
7730
|
-
] }),
|
|
7731
|
-
selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7732
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
7733
|
-
/* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
|
|
7734
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
|
|
7735
|
-
selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
|
|
7736
|
-
(isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
|
|
7737
|
-
Button,
|
|
7738
|
-
{
|
|
7739
|
-
component: "a",
|
|
7740
|
-
href: getNavigationUrl() || "#",
|
|
7741
|
-
target: "_blank",
|
|
7742
|
-
rel: "noopener noreferrer",
|
|
7743
|
-
variant: "light",
|
|
7744
|
-
size: "xs",
|
|
7745
|
-
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
|
|
7746
|
-
mt: 4,
|
|
7747
|
-
children: [
|
|
7748
|
-
"Go to",
|
|
7749
|
-
" ",
|
|
7750
|
-
selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
|
|
7751
|
-
]
|
|
7752
|
-
}
|
|
7753
|
-
),
|
|
7754
|
-
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
7755
|
-
] })
|
|
7756
|
-
] }),
|
|
7757
|
-
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: [
|
|
7758
|
-
EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
|
|
7759
|
-
ExecutionStatusSection,
|
|
7760
|
-
{
|
|
7761
|
-
executions: executionsData.executions,
|
|
7762
|
-
status: section.status,
|
|
7763
|
-
title: section.title,
|
|
7764
|
-
badgeColor: section.badgeColor,
|
|
7765
|
-
resourceUrl
|
|
7766
|
-
},
|
|
7767
|
-
section.status
|
|
7768
|
-
)),
|
|
7769
|
-
totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
7770
|
-
Pagination,
|
|
7771
|
-
{
|
|
7772
|
-
size: "sm",
|
|
7773
|
-
total: totalExecutionPages(executionsData.totalExecutions),
|
|
7774
|
-
value: executionPage,
|
|
7775
|
-
onChange: setExecutionPage,
|
|
7776
|
-
boundaries: 1
|
|
7777
|
-
}
|
|
7778
|
-
) })
|
|
7779
|
-
] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
|
|
7780
|
-
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: [
|
|
7781
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
7782
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
|
|
7783
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
|
|
7784
|
-
] }),
|
|
7785
|
-
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
7786
|
-
Card,
|
|
8834
|
+
/* @__PURE__ */ jsx(Box, { p: "sm", children: /* @__PURE__ */ jsx(
|
|
8835
|
+
FilterPanel,
|
|
8836
|
+
{
|
|
8837
|
+
filters,
|
|
8838
|
+
onChangeFilters: updateFilters,
|
|
8839
|
+
resetValue: toolbarResetValue,
|
|
8840
|
+
disabled: !baseGraph,
|
|
8841
|
+
commandViewData: cleanData,
|
|
8842
|
+
lens: "command-view",
|
|
8843
|
+
resourcesHidden,
|
|
8844
|
+
diagnosticsHidden,
|
|
8845
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
8846
|
+
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
8847
|
+
onRevealResources: revealAllResources,
|
|
8848
|
+
onResetFilters: handleResetFilters,
|
|
8849
|
+
visibilityCounts: visibilityProjection,
|
|
8850
|
+
graph: visibleGraph,
|
|
8851
|
+
baseGraph,
|
|
8852
|
+
layout: "stack"
|
|
8853
|
+
}
|
|
8854
|
+
) }),
|
|
8855
|
+
selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8856
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
8857
|
+
/* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
|
|
8858
|
+
/* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
|
|
8859
|
+
selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
|
|
8860
|
+
(isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
|
|
8861
|
+
Button,
|
|
7787
8862
|
{
|
|
7788
|
-
padding: "xs",
|
|
7789
|
-
withBorder: true,
|
|
7790
8863
|
component: "a",
|
|
7791
|
-
href:
|
|
8864
|
+
href: getNavigationUrl() || "#",
|
|
7792
8865
|
target: "_blank",
|
|
7793
8866
|
rel: "noopener noreferrer",
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
8867
|
+
variant: "light",
|
|
8868
|
+
size: "xs",
|
|
8869
|
+
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
|
|
8870
|
+
mt: 4,
|
|
7797
8871
|
children: [
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
] }),
|
|
7802
|
-
task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
|
|
8872
|
+
"Go to",
|
|
8873
|
+
" ",
|
|
8874
|
+
selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
|
|
7803
8875
|
]
|
|
7804
|
-
}
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
] })
|
|
7808
|
-
] })
|
|
7809
|
-
|
|
8876
|
+
}
|
|
8877
|
+
),
|
|
8878
|
+
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
8879
|
+
] })
|
|
8880
|
+
] }),
|
|
8881
|
+
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: [
|
|
8882
|
+
EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
|
|
8883
|
+
ExecutionStatusSection,
|
|
8884
|
+
{
|
|
8885
|
+
executions: executionsData.executions,
|
|
8886
|
+
status: section.status,
|
|
8887
|
+
title: section.title,
|
|
8888
|
+
badgeColor: section.badgeColor,
|
|
8889
|
+
resourceUrl
|
|
8890
|
+
},
|
|
8891
|
+
section.status
|
|
8892
|
+
)),
|
|
8893
|
+
totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
8894
|
+
Pagination,
|
|
8895
|
+
{
|
|
8896
|
+
size: "sm",
|
|
8897
|
+
total: totalExecutionPages(executionsData.totalExecutions),
|
|
8898
|
+
value: executionPage,
|
|
8899
|
+
onChange: setExecutionPage,
|
|
8900
|
+
boundaries: 1
|
|
8901
|
+
}
|
|
8902
|
+
) })
|
|
8903
|
+
] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
|
|
8904
|
+
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: [
|
|
8905
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
8906
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
|
|
8907
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
|
|
8908
|
+
] }),
|
|
8909
|
+
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
8910
|
+
Card,
|
|
8911
|
+
{
|
|
8912
|
+
padding: "xs",
|
|
8913
|
+
withBorder: true,
|
|
8914
|
+
component: "a",
|
|
8915
|
+
href: `/operations/command-queue?task=${task.id}`,
|
|
8916
|
+
target: "_blank",
|
|
8917
|
+
rel: "noopener noreferrer",
|
|
8918
|
+
style: HOVER_CARD_STYLE,
|
|
8919
|
+
onMouseEnter: handleHoverEnter,
|
|
8920
|
+
onMouseLeave: handleHoverLeave,
|
|
8921
|
+
children: [
|
|
8922
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: task.description ? 4 : 0, children: [
|
|
8923
|
+
/* @__PURE__ */ jsx(Badge, { size: "xs", color: "orange", variant: "light", children: "pending" }),
|
|
8924
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(task.createdAt) })
|
|
8925
|
+
] }),
|
|
8926
|
+
task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
|
|
8927
|
+
]
|
|
8928
|
+
},
|
|
8929
|
+
task.id
|
|
8930
|
+
)) })
|
|
8931
|
+
] }) : checkpointTasksData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending tasks" }) : null })
|
|
8932
|
+
] })
|
|
7810
8933
|
}
|
|
7811
8934
|
);
|
|
7812
8935
|
}
|
|
@@ -9116,15 +10239,15 @@ var OperationsSidebar = () => {
|
|
|
9116
10239
|
function CommandQueueShell({ children }) {
|
|
9117
10240
|
return /* @__PURE__ */ jsx(SubshellContentContainer, { children });
|
|
9118
10241
|
}
|
|
10242
|
+
var commandViewSidebarWidth = 320;
|
|
10243
|
+
var defaultOperationsSidebarWidth = 250;
|
|
9119
10244
|
var operationsManifest = {
|
|
9120
10245
|
key: "operations",
|
|
9121
10246
|
featureId: "operations",
|
|
9122
|
-
capabilityIds: ["operations.
|
|
10247
|
+
capabilityIds: ["operations.command-view"],
|
|
9123
10248
|
icon: IconCode,
|
|
9124
10249
|
sidebar: OperationsSidebar,
|
|
9125
|
-
|
|
9126
|
-
featureId: "operations.graph"
|
|
9127
|
-
}
|
|
10250
|
+
sidebarWidth: ({ currentPath }) => currentPath.startsWith("/operations/command-view") ? commandViewSidebarWidth : defaultOperationsSidebarWidth
|
|
9128
10251
|
};
|
|
9129
10252
|
|
|
9130
10253
|
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 };
|