@elevasis/ui 2.25.6 → 2.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.js +2 -2
- package/dist/app/index.css +15 -5
- package/dist/app/index.d.ts +61 -14
- package/dist/app/index.js +6 -6
- package/dist/charts/index.js +6 -5
- package/dist/chunk-3MEXPLWT.js +265 -0
- package/dist/{chunk-BDKM56TP.js → chunk-4KTLOK7K.js} +1 -1
- package/dist/{chunk-KMAXFJPH.js → chunk-CW3UNAF2.js} +5 -409
- package/dist/{chunk-HKBEURCV.js → chunk-G26INIF3.js} +1 -1
- package/dist/{chunk-7F3IQMLI.js → chunk-G66QFZXD.js} +11 -214
- package/dist/{chunk-QIW6OCEI.js → chunk-HLFFKKT3.js} +27 -373
- package/dist/chunk-JDNEWB5F.js +10 -0
- package/dist/{chunk-L7D6KNHV.js → chunk-JKBGDFX2.js} +890 -749
- package/dist/{chunk-YRKQNPK2.js → chunk-JPGX3533.js} +4 -3
- package/dist/chunk-KEFWANZY.js +155 -0
- package/dist/chunk-LH4GPYDX.js +448 -0
- package/dist/{chunk-JXSBOG2R.js → chunk-LWKZ3BCC.js} +5 -4
- package/dist/chunk-MYEOTM7D.js +92 -0
- package/dist/chunk-OGXKOMUT.js +412 -0
- package/dist/chunk-OHXU5WWK.js +3731 -0
- package/dist/chunk-ONFKASZI.js +2004 -0
- package/dist/{chunk-U36X6NZM.js → chunk-RIFTUOPE.js} +2 -14
- package/dist/{chunk-T6INEVX6.js → chunk-SGS4CQ2B.js} +1 -1
- package/dist/{chunk-C7IBFI5B.js → chunk-UPMX5GJI.js} +5 -5
- package/dist/{chunk-ARJPZ66V.js → chunk-UY5I2KOZ.js} +208 -3124
- package/dist/chunk-W2ZTLH7Y.js +662 -0
- package/dist/{chunk-KNISO652.js → chunk-WUVR4QY6.js} +9 -9
- package/dist/{chunk-Q5BEODAT.js → chunk-X2SUMO3P.js} +2 -1
- package/dist/{chunk-SNHGSCKH.js → chunk-XBMCDGHA.js} +1 -1
- package/dist/{chunk-N55DVMAG.js → chunk-XQQEKWTL.js} +2 -6
- package/dist/{chunk-SBQ4MYQV.js → chunk-XZSEPJZQ.js} +5 -6
- package/dist/{chunk-CPAJXBTL.js → chunk-YHBPR67D.js} +490 -676
- package/dist/{chunk-QARSVM7Q.js → chunk-YO2YORW4.js} +4 -4
- package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
- package/dist/components/index.css +15 -5
- package/dist/components/index.d.ts +202 -383
- package/dist/components/index.js +43 -429
- package/dist/components/navigation/index.css +25 -15
- package/dist/execution/index.d.ts +0 -73
- package/dist/features/auth/index.css +25 -15
- package/dist/features/crm/index.css +25 -15
- package/dist/features/crm/index.d.ts +49 -49
- package/dist/features/crm/index.js +14 -15
- package/dist/features/dashboard/index.css +25 -15
- package/dist/features/dashboard/index.js +18 -16
- package/dist/features/delivery/index.css +15 -5
- package/dist/features/delivery/index.js +14 -15
- package/dist/features/knowledge/index.css +611 -0
- package/dist/features/knowledge/index.js +375 -72
- package/dist/features/lead-gen/index.css +25 -15
- package/dist/features/lead-gen/index.d.ts +60 -21
- package/dist/features/lead-gen/index.js +16 -16
- package/dist/features/monitoring/index.css +15 -5
- package/dist/features/monitoring/index.js +17 -17
- package/dist/features/monitoring/requests/index.css +25 -15
- package/dist/features/monitoring/requests/index.js +13 -14
- package/dist/features/operations/index.css +25 -15
- package/dist/features/operations/index.d.ts +16 -98
- package/dist/features/operations/index.js +26 -22
- package/dist/features/settings/index.css +25 -15
- package/dist/features/settings/index.d.ts +1 -0
- package/dist/features/settings/index.js +15 -16
- package/dist/hooks/delivery/index.css +25 -15
- package/dist/hooks/delivery/index.js +2 -2
- package/dist/hooks/index.css +15 -5
- package/dist/hooks/index.d.ts +172 -380
- package/dist/hooks/index.js +13 -14
- package/dist/hooks/published.css +15 -5
- package/dist/hooks/published.d.ts +172 -380
- package/dist/hooks/published.js +13 -14
- package/dist/index.css +15 -5
- package/dist/index.d.ts +988 -403
- package/dist/index.js +15 -15
- package/dist/initialization/index.d.ts +1 -0
- package/dist/knowledge/index.d.ts +981 -41
- package/dist/knowledge/index.js +5449 -294
- package/dist/layout/index.d.ts +2 -0
- package/dist/layout/index.js +3 -2
- package/dist/organization/index.css +25 -15
- package/dist/organization/index.d.ts +1 -0
- package/dist/provider/index.css +25 -15
- package/dist/provider/index.d.ts +818 -26
- package/dist/provider/index.js +11 -11
- package/dist/provider/published.css +25 -15
- package/dist/provider/published.d.ts +817 -25
- package/dist/provider/published.js +8 -9
- package/dist/test-utils/index.js +2 -2
- package/dist/test-utils/setup.js +1 -1
- package/dist/theme/index.js +3 -2
- package/dist/theme/presets/index.d.ts +97 -0
- package/dist/theme/presets/index.js +3 -0
- package/dist/types/index.d.ts +71 -126
- package/dist/utils/index.js +1 -1
- package/dist/vite/index.d.ts +7 -0
- package/dist/vite/index.js +10 -0
- package/dist/vite-plugin-knowledge/index.d.ts +1 -33
- package/dist/vite-plugin-knowledge/index.js +1 -66
- package/package.json +16 -3
- package/src/knowledge/README.md +8 -8
- package/src/theme/presets/README.md +19 -0
- package/dist/chunk-5RLYII6P.js +0 -314
- package/dist/chunk-6U7AIIHF.js +0 -880
- package/dist/chunk-HAEJ4M54.js +0 -94
- package/dist/chunk-LPM7O6XM.js +0 -293
- /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
|
@@ -1,32 +1,35 @@
|
|
|
1
|
-
import { SubshellSidebarLoader, SubshellLoader } from './chunk-N55DVMAG.js';
|
|
2
1
|
import { ChatHeader, ChatSidebar } from './chunk-ROSMICXG.js';
|
|
3
|
-
import { buildOrganizationGraph } from './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { getOrganizationGraphLensConfig, useOrganizationGraphFilters, createOrganizationGraphFilters, buildOrganizationGraph, filterOrganizationGraph, getCommandViewVisibilityProjection, resolveOrganizationGraphPathTrace, getCommandViewOperationalOverview, getCommandViewSelectionOperationalSummary, buildCommandViewDrillDownSections, expandAroundGraph, getConnectedHiddenResourceIds, FilterPanel, OrganizationGraphDetailPanel, ExpandAroundPanel, CommandViewSidebarContent, getOrganizationGraphTraceNodeOptions, formatOrganizationGraphTraceNodeOptionLabel } from './chunk-OHXU5WWK.js';
|
|
3
|
+
import { SubshellLoader } from './chunk-JDNEWB5F.js';
|
|
4
|
+
import { resolveSemanticIconComponent } from './chunk-KEFWANZY.js';
|
|
5
|
+
import { SubshellSidebarLoader } from './chunk-XQQEKWTL.js';
|
|
6
|
+
import { BaseNode, useGraphTheme, BaseEdge, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-G66QFZXD.js';
|
|
7
|
+
import { FormFieldRenderer } from './chunk-3MEXPLWT.js';
|
|
8
|
+
import { ResourceHealthPanel } from './chunk-YO2YORW4.js';
|
|
9
|
+
import { useCyberColors, CyberDonut } from './chunk-CW3UNAF2.js';
|
|
7
10
|
import { AppShellLoader } from './chunk-RYTEQBAO.js';
|
|
8
11
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
9
12
|
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
10
13
|
import { CustomModal, ConfirmationModal } from './chunk-KVJ3LFH2.js';
|
|
11
|
-
import { getResourceStatusColor, useTimelineData, useAgentIterationData, getStatusIcon } from './chunk-E4WQGJNS.js';
|
|
12
|
-
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-CPAJXBTL.js';
|
|
13
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-HKBEURCV.js';
|
|
14
14
|
import { useGraphHighlighting, calculateGraphHeight, Graph_module_css_default, GRAPH_CONSTANTS } from './chunk-22UVE3RA.js';
|
|
15
|
+
import { getResourceStatusColor, useTimelineData, useAgentIterationData, getStatusIcon } from './chunk-E4WQGJNS.js';
|
|
16
|
+
import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, collectResourceFilterFacets, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, COMMAND_VIEW_VISUALIZATION_MODES, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions, getCommandViewGraphPositions } from './chunk-YHBPR67D.js';
|
|
17
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-G26INIF3.js';
|
|
15
18
|
import { useMergedExecution } from './chunk-3ZMAGTWF.js';
|
|
19
|
+
import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-RIFTUOPE.js';
|
|
20
|
+
import { StyledMarkdown } from './chunk-3KMDHCAR.js';
|
|
21
|
+
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-V3HUIZJX.js';
|
|
16
22
|
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
17
|
-
import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-U36X6NZM.js';
|
|
18
23
|
import { NavigationButton } from './chunk-NYBEU5TE.js';
|
|
19
|
-
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-V3HUIZJX.js';
|
|
20
|
-
import { StyledMarkdown } from './chunk-3KMDHCAR.js';
|
|
21
24
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
22
25
|
import { useAppearance } from './chunk-E565XMTQ.js';
|
|
23
26
|
import { topbarHeight } from './chunk-DT3QYZVU.js';
|
|
24
|
-
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime,
|
|
27
|
+
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, debounce } from './chunk-QD4X4H5A.js';
|
|
25
28
|
import { ResourceStatusColors, toWorkflowLogMessages } from './chunk-KRWALB24.js';
|
|
26
29
|
import { useInitialization } from './chunk-WKJ47GIW.js';
|
|
27
30
|
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
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,
|
|
29
|
-
import { IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconCode, IconAlertCircle, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions,
|
|
31
|
+
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, Loader, SegmentedControl, Modal, LoadingOverlay, ScrollArea } from '@mantine/core';
|
|
32
|
+
import { IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconCode, IconAlertCircle, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconNetwork, IconSitemap, IconCopy, IconPlayerStop, IconReload, IconTrash, IconTerminal2, IconBug, IconChevronDown, IconPlayerPlay, 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, IconHistory } from '@tabler/icons-react';
|
|
30
33
|
import { useForm } from '@mantine/form';
|
|
31
34
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
32
35
|
import { memo, useState, useMemo, useRef, useCallback, useEffect, useDeferredValue, useEffectEvent } from 'react';
|
|
@@ -37,8 +40,6 @@ import { useClipboard } from '@mantine/hooks';
|
|
|
37
40
|
import { notifications } from '@mantine/notifications';
|
|
38
41
|
import { useNavigate } from '@tanstack/react-router';
|
|
39
42
|
import cytoscape from 'cytoscape';
|
|
40
|
-
import { create } from 'zustand';
|
|
41
|
-
import { formatDistanceToNow } from 'date-fns';
|
|
42
43
|
|
|
43
44
|
var iconMap = {
|
|
44
45
|
IconCheck,
|
|
@@ -55,13 +56,35 @@ var iconMap = {
|
|
|
55
56
|
IconSend,
|
|
56
57
|
IconMail
|
|
57
58
|
};
|
|
59
|
+
var semanticActionIconMap = {
|
|
60
|
+
"action.approve": IconCheck,
|
|
61
|
+
"action.reject": IconX,
|
|
62
|
+
"action.retry": IconRefresh,
|
|
63
|
+
"action.escalate": IconAlertTriangle,
|
|
64
|
+
"action.edit": IconEdit,
|
|
65
|
+
"action.view": IconEye,
|
|
66
|
+
"action.launch": IconRocket,
|
|
67
|
+
"action.message": IconMessageCircle,
|
|
68
|
+
"action.promote": IconArrowUp,
|
|
69
|
+
"action.submit": IconSend,
|
|
70
|
+
"action.email": IconMail,
|
|
71
|
+
"status.pending": IconClock,
|
|
72
|
+
"status.success": IconCheck,
|
|
73
|
+
"status.error": IconX,
|
|
74
|
+
"status.warning": IconAlertTriangle
|
|
75
|
+
};
|
|
58
76
|
function getIcon(iconName) {
|
|
59
77
|
if (!iconName) return null;
|
|
60
|
-
const icon = iconMap[iconName];
|
|
61
|
-
if (
|
|
62
|
-
|
|
78
|
+
const icon = iconMap[iconName] ?? semanticActionIconMap[iconName];
|
|
79
|
+
if (icon) return icon;
|
|
80
|
+
const semanticIcon = resolveSemanticIconComponent(iconName);
|
|
81
|
+
if (semanticIcon) return semanticIcon;
|
|
82
|
+
if (process.env.NODE_ENV !== "production") {
|
|
83
|
+
console.warn(
|
|
84
|
+
`[iconMap] Unknown icon "${iconName}". Allowed legacy names: ${Object.keys(iconMap).join(", ")}. Semantic action/status tokens are also supported.`
|
|
85
|
+
);
|
|
63
86
|
}
|
|
64
|
-
return
|
|
87
|
+
return null;
|
|
65
88
|
}
|
|
66
89
|
function resolveDefaultValue(context, path) {
|
|
67
90
|
if (!context || typeof context !== "object") return void 0;
|
|
@@ -587,20 +610,6 @@ function AgentDefinitionDisplay({ agent, defaultExpanded = false }) {
|
|
|
587
610
|
}
|
|
588
611
|
]
|
|
589
612
|
}
|
|
590
|
-
),
|
|
591
|
-
/* @__PURE__ */ jsx(
|
|
592
|
-
ConfigCard,
|
|
593
|
-
{
|
|
594
|
-
icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
|
|
595
|
-
title: "Execution Interface",
|
|
596
|
-
color: "teal",
|
|
597
|
-
items: [
|
|
598
|
-
{
|
|
599
|
-
label: "Has Interface",
|
|
600
|
-
value: agent.interface ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "green", children: "Yes" }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: "No" })
|
|
601
|
-
}
|
|
602
|
-
]
|
|
603
|
-
}
|
|
604
613
|
)
|
|
605
614
|
] }),
|
|
606
615
|
/* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)", marginTop: "var(--mantine-spacing-sm)" }, children: /* @__PURE__ */ jsx(ContractDisplay, { contract: agent.contract, defaultExpanded }) })
|
|
@@ -719,36 +728,20 @@ function WorkflowDefinitionDisplay({ workflow, defaultExpanded = false }) {
|
|
|
719
728
|
}
|
|
720
729
|
),
|
|
721
730
|
/* @__PURE__ */ jsxs(Collapse, { in: configExpanded, children: [
|
|
722
|
-
/* @__PURE__ */
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
{
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
),
|
|
737
|
-
/* @__PURE__ */ jsx(
|
|
738
|
-
ConfigCard,
|
|
739
|
-
{
|
|
740
|
-
icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
|
|
741
|
-
title: "Execution Interface",
|
|
742
|
-
color: "teal",
|
|
743
|
-
items: [
|
|
744
|
-
{
|
|
745
|
-
label: "Has Interface",
|
|
746
|
-
value: workflow.interface ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "green", children: "Yes" }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: "No" })
|
|
747
|
-
}
|
|
748
|
-
]
|
|
749
|
-
}
|
|
750
|
-
)
|
|
751
|
-
] }),
|
|
731
|
+
/* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)" }, children: /* @__PURE__ */ jsx(
|
|
732
|
+
ConfigCard,
|
|
733
|
+
{
|
|
734
|
+
icon: /* @__PURE__ */ jsx(IconVersions, { size: 14 }),
|
|
735
|
+
title: "Version",
|
|
736
|
+
color: "grape",
|
|
737
|
+
items: [
|
|
738
|
+
{
|
|
739
|
+
label: "Version",
|
|
740
|
+
value: /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: workflow.config.version })
|
|
741
|
+
}
|
|
742
|
+
]
|
|
743
|
+
}
|
|
744
|
+
) }),
|
|
752
745
|
/* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)", marginTop: "var(--mantine-spacing-sm)" }, children: /* @__PURE__ */ jsx(ContractDisplay, { contract: workflow.contract, defaultExpanded }) })
|
|
753
746
|
] })
|
|
754
747
|
] }) });
|
|
@@ -2723,174 +2716,12 @@ function ResourceNotFoundState2({ type, resourceId, onNavigateBack }) {
|
|
|
2723
2716
|
/* @__PURE__ */ jsx(Button, { variant: "light", leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }), onClick: handleBack, children: "Back to Operations" })
|
|
2724
2717
|
] }) }) });
|
|
2725
2718
|
}
|
|
2726
|
-
function ExecuteWorkflowModal({
|
|
2727
|
-
opened,
|
|
2728
|
-
onClose,
|
|
2729
|
-
resource,
|
|
2730
|
-
isPending = false,
|
|
2731
|
-
error,
|
|
2732
|
-
result,
|
|
2733
|
-
onViewExecution,
|
|
2734
|
-
onReset,
|
|
2735
|
-
children
|
|
2736
|
-
}) {
|
|
2737
|
-
const canClose = !isPending;
|
|
2738
|
-
const title = resource.name ?? resource.resourceId;
|
|
2739
|
-
return /* @__PURE__ */ jsx(
|
|
2740
|
-
Modal,
|
|
2741
|
-
{
|
|
2742
|
-
opened,
|
|
2743
|
-
onClose: canClose ? onClose : () => void 0,
|
|
2744
|
-
centered: true,
|
|
2745
|
-
size: "lg",
|
|
2746
|
-
closeOnClickOutside: canClose,
|
|
2747
|
-
closeOnEscape: canClose,
|
|
2748
|
-
withCloseButton: canClose,
|
|
2749
|
-
title: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
2750
|
-
/* @__PURE__ */ jsxs(Text, { fw: 600, children: [
|
|
2751
|
-
"Run ",
|
|
2752
|
-
resource.resourceType
|
|
2753
|
-
] }),
|
|
2754
|
-
/* @__PURE__ */ jsx(Badge, { color: "blue", variant: "light", size: "sm", children: resource.resourceType })
|
|
2755
|
-
] }),
|
|
2756
|
-
children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
2757
|
-
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
2758
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Target:" }),
|
|
2759
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: title }),
|
|
2760
|
-
/* @__PURE__ */ jsx(Code, { children: resource.resourceId })
|
|
2761
|
-
] }),
|
|
2762
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
2763
|
-
result ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
2764
|
-
/* @__PURE__ */ jsx(Alert, { variant: "light", color: "teal", title: "Execution started", icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }), children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
2765
|
-
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
2766
|
-
"The ",
|
|
2767
|
-
resource.resourceType,
|
|
2768
|
-
" is now running."
|
|
2769
|
-
] }),
|
|
2770
|
-
/* @__PURE__ */ jsxs(Group, { gap: 4, children: [
|
|
2771
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Execution ID:" }),
|
|
2772
|
-
/* @__PURE__ */ jsx(Code, { children: result.executionId })
|
|
2773
|
-
] })
|
|
2774
|
-
] }) }),
|
|
2775
|
-
/* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
|
|
2776
|
-
onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Run again" }),
|
|
2777
|
-
onViewExecution && /* @__PURE__ */ jsx(
|
|
2778
|
-
Button,
|
|
2779
|
-
{
|
|
2780
|
-
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 16 }),
|
|
2781
|
-
onClick: () => onViewExecution(result.executionId),
|
|
2782
|
-
children: "View execution"
|
|
2783
|
-
}
|
|
2784
|
-
),
|
|
2785
|
-
/* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
|
|
2786
|
-
] })
|
|
2787
|
-
] }) : error ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
2788
|
-
/* @__PURE__ */ jsx(Alert, { variant: "light", color: "red", title: "Execution failed to start", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: /* @__PURE__ */ jsx(Text, { size: "sm", children: error.message || "An unknown error occurred." }) }),
|
|
2789
|
-
/* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
|
|
2790
|
-
onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Try again" }),
|
|
2791
|
-
/* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
|
|
2792
|
-
] })
|
|
2793
|
-
] }) : /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
2794
|
-
/* @__PURE__ */ jsx(LoadingOverlay, { visible: isPending, zIndex: 1e3, overlayProps: { blur: 2 } }),
|
|
2795
|
-
children ?? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No input form provided." })
|
|
2796
|
-
] })
|
|
2797
|
-
] })
|
|
2798
|
-
}
|
|
2799
|
-
);
|
|
2800
|
-
}
|
|
2801
|
-
function getInitialValues(fields) {
|
|
2802
|
-
const values = {};
|
|
2803
|
-
for (const field of fields) {
|
|
2804
|
-
values[field.name] = field.defaultValue ?? (field.type === "checkbox" ? false : "");
|
|
2805
|
-
}
|
|
2806
|
-
return values;
|
|
2807
|
-
}
|
|
2808
|
-
function applyFieldMappings(values, mappings) {
|
|
2809
|
-
if (!mappings) return values;
|
|
2810
|
-
const mapped = {};
|
|
2811
|
-
for (const [key, value] of Object.entries(values)) {
|
|
2812
|
-
const targetKey = mappings[key] ?? key;
|
|
2813
|
-
mapped[targetKey] = value;
|
|
2814
|
-
}
|
|
2815
|
-
return mapped;
|
|
2816
|
-
}
|
|
2817
|
-
function ResourceExecuteForm({
|
|
2818
|
-
formSchema,
|
|
2819
|
-
onSubmit,
|
|
2820
|
-
isPending = false,
|
|
2821
|
-
disabled = false,
|
|
2822
|
-
submitLabel = "Run"
|
|
2823
|
-
}) {
|
|
2824
|
-
const hasFields = formSchema?.fields?.length > 0;
|
|
2825
|
-
const form = useForm({
|
|
2826
|
-
initialValues: hasFields ? getInitialValues(formSchema.fields) : {},
|
|
2827
|
-
validate: hasFields ? Object.fromEntries(
|
|
2828
|
-
formSchema.fields.filter((f) => f.required).map((f) => [
|
|
2829
|
-
f.name,
|
|
2830
|
-
(value) => !value && value !== false ? `${f.label} is required` : null
|
|
2831
|
-
])
|
|
2832
|
-
) : {}
|
|
2833
|
-
});
|
|
2834
|
-
const handleSubmit = (values) => {
|
|
2835
|
-
const input = applyFieldMappings(values, formSchema?.fieldMappings);
|
|
2836
|
-
void onSubmit(input);
|
|
2837
|
-
};
|
|
2838
|
-
if (!hasFields) {
|
|
2839
|
-
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
2840
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "This workflow takes no input." }),
|
|
2841
|
-
/* @__PURE__ */ jsx(Button, { onClick: () => void onSubmit({}), loading: isPending, disabled, fullWidth: true, children: isPending ? formSchema?.submitButton?.loadingLabel ?? "Running..." : submitLabel })
|
|
2842
|
-
] });
|
|
2843
|
-
}
|
|
2844
|
-
return /* @__PURE__ */ jsx("form", { onSubmit: form.onSubmit(handleSubmit), children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
2845
|
-
formSchema.fields.map((field) => /* @__PURE__ */ jsx(FormFieldRenderer, { field, form }, field.name)),
|
|
2846
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", loading: isPending, disabled, fullWidth: true, children: isPending ? formSchema.submitButton?.loadingLabel ?? "Running..." : submitLabel })
|
|
2847
|
-
] }) });
|
|
2848
|
-
}
|
|
2849
|
-
function ResourceExecuteDialog({ opened, onClose, resource, onViewExecution }) {
|
|
2850
|
-
const mutation = useExecuteAsync();
|
|
2851
|
-
const handleSubmit = async (input) => {
|
|
2852
|
-
await mutation.mutateAsync({
|
|
2853
|
-
resourceId: resource.resourceId,
|
|
2854
|
-
resourceType: resource.resourceType,
|
|
2855
|
-
input
|
|
2856
|
-
});
|
|
2857
|
-
};
|
|
2858
|
-
const handleReset = () => {
|
|
2859
|
-
mutation.reset();
|
|
2860
|
-
};
|
|
2861
|
-
const modalResource = {
|
|
2862
|
-
resourceId: resource.resourceId,
|
|
2863
|
-
resourceType: resource.resourceType,
|
|
2864
|
-
name: resource.name
|
|
2865
|
-
};
|
|
2866
|
-
return /* @__PURE__ */ jsx(
|
|
2867
|
-
ExecuteWorkflowModal,
|
|
2868
|
-
{
|
|
2869
|
-
opened,
|
|
2870
|
-
onClose,
|
|
2871
|
-
resource: modalResource,
|
|
2872
|
-
isPending: mutation.isPending,
|
|
2873
|
-
error: mutation.error,
|
|
2874
|
-
result: mutation.data ?? null,
|
|
2875
|
-
onViewExecution,
|
|
2876
|
-
onReset: handleReset,
|
|
2877
|
-
children: /* @__PURE__ */ jsx(
|
|
2878
|
-
ResourceExecuteForm,
|
|
2879
|
-
{
|
|
2880
|
-
formSchema: resource.formSchema ?? { fields: [] },
|
|
2881
|
-
onSubmit: handleSubmit,
|
|
2882
|
-
isPending: mutation.isPending,
|
|
2883
|
-
disabled: mutation.isPending
|
|
2884
|
-
}
|
|
2885
|
-
)
|
|
2886
|
-
}
|
|
2887
|
-
);
|
|
2888
|
-
}
|
|
2889
2719
|
function ResourceDetailPage({
|
|
2890
2720
|
type,
|
|
2891
2721
|
resourceId,
|
|
2892
2722
|
timeRange,
|
|
2893
2723
|
renderExecutionPanel,
|
|
2724
|
+
renderExecuteDialog,
|
|
2894
2725
|
onNavigateToResources,
|
|
2895
2726
|
onNavigateToSessions,
|
|
2896
2727
|
onNavigateBack
|
|
@@ -2926,19 +2757,13 @@ function ResourceDetailPage({
|
|
|
2926
2757
|
const validResource = resource;
|
|
2927
2758
|
const sessionCapable = isSessionCapable(type, resourceDefinition);
|
|
2928
2759
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
resourceType: type,
|
|
2937
|
-
name: validResource.name,
|
|
2938
|
-
formSchema: resourceDefinition?.interface?.form
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
),
|
|
2760
|
+
renderExecuteDialog({
|
|
2761
|
+
opened: runOpened,
|
|
2762
|
+
onClose: () => setRunOpened(false),
|
|
2763
|
+
resourceId,
|
|
2764
|
+
resourceType: type,
|
|
2765
|
+
name: validResource.name
|
|
2766
|
+
}),
|
|
2942
2767
|
/* @__PURE__ */ jsxs(Stack, { children: [
|
|
2943
2768
|
/* @__PURE__ */ jsx(
|
|
2944
2769
|
ResourceHeader,
|
|
@@ -3547,2534 +3372,74 @@ function CommandQueueDetailPage({
|
|
|
3547
3372
|
] }) })
|
|
3548
3373
|
] });
|
|
3549
3374
|
}
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
entity: "Entity",
|
|
3557
|
-
capability: "Capability",
|
|
3558
|
-
resource: "Resource",
|
|
3559
|
-
knowledge: "Knowledge"
|
|
3560
|
-
};
|
|
3561
|
-
var NODE_KIND_MEANINGS = {
|
|
3562
|
-
organization: "The root of the shared organization model and the parent for every derived node.",
|
|
3563
|
-
feature: "A feature that enables or disables downstream surfaces and model surfaces.",
|
|
3564
|
-
surface: "A user-facing or operational surface that exposes feature behavior in the model.",
|
|
3565
|
-
entity: "A shared business concept that can be referenced by surfaces, resources, or capabilities.",
|
|
3566
|
-
capability: "A reusable capability that can be attached to a feature or surface.",
|
|
3567
|
-
resource: "A concrete command-view or mapped resource that bridges execution topology into the model.",
|
|
3568
|
-
knowledge: "An operational knowledge node that documents a process, strategy, or runbook in the org model."
|
|
3569
|
-
};
|
|
3570
|
-
var EDGE_KIND_LABELS = {
|
|
3571
|
-
contains: "Containment",
|
|
3572
|
-
references: "Reference",
|
|
3573
|
-
exposes: "Exposure",
|
|
3574
|
-
maps_to: "Mapping",
|
|
3575
|
-
"operates-on": "Operates on",
|
|
3576
|
-
uses: "Uses",
|
|
3577
|
-
governs: "Governs"
|
|
3578
|
-
};
|
|
3579
|
-
var EDGE_KIND_MEANINGS = {
|
|
3580
|
-
contains: "A hierarchy or ownership link inside the shared graph.",
|
|
3581
|
-
references: "A semantic association or dependency between two graph nodes.",
|
|
3582
|
-
exposes: "A feature enables a surface to be visible or reachable.",
|
|
3583
|
-
maps_to: "A concrete resource is aligned to a domain, entity, capability, or surface.",
|
|
3584
|
-
"operates-on": "A concrete resource operates on an Organization Model node.",
|
|
3585
|
-
uses: "A concrete resource depends on another graph node or integration.",
|
|
3586
|
-
governs: "A knowledge node governs or provides authoritative guidance for another node."
|
|
3587
|
-
};
|
|
3588
|
-
var RELATIONSHIP_MEANINGS = {
|
|
3589
|
-
triggers: "Executable handoff: the source resource starts the target resource.",
|
|
3590
|
-
uses: "Operational dependency: the source resource relies on the target integration.",
|
|
3591
|
-
approval: "Human gate: the source resource pauses for approval at the target checkpoint."
|
|
3375
|
+
var cellStyle = {
|
|
3376
|
+
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
3377
|
+
display: "flex",
|
|
3378
|
+
alignItems: "center",
|
|
3379
|
+
gap: "var(--mantine-spacing-sm)",
|
|
3380
|
+
minWidth: 0
|
|
3592
3381
|
};
|
|
3593
|
-
function
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
}
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
}
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
}
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
}
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
}
|
|
3654
|
-
function buildNodeState(graph, node, nodesById) {
|
|
3655
|
-
const incidentEdges = graph.edges.filter((edge) => edge.sourceId === node.id || edge.targetId === node.id);
|
|
3656
|
-
const incomingEdges = incidentEdges.filter((edge) => edge.targetId === node.id);
|
|
3657
|
-
const outgoingEdges = incidentEdges.filter((edge) => edge.sourceId === node.id);
|
|
3658
|
-
const adjacentNodes = uniqueNodesById(
|
|
3659
|
-
incidentEdges.map((edge) => edge.sourceId === node.id ? nodesById.get(edge.targetId) : nodesById.get(edge.sourceId)).filter((value) => Boolean(value))
|
|
3660
|
-
);
|
|
3661
|
-
const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
|
|
3662
|
-
const contexts = incidentEdges.filter(
|
|
3663
|
-
(edge) => edge.sourceId === node.id ? edge.targetId === adjacentNode.id : edge.sourceId === adjacentNode.id
|
|
3664
|
-
).map(
|
|
3665
|
-
(edge) => `${edge.sourceId === node.id ? "outgoing" : "incoming"} via ${edge.label ?? getEdgeKindLabel(edge.kind).toLowerCase()}`
|
|
3666
|
-
);
|
|
3667
|
-
return {
|
|
3668
|
-
id: adjacentNode.id,
|
|
3669
|
-
label: adjacentNode.label,
|
|
3670
|
-
kind: adjacentNode.kind,
|
|
3671
|
-
kindLabel: getNodeKindLabel(adjacentNode.kind),
|
|
3672
|
-
context: contexts.slice(0, 2).join(", ")
|
|
3673
|
-
};
|
|
3674
|
-
});
|
|
3675
|
-
const relatedEdges = incidentEdges.slice().sort((left, right) => left.id.localeCompare(right.id)).map((edge) => {
|
|
3676
|
-
const connectedId = edge.sourceId === node.id ? edge.targetId : edge.sourceId;
|
|
3677
|
-
const connectedNode = nodesById.get(connectedId);
|
|
3678
|
-
return {
|
|
3679
|
-
id: edge.id,
|
|
3680
|
-
label: edge.label ?? edge.relationshipType ?? getEdgeKindLabel(edge.kind),
|
|
3681
|
-
kind: edge.kind,
|
|
3682
|
-
kindLabel: getEdgeKindLabel(edge.kind),
|
|
3683
|
-
context: `${edge.sourceId === node.id ? "outgoing" : "incoming"}${connectedNode ? ` to ${connectedNode.label}` : ""}`
|
|
3684
|
-
};
|
|
3685
|
-
});
|
|
3686
|
-
const metadata = [
|
|
3687
|
-
{ label: "Graph ID", value: node.id },
|
|
3688
|
-
{ label: "Source ID", value: node.sourceId ?? node.id },
|
|
3689
|
-
{ label: "Kind", value: getNodeKindLabel(node.kind) }
|
|
3690
|
-
];
|
|
3691
|
-
if (node.enabled !== void 0) {
|
|
3692
|
-
metadata.push({ label: "Enabled", value: node.enabled ? "Yes" : "No" });
|
|
3693
|
-
}
|
|
3694
|
-
if (node.featureId) {
|
|
3695
|
-
metadata.push({ label: "Feature ID", value: node.featureId });
|
|
3696
|
-
}
|
|
3697
|
-
if (node.resourceType) {
|
|
3698
|
-
metadata.push({ label: "Resource Type", value: titleCase(node.resourceType) });
|
|
3699
|
-
}
|
|
3700
|
-
const meaningfulEdges = incidentEdges.filter((edge) => edge.kind !== "contains" || edge.relationshipType);
|
|
3701
|
-
return {
|
|
3702
|
-
state: "node",
|
|
3703
|
-
title: node.label,
|
|
3704
|
-
semanticCategory: getNodeKindLabel(node.kind),
|
|
3705
|
-
operationalMeaning: getNodeMeaning(node),
|
|
3706
|
-
description: node.description,
|
|
3707
|
-
metrics: [
|
|
3708
|
-
{
|
|
3709
|
-
label: "Connected edges",
|
|
3710
|
-
value: String(incidentEdges.length),
|
|
3711
|
-
hint: "All direct relationships attached to this node"
|
|
3712
|
-
},
|
|
3713
|
-
{ label: "Incoming", value: String(incomingEdges.length), hint: "Edges that point into this node" },
|
|
3714
|
-
{ label: "Outgoing", value: String(outgoingEdges.length), hint: "Edges that start at this node" },
|
|
3715
|
-
{
|
|
3716
|
-
label: "Meaningful links",
|
|
3717
|
-
value: String(meaningfulEdges.length),
|
|
3718
|
-
hint: "Edges with semantic or operational meaning"
|
|
3719
|
-
}
|
|
3720
|
-
],
|
|
3721
|
-
metadata,
|
|
3722
|
-
adjacentKindCounts: countByKind(adjacentNodes),
|
|
3723
|
-
node,
|
|
3724
|
-
relatedNodes,
|
|
3725
|
-
relatedEdges
|
|
3726
|
-
};
|
|
3727
|
-
}
|
|
3728
|
-
function buildEdgeState(graph, edge, nodesById) {
|
|
3729
|
-
const sourceNode = nodesById.get(edge.sourceId);
|
|
3730
|
-
const targetNode = nodesById.get(edge.targetId);
|
|
3731
|
-
const sourceIncidentEdges = graph.edges.filter(
|
|
3732
|
-
(candidate) => candidate.sourceId === edge.sourceId || candidate.targetId === edge.sourceId
|
|
3733
|
-
);
|
|
3734
|
-
const targetIncidentEdges = graph.edges.filter(
|
|
3735
|
-
(candidate) => candidate.sourceId === edge.targetId || candidate.targetId === edge.targetId
|
|
3736
|
-
);
|
|
3737
|
-
const adjacentNodes = uniqueNodesById(
|
|
3738
|
-
[...sourceIncidentEdges, ...targetIncidentEdges].map((candidate) => {
|
|
3739
|
-
if (candidate.sourceId === edge.sourceId) return nodesById.get(candidate.targetId);
|
|
3740
|
-
if (candidate.targetId === edge.sourceId) return nodesById.get(candidate.sourceId);
|
|
3741
|
-
if (candidate.sourceId === edge.targetId) return nodesById.get(candidate.targetId);
|
|
3742
|
-
if (candidate.targetId === edge.targetId) return nodesById.get(candidate.sourceId);
|
|
3743
|
-
return null;
|
|
3744
|
-
}).filter((value) => Boolean(value)).filter((candidate) => candidate.id !== edge.sourceId && candidate.id !== edge.targetId)
|
|
3745
|
-
);
|
|
3746
|
-
const sourceNeighborIds = new Set(
|
|
3747
|
-
sourceIncidentEdges.map((candidate) => {
|
|
3748
|
-
if (candidate.sourceId === edge.sourceId) return candidate.targetId;
|
|
3749
|
-
if (candidate.targetId === edge.sourceId) return candidate.sourceId;
|
|
3750
|
-
return null;
|
|
3751
|
-
}).filter((value) => Boolean(value))
|
|
3752
|
-
);
|
|
3753
|
-
const targetNeighborIds = new Set(
|
|
3754
|
-
targetIncidentEdges.map((candidate) => {
|
|
3755
|
-
if (candidate.sourceId === edge.targetId) return candidate.targetId;
|
|
3756
|
-
if (candidate.targetId === edge.targetId) return candidate.sourceId;
|
|
3757
|
-
return null;
|
|
3758
|
-
}).filter((value) => Boolean(value))
|
|
3759
|
-
);
|
|
3760
|
-
const sharedNeighborCount = [...sourceNeighborIds].filter((neighborId) => targetNeighborIds.has(neighborId)).length;
|
|
3761
|
-
const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
|
|
3762
|
-
const sourceContext = sourceIncidentEdges.some(
|
|
3763
|
-
(candidate) => candidate.sourceId === edge.sourceId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.sourceId && candidate.sourceId === adjacentNode.id
|
|
3764
|
-
);
|
|
3765
|
-
const targetContext = targetIncidentEdges.some(
|
|
3766
|
-
(candidate) => candidate.sourceId === edge.targetId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.targetId && candidate.sourceId === adjacentNode.id
|
|
3767
|
-
);
|
|
3768
|
-
const contextParts = [];
|
|
3769
|
-
if (sourceContext) contextParts.push("source neighborhood");
|
|
3770
|
-
if (targetContext) contextParts.push("target neighborhood");
|
|
3771
|
-
return {
|
|
3772
|
-
id: adjacentNode.id,
|
|
3773
|
-
label: adjacentNode.label,
|
|
3774
|
-
kind: adjacentNode.kind,
|
|
3775
|
-
kindLabel: getNodeKindLabel(adjacentNode.kind),
|
|
3776
|
-
context: contextParts.join(" + ")
|
|
3777
|
-
};
|
|
3778
|
-
});
|
|
3779
|
-
const surroundingEdges = uniqueEdgesById([...sourceIncidentEdges, ...targetIncidentEdges]).filter((candidate) => candidate.id !== edge.id).sort((left, right) => left.id.localeCompare(right.id)).map((candidate) => {
|
|
3780
|
-
const leftNode = nodesById.get(candidate.sourceId);
|
|
3781
|
-
const rightNode = nodesById.get(candidate.targetId);
|
|
3782
|
-
return {
|
|
3783
|
-
id: candidate.id,
|
|
3784
|
-
label: candidate.label ?? candidate.relationshipType ?? getEdgeKindLabel(candidate.kind),
|
|
3785
|
-
kind: candidate.kind,
|
|
3786
|
-
kindLabel: getEdgeKindLabel(candidate.kind),
|
|
3787
|
-
context: `${leftNode?.label ?? candidate.sourceId} -> ${rightNode?.label ?? candidate.targetId}`
|
|
3788
|
-
};
|
|
3789
|
-
});
|
|
3790
|
-
const metadata = [
|
|
3791
|
-
{ label: "Graph ID", value: edge.id },
|
|
3792
|
-
{ label: "Source ID", value: edge.sourceId },
|
|
3793
|
-
{ label: "Target ID", value: edge.targetId },
|
|
3794
|
-
{ label: "Edge kind", value: getEdgeKindLabel(edge.kind) }
|
|
3795
|
-
];
|
|
3796
|
-
if (edge.label) {
|
|
3797
|
-
metadata.push({ label: "Label", value: edge.label });
|
|
3798
|
-
}
|
|
3799
|
-
if (edge.relationshipType) {
|
|
3800
|
-
metadata.push({ label: "Relationship", value: titleCase(edge.relationshipType) });
|
|
3801
|
-
}
|
|
3802
|
-
return {
|
|
3803
|
-
state: "edge",
|
|
3804
|
-
title: edge.label ?? `${sourceNode?.label ?? edge.sourceId} \u2192 ${targetNode?.label ?? edge.targetId}`,
|
|
3805
|
-
semanticCategory: edge.relationshipType ? titleCase(edge.relationshipType) : getEdgeKindLabel(edge.kind),
|
|
3806
|
-
operationalMeaning: getEdgeMeaning(edge, sourceNode, targetNode),
|
|
3807
|
-
description: edge.label,
|
|
3808
|
-
metrics: [
|
|
3809
|
-
{
|
|
3810
|
-
label: "Source degree",
|
|
3811
|
-
value: String(sourceIncidentEdges.length),
|
|
3812
|
-
hint: "Relationships attached to the source node"
|
|
3813
|
-
},
|
|
3814
|
-
{
|
|
3815
|
-
label: "Target degree",
|
|
3816
|
-
value: String(targetIncidentEdges.length),
|
|
3817
|
-
hint: "Relationships attached to the target node"
|
|
3818
|
-
},
|
|
3819
|
-
{
|
|
3820
|
-
label: "Nearby nodes",
|
|
3821
|
-
value: String(adjacentNodes.length),
|
|
3822
|
-
hint: "Unique nodes in the source and target neighborhoods"
|
|
3823
|
-
},
|
|
3824
|
-
{
|
|
3825
|
-
label: "Shared peers",
|
|
3826
|
-
value: String(sharedNeighborCount),
|
|
3827
|
-
hint: "Neighbors that appear in both node neighborhoods"
|
|
3828
|
-
}
|
|
3829
|
-
],
|
|
3830
|
-
metadata,
|
|
3831
|
-
adjacentKindCounts: countByKind(adjacentNodes),
|
|
3832
|
-
edge,
|
|
3833
|
-
sourceNode,
|
|
3834
|
-
targetNode,
|
|
3835
|
-
relatedNodes,
|
|
3836
|
-
relatedEdges: surroundingEdges
|
|
3837
|
-
};
|
|
3838
|
-
}
|
|
3839
|
-
function getOrganizationGraphDetailState(graph, selectedElement) {
|
|
3840
|
-
if (!selectedElement) {
|
|
3841
|
-
return {
|
|
3842
|
-
state: "empty",
|
|
3843
|
-
title: "No element selected",
|
|
3844
|
-
semanticCategory: "Selection",
|
|
3845
|
-
operationalMeaning: "Select a node or edge to inspect its semantic and operational context.",
|
|
3846
|
-
metrics: [],
|
|
3847
|
-
metadata: [],
|
|
3848
|
-
adjacentKindCounts: []
|
|
3849
|
-
};
|
|
3850
|
-
}
|
|
3851
|
-
if (!graph) {
|
|
3852
|
-
return {
|
|
3853
|
-
state: "missing",
|
|
3854
|
-
title: "Graph unavailable",
|
|
3855
|
-
semanticCategory: selectedElement.type === "node" ? "Selected node" : "Selected edge",
|
|
3856
|
-
operationalMeaning: "The graph data is not available yet, so this selection cannot be resolved.",
|
|
3857
|
-
metrics: [],
|
|
3858
|
-
metadata: [{ label: "Selected ID", value: selectedElement.id }],
|
|
3859
|
-
adjacentKindCounts: [],
|
|
3860
|
-
missingId: selectedElement.id
|
|
3861
|
-
};
|
|
3862
|
-
}
|
|
3863
|
-
const { nodesById, edgesById } = getGraphIndex(graph);
|
|
3864
|
-
if (selectedElement.type === "node") {
|
|
3865
|
-
const node = nodesById.get(selectedElement.id);
|
|
3866
|
-
if (!node) {
|
|
3867
|
-
return {
|
|
3868
|
-
state: "missing",
|
|
3869
|
-
title: "Selected node unavailable",
|
|
3870
|
-
semanticCategory: "Node",
|
|
3871
|
-
operationalMeaning: "The selected node is no longer present in the current graph build.",
|
|
3872
|
-
metrics: [],
|
|
3873
|
-
metadata: [{ label: "Selected ID", value: selectedElement.id }],
|
|
3874
|
-
adjacentKindCounts: [],
|
|
3875
|
-
missingId: selectedElement.id
|
|
3876
|
-
};
|
|
3877
|
-
}
|
|
3878
|
-
return buildNodeState(graph, node, nodesById);
|
|
3879
|
-
}
|
|
3880
|
-
const edge = edgesById.get(selectedElement.id);
|
|
3881
|
-
if (!edge) {
|
|
3882
|
-
return {
|
|
3883
|
-
state: "missing",
|
|
3884
|
-
title: "Selected edge unavailable",
|
|
3885
|
-
semanticCategory: "Edge",
|
|
3886
|
-
operationalMeaning: "The selected edge is no longer present in the current graph build.",
|
|
3887
|
-
metrics: [],
|
|
3888
|
-
metadata: [{ label: "Selected ID", value: selectedElement.id }],
|
|
3889
|
-
adjacentKindCounts: [],
|
|
3890
|
-
missingId: selectedElement.id
|
|
3891
|
-
};
|
|
3892
|
-
}
|
|
3893
|
-
return buildEdgeState(graph, edge, nodesById);
|
|
3894
|
-
}
|
|
3895
|
-
function getNodeKindColor(kind) {
|
|
3896
|
-
switch (kind) {
|
|
3897
|
-
case "organization":
|
|
3898
|
-
return "gray";
|
|
3899
|
-
case "feature":
|
|
3900
|
-
return "blue";
|
|
3901
|
-
case "domain":
|
|
3902
|
-
return "violet";
|
|
3903
|
-
case "surface":
|
|
3904
|
-
return "cyan";
|
|
3905
|
-
case "entity":
|
|
3906
|
-
return "pink";
|
|
3907
|
-
case "capability":
|
|
3908
|
-
return "green";
|
|
3909
|
-
case "resource":
|
|
3910
|
-
return "orange";
|
|
3911
|
-
default:
|
|
3912
|
-
return "gray";
|
|
3913
|
-
}
|
|
3914
|
-
}
|
|
3915
|
-
function getEdgeKindColor(kind) {
|
|
3916
|
-
switch (kind) {
|
|
3917
|
-
case "contains":
|
|
3918
|
-
return "gray";
|
|
3919
|
-
case "references":
|
|
3920
|
-
return "cyan";
|
|
3921
|
-
case "exposes":
|
|
3922
|
-
return "blue";
|
|
3923
|
-
case "maps_to":
|
|
3924
|
-
return "violet";
|
|
3925
|
-
default:
|
|
3926
|
-
return "gray";
|
|
3927
|
-
}
|
|
3928
|
-
}
|
|
3929
|
-
function getNodeKindLabel2(kind) {
|
|
3930
|
-
switch (kind) {
|
|
3931
|
-
case "organization":
|
|
3932
|
-
return "Organization root";
|
|
3933
|
-
case "feature":
|
|
3934
|
-
return "Feature gate";
|
|
3935
|
-
case "domain":
|
|
3936
|
-
return "Domain boundary";
|
|
3937
|
-
case "surface":
|
|
3938
|
-
return "Surface";
|
|
3939
|
-
case "entity":
|
|
3940
|
-
return "Entity";
|
|
3941
|
-
case "capability":
|
|
3942
|
-
return "Capability";
|
|
3943
|
-
case "resource":
|
|
3944
|
-
return "Resource";
|
|
3945
|
-
default:
|
|
3946
|
-
return kind;
|
|
3947
|
-
}
|
|
3948
|
-
}
|
|
3949
|
-
function titleCase2(value) {
|
|
3950
|
-
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
3951
|
-
}
|
|
3952
|
-
function MetricCard({ metric }) {
|
|
3953
|
-
return /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3954
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: metric.label }),
|
|
3955
|
-
/* @__PURE__ */ jsx(Text, { size: "lg", fw: 800, children: metric.value }),
|
|
3956
|
-
metric.hint ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: metric.hint }) : null
|
|
3957
|
-
] }) });
|
|
3958
|
-
}
|
|
3959
|
-
function RelatedItemCard({ item, itemType }) {
|
|
3960
|
-
const badgeColor = itemType === "node" ? getNodeKindColor(item.kind) : getEdgeKindColor(item.kind);
|
|
3961
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3962
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
|
|
3963
|
-
/* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
|
|
3964
|
-
/* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: badgeColor, children: item.kindLabel })
|
|
3965
|
-
] }),
|
|
3966
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.context }),
|
|
3967
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.id })
|
|
3968
|
-
] }) });
|
|
3969
|
-
}
|
|
3970
|
-
function getStatusColor3(value) {
|
|
3971
|
-
switch (value) {
|
|
3972
|
-
case "failed":
|
|
3973
|
-
return "red";
|
|
3974
|
-
case "warning":
|
|
3975
|
-
return "yellow";
|
|
3976
|
-
case "running":
|
|
3977
|
-
case "processing":
|
|
3978
|
-
return "blue";
|
|
3979
|
-
case "completed":
|
|
3980
|
-
return "green";
|
|
3981
|
-
case "pending":
|
|
3982
|
-
return "orange";
|
|
3983
|
-
case "expired":
|
|
3984
|
-
return "gray";
|
|
3985
|
-
default:
|
|
3986
|
-
return "gray";
|
|
3987
|
-
}
|
|
3988
|
-
}
|
|
3989
|
-
function FollowUpSectionCard({ section }) {
|
|
3990
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3991
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
3992
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3993
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: section.title }),
|
|
3994
|
-
section.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: section.description }) : null
|
|
3995
|
-
] }),
|
|
3996
|
-
section.primaryAction ? /* @__PURE__ */ jsx(
|
|
3997
|
-
Button,
|
|
3998
|
-
{
|
|
3999
|
-
size: "xs",
|
|
4000
|
-
variant: "light",
|
|
4001
|
-
component: "a",
|
|
4002
|
-
href: section.primaryAction.href,
|
|
4003
|
-
target: "_blank",
|
|
4004
|
-
rel: "noreferrer",
|
|
4005
|
-
children: section.primaryAction.label
|
|
4006
|
-
}
|
|
4007
|
-
) : null
|
|
4008
|
-
] }),
|
|
4009
|
-
section.items.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: section.items.map((item) => /* @__PURE__ */ jsx(
|
|
4010
|
-
Paper,
|
|
4011
|
-
{
|
|
4012
|
-
withBorder: true,
|
|
4013
|
-
radius: "md",
|
|
4014
|
-
p: "sm",
|
|
4015
|
-
component: "a",
|
|
4016
|
-
href: item.href,
|
|
4017
|
-
target: "_blank",
|
|
4018
|
-
rel: "noreferrer",
|
|
4019
|
-
style: { display: "block", textDecoration: "none", color: "inherit" },
|
|
4020
|
-
children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
4021
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
|
|
4022
|
-
/* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
|
|
4023
|
-
item.badgeLabel ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: item.badgeColor ?? getStatusColor3(item.badgeLabel), children: item.badgeLabel }) : null
|
|
4024
|
-
] }),
|
|
4025
|
-
item.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.description }) : null,
|
|
4026
|
-
item.meta ? /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.meta }) : null
|
|
4027
|
-
] })
|
|
4028
|
-
},
|
|
4029
|
-
item.id
|
|
4030
|
-
)) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: section.emptyMessage })
|
|
4031
|
-
] }) });
|
|
4032
|
-
}
|
|
4033
|
-
function OrganizationGraphDetailPanel({
|
|
4034
|
-
graph,
|
|
4035
|
-
selectedElement,
|
|
4036
|
-
supplementalSummary,
|
|
4037
|
-
followUpSections,
|
|
4038
|
-
expandAroundPanel,
|
|
4039
|
-
onClearSelection,
|
|
4040
|
-
className
|
|
4041
|
-
}) {
|
|
4042
|
-
const state = getOrganizationGraphDetailState(graph, selectedElement);
|
|
4043
|
-
if (state.state === "empty") {
|
|
4044
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsx(EmptyState, { icon: IconShare2, title: state.title, description: state.operationalMeaning, py: "md" }) });
|
|
4045
|
-
}
|
|
4046
|
-
if (state.state === "missing") {
|
|
4047
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
4048
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
4049
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
4050
|
-
/* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", children: state.title }),
|
|
4051
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
|
|
4052
|
-
] }),
|
|
4053
|
-
onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
|
|
4054
|
-
] }),
|
|
4055
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "gray", children: state.semanticCategory }),
|
|
4056
|
-
/* @__PURE__ */ jsxs(Paper, { withBorder: true, radius: "md", p: "sm", children: [
|
|
4057
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Selected ID" }),
|
|
4058
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", children: state.missingId })
|
|
4059
|
-
] })
|
|
4060
|
-
] }) });
|
|
4061
|
-
}
|
|
4062
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
4063
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
|
|
4064
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
4065
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
4066
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "violet", children: state.semanticCategory }),
|
|
4067
|
-
state.state === "node" ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: state.node.enabled === false ? "gray" : "green", children: state.node.enabled === false ? "Disabled" : "Enabled" }) : null,
|
|
4068
|
-
state.state === "edge" && state.edge.relationshipType ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "orange", children: titleCase2(state.edge.relationshipType) }) : null
|
|
4069
|
-
] }),
|
|
4070
|
-
/* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", children: state.title }),
|
|
4071
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
|
|
4072
|
-
] }),
|
|
4073
|
-
onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
|
|
4074
|
-
] }),
|
|
4075
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: state.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, metric.label)) }),
|
|
4076
|
-
expandAroundPanel,
|
|
4077
|
-
supplementalSummary && (supplementalSummary.metrics.length > 0 || supplementalSummary.metadata.length > 0) ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4078
|
-
/* @__PURE__ */ jsx(
|
|
4079
|
-
Divider,
|
|
4080
|
-
{
|
|
4081
|
-
label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
4082
|
-
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
|
|
4083
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: supplementalSummary.title })
|
|
4084
|
-
] }),
|
|
4085
|
-
labelPosition: "center"
|
|
4086
|
-
}
|
|
4087
|
-
),
|
|
4088
|
-
supplementalSummary.description ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: supplementalSummary.description }) : null,
|
|
4089
|
-
supplementalSummary.metrics.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: supplementalSummary.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, `supplemental-${metric.label}`)) }) : null,
|
|
4090
|
-
supplementalSummary.metadata.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: supplementalSummary.metadata.map((item) => /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4091
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
|
|
4092
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
|
|
4093
|
-
] }) }, `supplemental-${item.label}`)) }) : null
|
|
4094
|
-
] }) : null,
|
|
4095
|
-
followUpSections && followUpSections.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4096
|
-
/* @__PURE__ */ jsx(
|
|
4097
|
-
Divider,
|
|
4098
|
-
{
|
|
4099
|
-
label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
4100
|
-
/* @__PURE__ */ jsx(IconShare2, { size: 14 }),
|
|
4101
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Follow-up actions" })
|
|
4102
|
-
] }),
|
|
4103
|
-
labelPosition: "center"
|
|
4104
|
-
}
|
|
4105
|
-
),
|
|
4106
|
-
/* @__PURE__ */ jsx(Stack, { gap: "sm", children: followUpSections.map((section) => /* @__PURE__ */ jsx(FollowUpSectionCard, { section }, section.title)) })
|
|
4107
|
-
] }) : null,
|
|
4108
|
-
/* @__PURE__ */ jsx(
|
|
4109
|
-
Divider,
|
|
4110
|
-
{
|
|
4111
|
-
label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
4112
|
-
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
|
|
4113
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Linked metadata" })
|
|
4114
|
-
] }),
|
|
4115
|
-
labelPosition: "center"
|
|
4116
|
-
}
|
|
4117
|
-
),
|
|
4118
|
-
/* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.metadata.map((item) => /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4119
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
|
|
4120
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
|
|
4121
|
-
] }) }, item.label)) }),
|
|
4122
|
-
state.adjacentKindCounts.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4123
|
-
/* @__PURE__ */ jsx(
|
|
4124
|
-
Divider,
|
|
4125
|
-
{
|
|
4126
|
-
label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
4127
|
-
/* @__PURE__ */ jsx(IconShare2, { size: 14 }),
|
|
4128
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Nearby kinds" })
|
|
4129
|
-
] }),
|
|
4130
|
-
labelPosition: "center"
|
|
4131
|
-
}
|
|
4132
|
-
),
|
|
4133
|
-
/* @__PURE__ */ jsx(Group, { gap: "xs", children: state.adjacentKindCounts.map((item) => /* @__PURE__ */ jsxs(Badge, { variant: "light", color: getNodeKindColor(item.kind), children: [
|
|
4134
|
-
item.count,
|
|
4135
|
-
" ",
|
|
4136
|
-
item.label
|
|
4137
|
-
] }, item.kind)) })
|
|
4138
|
-
] }) : null,
|
|
4139
|
-
state.state === "edge" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4140
|
-
/* @__PURE__ */ jsx(
|
|
4141
|
-
Divider,
|
|
4142
|
-
{
|
|
4143
|
-
label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
|
|
4144
|
-
/* @__PURE__ */ jsx(IconShare2, { size: 14 }),
|
|
4145
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Endpoints" })
|
|
4146
|
-
] }),
|
|
4147
|
-
labelPosition: "center"
|
|
4148
|
-
}
|
|
4149
|
-
),
|
|
4150
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
|
|
4151
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4152
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Source" }),
|
|
4153
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
4154
|
-
/* @__PURE__ */ jsx(Text, { fw: 700, children: state.sourceNode?.label ?? state.edge.sourceId }),
|
|
4155
|
-
/* @__PURE__ */ jsx(
|
|
4156
|
-
Badge,
|
|
4157
|
-
{
|
|
4158
|
-
size: "xs",
|
|
4159
|
-
variant: "light",
|
|
4160
|
-
color: state.sourceNode ? getNodeKindColor(state.sourceNode.kind) : "gray",
|
|
4161
|
-
children: state.sourceNode ? getNodeKindLabel2(state.sourceNode.kind) : "unresolved"
|
|
4162
|
-
}
|
|
4163
|
-
)
|
|
4164
|
-
] })
|
|
4165
|
-
] }) }),
|
|
4166
|
-
/* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
4167
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Target" }),
|
|
4168
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
4169
|
-
/* @__PURE__ */ jsx(Text, { fw: 700, children: state.targetNode?.label ?? state.edge.targetId }),
|
|
4170
|
-
/* @__PURE__ */ jsx(
|
|
4171
|
-
Badge,
|
|
4172
|
-
{
|
|
4173
|
-
size: "xs",
|
|
4174
|
-
variant: "light",
|
|
4175
|
-
color: state.targetNode ? getNodeKindColor(state.targetNode.kind) : "gray",
|
|
4176
|
-
children: state.targetNode ? getNodeKindLabel2(state.targetNode.kind) : "unresolved"
|
|
4177
|
-
}
|
|
4178
|
-
)
|
|
4179
|
-
] })
|
|
4180
|
-
] }) })
|
|
4181
|
-
] })
|
|
4182
|
-
] }) : null,
|
|
4183
|
-
/* @__PURE__ */ jsx(
|
|
4184
|
-
Divider,
|
|
4185
|
-
{
|
|
4186
|
-
label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding nodes" : "Direct nodes" }),
|
|
4187
|
-
labelPosition: "center"
|
|
4188
|
-
}
|
|
4189
|
-
),
|
|
4190
|
-
state.relatedNodes.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.relatedNodes.map((item) => /* @__PURE__ */ jsx(RelatedItemCard, { item, itemType: "node" }, item.id)) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No nearby nodes were found in the current graph selection." }),
|
|
4191
|
-
/* @__PURE__ */ jsx(
|
|
4192
|
-
Divider,
|
|
4193
|
-
{
|
|
4194
|
-
label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding edges" : "Direct edges" }),
|
|
4195
|
-
labelPosition: "center"
|
|
4196
|
-
}
|
|
4197
|
-
),
|
|
4198
|
-
state.relatedEdges.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.relatedEdges.map((item) => /* @__PURE__ */ jsx(RelatedItemCard, { item, itemType: "edge" }, item.id)) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No adjacent edges were found for the current selection." })
|
|
4199
|
-
] }) });
|
|
4200
|
-
}
|
|
4201
|
-
|
|
4202
|
-
// src/features/operations/organization-graph/types.ts
|
|
4203
|
-
var ORGANIZATION_GRAPH_NODE_KIND_ORDER = [
|
|
4204
|
-
"organization",
|
|
4205
|
-
"feature",
|
|
4206
|
-
"surface",
|
|
4207
|
-
"entity",
|
|
4208
|
-
"capability",
|
|
4209
|
-
"resource",
|
|
4210
|
-
"knowledge"
|
|
4211
|
-
];
|
|
4212
|
-
var ORGANIZATION_GRAPH_NODE_KIND_LABELS = {
|
|
4213
|
-
organization: "Organization",
|
|
4214
|
-
feature: "Feature",
|
|
4215
|
-
surface: "Surface",
|
|
4216
|
-
entity: "Entity",
|
|
4217
|
-
capability: "Capability",
|
|
4218
|
-
resource: "Resource",
|
|
4219
|
-
knowledge: "Knowledge"
|
|
4220
|
-
};
|
|
4221
|
-
var DEFAULT_ORGANIZATION_GRAPH_FILTERS = {
|
|
4222
|
-
search: "",
|
|
4223
|
-
nodeKinds: [],
|
|
4224
|
-
topologyPresence: "all",
|
|
4225
|
-
environmentStatus: "all",
|
|
4226
|
-
resourceTypes: [],
|
|
4227
|
-
showIntegrations: true,
|
|
4228
|
-
domainFilters: {}
|
|
4229
|
-
};
|
|
4230
|
-
|
|
4231
|
-
// src/features/operations/organization-graph/helpers.ts
|
|
4232
|
-
var TOPLOGY_EDGE_TYPES = /* @__PURE__ */ new Set(["maps_to", "triggers", "uses", "approval"]);
|
|
4233
|
-
function getCommandViewNodes(data) {
|
|
4234
|
-
return [
|
|
4235
|
-
...data.agents,
|
|
4236
|
-
...data.workflows,
|
|
4237
|
-
...data.triggers,
|
|
4238
|
-
...data.integrations,
|
|
4239
|
-
...data.externalResources,
|
|
4240
|
-
...data.humanCheckpoints
|
|
4241
|
-
];
|
|
4242
|
-
}
|
|
4243
|
-
function getCommandViewNodeForGraphNode(node, commandViewData) {
|
|
4244
|
-
if (!commandViewData || node.kind !== "resource" || !node.sourceId) {
|
|
4245
|
-
return null;
|
|
4246
|
-
}
|
|
4247
|
-
return getCommandViewNodes(commandViewData).find((item) => item.resourceId === node.sourceId) ?? null;
|
|
4248
|
-
}
|
|
4249
|
-
function normalizeText(value) {
|
|
4250
|
-
return value.trim().toLowerCase();
|
|
4251
|
-
}
|
|
4252
|
-
function includesQuery(value, query) {
|
|
4253
|
-
if (!value) return false;
|
|
4254
|
-
return normalizeText(value).includes(query);
|
|
4255
|
-
}
|
|
4256
|
-
function titleCase3(value) {
|
|
4257
|
-
return value.replace(/_/g, " ").split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
4258
|
-
}
|
|
4259
|
-
function isTopologyEdge(edge) {
|
|
4260
|
-
return TOPLOGY_EDGE_TYPES.has(edge.kind) || Boolean(edge.relationshipType);
|
|
4261
|
-
}
|
|
4262
|
-
function isSemanticEdge(edge) {
|
|
4263
|
-
return !isTopologyEdge(edge);
|
|
4264
|
-
}
|
|
4265
|
-
function getIncidentEdges(graph, nodeId) {
|
|
4266
|
-
return graph.edges.filter((edge) => edge.sourceId === nodeId || edge.targetId === nodeId);
|
|
4267
|
-
}
|
|
4268
|
-
function createOrganizationGraphFilters(partial) {
|
|
4269
|
-
return {
|
|
4270
|
-
search: partial?.search ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.search,
|
|
4271
|
-
nodeKinds: partial?.nodeKinds ? [...partial.nodeKinds] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.nodeKinds],
|
|
4272
|
-
topologyPresence: partial?.topologyPresence ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.topologyPresence,
|
|
4273
|
-
environmentStatus: partial?.environmentStatus ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.environmentStatus,
|
|
4274
|
-
resourceTypes: partial?.resourceTypes ? [...partial.resourceTypes] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.resourceTypes],
|
|
4275
|
-
showIntegrations: partial?.showIntegrations ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.showIntegrations,
|
|
4276
|
-
domainFilters: partial?.domainFilters ? { ...partial.domainFilters } : { ...DEFAULT_ORGANIZATION_GRAPH_FILTERS.domainFilters }
|
|
4277
|
-
};
|
|
4278
|
-
}
|
|
4279
|
-
function normalizeOrganizationGraphSearch(search) {
|
|
4280
|
-
return search.trim().toLowerCase();
|
|
4281
|
-
}
|
|
4282
|
-
function getOrganizationGraphNodePresence(node, incidentEdges) {
|
|
4283
|
-
if (node.kind === "resource") {
|
|
4284
|
-
const relevantEdges = incidentEdges.filter((edge) => edge.kind !== "contains");
|
|
4285
|
-
const hasTopologyEdges2 = relevantEdges.some(isTopologyEdge);
|
|
4286
|
-
const hasSemanticEdges2 = relevantEdges.some(isSemanticEdge);
|
|
4287
|
-
if (hasTopologyEdges2 && hasSemanticEdges2) {
|
|
4288
|
-
return "bridge";
|
|
4289
|
-
}
|
|
4290
|
-
if (hasTopologyEdges2) {
|
|
4291
|
-
return "topology-only";
|
|
4292
|
-
}
|
|
4293
|
-
return "semantic-only";
|
|
4294
|
-
}
|
|
4295
|
-
const hasTopologyEdges = incidentEdges.some(isTopologyEdge);
|
|
4296
|
-
const hasSemanticEdges = incidentEdges.some(isSemanticEdge);
|
|
4297
|
-
if (hasTopologyEdges && hasSemanticEdges) {
|
|
4298
|
-
return "bridge";
|
|
4299
|
-
}
|
|
4300
|
-
if (hasTopologyEdges) {
|
|
4301
|
-
return "topology-only";
|
|
4302
|
-
}
|
|
4303
|
-
return "semantic-only";
|
|
4304
|
-
}
|
|
4305
|
-
function getOrganizationGraphNodePresenceMap(graph) {
|
|
4306
|
-
const presenceByNodeId = /* @__PURE__ */ new Map();
|
|
4307
|
-
for (const node of graph.nodes) {
|
|
4308
|
-
presenceByNodeId.set(node.id, getOrganizationGraphNodePresence(node, getIncidentEdges(graph, node.id)));
|
|
4309
|
-
}
|
|
4310
|
-
return presenceByNodeId;
|
|
4311
|
-
}
|
|
4312
|
-
function getOrganizationGraphNodeKindOptions(kinds = ORGANIZATION_GRAPH_NODE_KIND_ORDER) {
|
|
4313
|
-
return kinds.map((kind) => ({
|
|
4314
|
-
kind,
|
|
4315
|
-
label: ORGANIZATION_GRAPH_NODE_KIND_LABELS[kind]
|
|
4316
|
-
}));
|
|
4317
|
-
}
|
|
4318
|
-
function getOrganizationGraphResourceTypeOptions(resourceTypes = [
|
|
4319
|
-
"workflow",
|
|
4320
|
-
"agent",
|
|
4321
|
-
"trigger",
|
|
4322
|
-
"integration",
|
|
4323
|
-
"external",
|
|
4324
|
-
"human_checkpoint"
|
|
4325
|
-
]) {
|
|
4326
|
-
return resourceTypes.map((resourceType) => ({
|
|
4327
|
-
resourceType,
|
|
4328
|
-
label: titleCase3(resourceType)
|
|
4329
|
-
}));
|
|
4330
|
-
}
|
|
4331
|
-
function getNodeStatus(node, commandViewData) {
|
|
4332
|
-
const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
|
|
4333
|
-
if (commandViewNode) {
|
|
4334
|
-
return commandViewNode.status;
|
|
4335
|
-
}
|
|
4336
|
-
return "status" in node && typeof node.status === "string" ? node.status : void 0;
|
|
4337
|
-
}
|
|
4338
|
-
function getExplicitNodeFacets(node, commandViewData) {
|
|
4339
|
-
const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
|
|
4340
|
-
if (commandViewNode) {
|
|
4341
|
-
return [
|
|
4342
|
-
...commandViewNode.category ? [`category:${commandViewNode.category}`] : [],
|
|
4343
|
-
...commandViewNode.links?.map((link) => link.nodeId) ?? []
|
|
4344
|
-
];
|
|
4345
|
-
}
|
|
4346
|
-
return [];
|
|
4347
|
-
}
|
|
4348
|
-
function getNodeFacets(graph, node, commandViewData) {
|
|
4349
|
-
const explicitFacets = getExplicitNodeFacets(node, commandViewData);
|
|
4350
|
-
if (explicitFacets.length > 0) {
|
|
4351
|
-
return explicitFacets;
|
|
4352
|
-
}
|
|
4353
|
-
if (node.kind === "feature") {
|
|
4354
|
-
return node.sourceId ? [node.sourceId] : [];
|
|
4355
|
-
}
|
|
4356
|
-
if (node.kind !== "resource") {
|
|
4357
|
-
return [];
|
|
4358
|
-
}
|
|
4359
|
-
const facetIds = /* @__PURE__ */ new Set();
|
|
4360
|
-
for (const edge of graph.edges) {
|
|
4361
|
-
if (edge.sourceId !== node.id) {
|
|
4362
|
-
continue;
|
|
4363
|
-
}
|
|
4364
|
-
const targetNode = graph.nodes.find((candidate) => candidate.id === edge.targetId);
|
|
4365
|
-
if (targetNode?.kind === "feature" && targetNode.sourceId) {
|
|
4366
|
-
facetIds.add(targetNode.id);
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
return [...facetIds];
|
|
4370
|
-
}
|
|
4371
|
-
function matchesOrganizationGraphNodeSearch(node, search) {
|
|
4372
|
-
const query = normalizeOrganizationGraphSearch(search);
|
|
4373
|
-
if (!query) return true;
|
|
4374
|
-
const nodeStatus = getNodeStatus(node);
|
|
4375
|
-
const nodeFacets = getExplicitNodeFacets(node);
|
|
4376
|
-
return includesQuery(node.id, query) || includesQuery(node.label, query) || includesQuery(node.description, query) || includesQuery(node.sourceId, query) || includesQuery(node.featureId, query) || includesQuery(node.resourceType, query) || includesQuery(nodeStatus, query) || nodeFacets.some((facet) => includesQuery(facet, query)) || includesQuery(node.kind, query);
|
|
4377
|
-
}
|
|
4378
|
-
function matchesOrganizationGraphEdgeSearch(edge, graph, search) {
|
|
4379
|
-
const query = normalizeOrganizationGraphSearch(search);
|
|
4380
|
-
if (!query) return true;
|
|
4381
|
-
const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
|
|
4382
|
-
const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
|
|
4383
|
-
return includesQuery(edge.id, query) || includesQuery(edge.label, query) || includesQuery(edge.kind, query) || includesQuery(edge.relationshipType, query) || includesQuery(sourceNode?.label, query) || includesQuery(sourceNode?.sourceId, query) || includesQuery(targetNode?.label, query) || includesQuery(targetNode?.sourceId, query);
|
|
4384
|
-
}
|
|
4385
|
-
function matchesTopologyPresence(nodePresence, topologyPresence) {
|
|
4386
|
-
if (topologyPresence === "all") return true;
|
|
4387
|
-
return nodePresence === topologyPresence;
|
|
4388
|
-
}
|
|
4389
|
-
function hasActiveDomainFilters(domainFilters) {
|
|
4390
|
-
return Object.values(domainFilters).some((filterState) => filterState !== "neutral");
|
|
4391
|
-
}
|
|
4392
|
-
function matchesDomainFilters(graph, node, domainFilters, commandViewData) {
|
|
4393
|
-
if (!hasActiveDomainFilters(domainFilters)) {
|
|
4394
|
-
return true;
|
|
4395
|
-
}
|
|
4396
|
-
const includedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "include").map(([domainId]) => domainId);
|
|
4397
|
-
const excludedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "exclude").map(([domainId]) => domainId);
|
|
4398
|
-
const nodeFacets = getNodeFacets(graph, node, commandViewData);
|
|
4399
|
-
if (excludedDomains.length > 0 && nodeFacets.some((domainId) => excludedDomains.includes(domainId))) {
|
|
4400
|
-
return false;
|
|
4401
|
-
}
|
|
4402
|
-
if (includedDomains.length > 0 && !nodeFacets.some((domainId) => includedDomains.includes(domainId))) {
|
|
4403
|
-
return false;
|
|
4404
|
-
}
|
|
4405
|
-
return true;
|
|
4406
|
-
}
|
|
4407
|
-
function matchesEnvironmentStatus(node, environmentStatus, commandViewData) {
|
|
4408
|
-
if (environmentStatus === "all") {
|
|
4409
|
-
return true;
|
|
4410
|
-
}
|
|
4411
|
-
const nodeStatus = getNodeStatus(node, commandViewData);
|
|
4412
|
-
if (!nodeStatus) {
|
|
4413
|
-
return true;
|
|
4414
|
-
}
|
|
4415
|
-
return nodeStatus === environmentStatus;
|
|
4416
|
-
}
|
|
4417
|
-
function matchesResourceTypeFilters(node, resourceTypes) {
|
|
4418
|
-
if (node.kind !== "resource" || resourceTypes.length === 0) {
|
|
4419
|
-
return true;
|
|
4420
|
-
}
|
|
4421
|
-
return Boolean(node.resourceType && resourceTypes.includes(node.resourceType));
|
|
4422
|
-
}
|
|
4423
|
-
function matchesIntegrationVisibility(node, showIntegrations) {
|
|
4424
|
-
if (showIntegrations) {
|
|
4425
|
-
return true;
|
|
4426
|
-
}
|
|
4427
|
-
return !(node.kind === "resource" && node.resourceType === "integration");
|
|
4428
|
-
}
|
|
4429
|
-
function filterOrganizationGraph(graph, filters, options) {
|
|
4430
|
-
const normalizedFilters = createOrganizationGraphFilters(filters);
|
|
4431
|
-
const normalizedSearch = normalizeOrganizationGraphSearch(normalizedFilters.search);
|
|
4432
|
-
const nodePresenceMap = getOrganizationGraphNodePresenceMap(graph);
|
|
4433
|
-
const selectedKinds = new Set(normalizedFilters.nodeKinds);
|
|
4434
|
-
const commandViewData = options?.commandViewData;
|
|
4435
|
-
const visibleNodeIds = /* @__PURE__ */ new Set();
|
|
4436
|
-
for (const node of graph.nodes) {
|
|
4437
|
-
if (selectedKinds.size > 0 && !selectedKinds.has(node.kind)) {
|
|
4438
|
-
continue;
|
|
4439
|
-
}
|
|
4440
|
-
if (!matchesIntegrationVisibility(node, normalizedFilters.showIntegrations)) {
|
|
4441
|
-
continue;
|
|
4442
|
-
}
|
|
4443
|
-
if (!matchesResourceTypeFilters(node, normalizedFilters.resourceTypes)) {
|
|
4444
|
-
continue;
|
|
4445
|
-
}
|
|
4446
|
-
if (!matchesEnvironmentStatus(node, normalizedFilters.environmentStatus, commandViewData)) {
|
|
4447
|
-
continue;
|
|
4448
|
-
}
|
|
4449
|
-
if (!matchesDomainFilters(graph, node, normalizedFilters.domainFilters, commandViewData)) {
|
|
4450
|
-
continue;
|
|
4451
|
-
}
|
|
4452
|
-
const presence = nodePresenceMap.get(node.id) ?? "semantic-only";
|
|
4453
|
-
if (!matchesTopologyPresence(presence, normalizedFilters.topologyPresence)) {
|
|
4454
|
-
continue;
|
|
4455
|
-
}
|
|
4456
|
-
if (normalizedSearch && !matchesOrganizationGraphNodeSearch(node, normalizedSearch)) {
|
|
4457
|
-
const incidentEdges = getIncidentEdges(graph, node.id);
|
|
4458
|
-
const edgeMatch = incidentEdges.some((edge) => matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch));
|
|
4459
|
-
if (!edgeMatch) {
|
|
4460
|
-
continue;
|
|
4461
|
-
}
|
|
4462
|
-
}
|
|
4463
|
-
visibleNodeIds.add(node.id);
|
|
4464
|
-
}
|
|
4465
|
-
const visibleEdges = graph.edges.filter((edge) => {
|
|
4466
|
-
const sourceVisible = visibleNodeIds.has(edge.sourceId);
|
|
4467
|
-
const targetVisible = visibleNodeIds.has(edge.targetId);
|
|
4468
|
-
if (!sourceVisible || !targetVisible) {
|
|
4469
|
-
return false;
|
|
4470
|
-
}
|
|
4471
|
-
if (normalizedSearch && !matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch)) {
|
|
4472
|
-
const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
|
|
4473
|
-
const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
|
|
4474
|
-
const nodeSearchMatch = Boolean(sourceNode && matchesOrganizationGraphNodeSearch(sourceNode, normalizedSearch)) || Boolean(targetNode && matchesOrganizationGraphNodeSearch(targetNode, normalizedSearch));
|
|
4475
|
-
if (!nodeSearchMatch) {
|
|
4476
|
-
return false;
|
|
4477
|
-
}
|
|
4478
|
-
}
|
|
4479
|
-
return true;
|
|
4480
|
-
});
|
|
4481
|
-
return {
|
|
4482
|
-
...graph,
|
|
4483
|
-
nodes: graph.nodes.filter((node) => visibleNodeIds.has(node.id)),
|
|
4484
|
-
edges: visibleEdges
|
|
4485
|
-
};
|
|
4486
|
-
}
|
|
4487
|
-
function getCommandViewResourceCategory(node, commandViewData) {
|
|
4488
|
-
return getCommandViewNodeForGraphNode(node, commandViewData)?.category ?? null;
|
|
4489
|
-
}
|
|
4490
|
-
function getConnectedHiddenResourceIds(graph, nodeId, hiddenIds) {
|
|
4491
|
-
if (!nodeId) {
|
|
4492
|
-
return /* @__PURE__ */ new Set();
|
|
4493
|
-
}
|
|
4494
|
-
const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
4495
|
-
const connectedIds = /* @__PURE__ */ new Set();
|
|
4496
|
-
for (const edge of graph.edges) {
|
|
4497
|
-
const neighborId = edge.sourceId === nodeId ? edge.targetId : edge.targetId === nodeId ? edge.sourceId : null;
|
|
4498
|
-
if (!neighborId || !hiddenIds.has(neighborId)) {
|
|
4499
|
-
continue;
|
|
4500
|
-
}
|
|
4501
|
-
if (nodesById.get(neighborId)?.kind === "resource") {
|
|
4502
|
-
connectedIds.add(neighborId);
|
|
4503
|
-
}
|
|
4504
|
-
}
|
|
4505
|
-
return connectedIds;
|
|
4506
|
-
}
|
|
4507
|
-
function getCommandViewVisibilityProjection({
|
|
4508
|
-
graph,
|
|
4509
|
-
commandViewData,
|
|
4510
|
-
resourcesHidden,
|
|
4511
|
-
diagnosticsHidden,
|
|
4512
|
-
diagnosticCategories,
|
|
4513
|
-
revealedIds = /* @__PURE__ */ new Set(),
|
|
4514
|
-
mode
|
|
4515
|
-
}) {
|
|
4516
|
-
const hiddenIds = /* @__PURE__ */ new Set();
|
|
4517
|
-
const hiddenEdgeIds = /* @__PURE__ */ new Set();
|
|
4518
|
-
const diagnosticCategorySet = new Set(diagnosticCategories);
|
|
4519
|
-
let totalResourceCount = 0;
|
|
4520
|
-
let hiddenDiagnosticResourceCount = 0;
|
|
4521
|
-
if (mode === "trace" || mode === "impact") {
|
|
4522
|
-
const resourceCount = graph.nodes.filter((node) => node.kind === "resource").length;
|
|
4523
|
-
return {
|
|
4524
|
-
hiddenIds,
|
|
4525
|
-
hiddenEdgeIds,
|
|
4526
|
-
totalResourceCount: resourceCount,
|
|
4527
|
-
visibleResourceCount: resourceCount,
|
|
4528
|
-
hiddenResourceCount: 0,
|
|
4529
|
-
hiddenDiagnosticResourceCount: 0
|
|
4530
|
-
};
|
|
4531
|
-
}
|
|
4532
|
-
for (const node of graph.nodes) {
|
|
4533
|
-
if (node.kind !== "resource") {
|
|
4534
|
-
continue;
|
|
4535
|
-
}
|
|
4536
|
-
totalResourceCount += 1;
|
|
4537
|
-
const category = getCommandViewResourceCategory(node, commandViewData);
|
|
4538
|
-
const isDiagnostic = Boolean(category && diagnosticCategorySet.has(category));
|
|
4539
|
-
if (isDiagnostic && diagnosticsHidden) {
|
|
4540
|
-
hiddenDiagnosticResourceCount += 1;
|
|
4541
|
-
}
|
|
4542
|
-
if (revealedIds.has(node.id)) {
|
|
4543
|
-
continue;
|
|
4544
|
-
}
|
|
4545
|
-
if (resourcesHidden || diagnosticsHidden && isDiagnostic) {
|
|
4546
|
-
hiddenIds.add(node.id);
|
|
4547
|
-
}
|
|
4548
|
-
}
|
|
4549
|
-
for (const edge of graph.edges) {
|
|
4550
|
-
if (hiddenIds.has(edge.sourceId) || hiddenIds.has(edge.targetId)) {
|
|
4551
|
-
hiddenEdgeIds.add(edge.id);
|
|
4552
|
-
}
|
|
4553
|
-
}
|
|
4554
|
-
const hiddenResourceCount = hiddenIds.size;
|
|
4555
|
-
return {
|
|
4556
|
-
hiddenIds,
|
|
4557
|
-
hiddenEdgeIds,
|
|
4558
|
-
totalResourceCount,
|
|
4559
|
-
visibleResourceCount: totalResourceCount - hiddenResourceCount,
|
|
4560
|
-
hiddenResourceCount,
|
|
4561
|
-
hiddenDiagnosticResourceCount
|
|
4562
|
-
};
|
|
4563
|
-
}
|
|
4564
|
-
function isOrganizationGraphFilterPristine(filters) {
|
|
4565
|
-
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);
|
|
4566
|
-
}
|
|
4567
|
-
var TOPOLOGY_PRESENCE_OPTIONS = [
|
|
4568
|
-
{ label: "All", value: "all" },
|
|
4569
|
-
{ label: "Semantic only", value: "semantic-only" },
|
|
4570
|
-
{ label: "Topology only", value: "topology-only" }
|
|
4571
|
-
];
|
|
4572
|
-
var ENVIRONMENT_STATUS_OPTIONS = [
|
|
4573
|
-
{ label: "All", value: "all" },
|
|
4574
|
-
{ label: "Prod", value: "prod" },
|
|
4575
|
-
{ label: "Dev", value: "dev" }
|
|
4576
|
-
];
|
|
4577
|
-
function OrganizationGraphFilterToolbar({
|
|
4578
|
-
value,
|
|
4579
|
-
onChange,
|
|
4580
|
-
availableKinds,
|
|
4581
|
-
disabled = false,
|
|
4582
|
-
searchPlaceholder = "Search nodes, relationships, or IDs",
|
|
4583
|
-
kindLabel = "Node kinds",
|
|
4584
|
-
resourceTypeLabel = "Resource types",
|
|
4585
|
-
topologyLabel = "Relationship presence",
|
|
4586
|
-
environmentLabel = "Environment",
|
|
4587
|
-
showIntegrationsLabel = "Show integrations",
|
|
4588
|
-
resetLabel = "Reset filters",
|
|
4589
|
-
resetValue = createOrganizationGraphFilters()
|
|
4590
|
-
}) {
|
|
4591
|
-
const kindOptions = getOrganizationGraphNodeKindOptions(availableKinds);
|
|
4592
|
-
const resourceTypeOptions = getOrganizationGraphResourceTypeOptions();
|
|
4593
|
-
const canReset = !isOrganizationGraphFilterPristine(value);
|
|
4594
|
-
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
4595
|
-
/* @__PURE__ */ jsx(
|
|
4596
|
-
TextInput,
|
|
4597
|
-
{
|
|
4598
|
-
label: "Search",
|
|
4599
|
-
placeholder: searchPlaceholder,
|
|
4600
|
-
value: value.search,
|
|
4601
|
-
onChange: (event) => onChange({
|
|
4602
|
-
...value,
|
|
4603
|
-
search: event.currentTarget.value
|
|
4604
|
-
}),
|
|
4605
|
-
leftSection: /* @__PURE__ */ jsx(IconSearch, { size: 14 }),
|
|
4606
|
-
disabled
|
|
4607
|
-
}
|
|
4608
|
-
),
|
|
4609
|
-
/* @__PURE__ */ jsx(
|
|
4610
|
-
MultiSelect,
|
|
4611
|
-
{
|
|
4612
|
-
label: kindLabel,
|
|
4613
|
-
placeholder: "All kinds",
|
|
4614
|
-
data: kindOptions.map((option) => ({ value: option.kind, label: option.label })),
|
|
4615
|
-
value: value.nodeKinds,
|
|
4616
|
-
onChange: (nodeKinds) => onChange({
|
|
4617
|
-
...value,
|
|
4618
|
-
nodeKinds
|
|
4619
|
-
}),
|
|
4620
|
-
searchable: true,
|
|
4621
|
-
clearable: true,
|
|
4622
|
-
disabled
|
|
4623
|
-
}
|
|
4624
|
-
),
|
|
4625
|
-
/* @__PURE__ */ jsx(
|
|
4626
|
-
MultiSelect,
|
|
4627
|
-
{
|
|
4628
|
-
label: resourceTypeLabel,
|
|
4629
|
-
placeholder: "All resource types",
|
|
4630
|
-
data: resourceTypeOptions.map((option) => ({ value: option.resourceType, label: option.label })),
|
|
4631
|
-
value: value.resourceTypes,
|
|
4632
|
-
onChange: (resourceTypes) => onChange({
|
|
4633
|
-
...value,
|
|
4634
|
-
resourceTypes
|
|
4635
|
-
}),
|
|
4636
|
-
searchable: true,
|
|
4637
|
-
clearable: true,
|
|
4638
|
-
disabled
|
|
4639
|
-
}
|
|
4640
|
-
),
|
|
4641
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
4642
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: topologyLabel }),
|
|
4643
|
-
/* @__PURE__ */ jsx(
|
|
4644
|
-
SegmentedControl,
|
|
4645
|
-
{
|
|
4646
|
-
value: value.topologyPresence,
|
|
4647
|
-
onChange: (topologyPresence) => onChange({
|
|
4648
|
-
...value,
|
|
4649
|
-
topologyPresence
|
|
4650
|
-
}),
|
|
4651
|
-
data: TOPOLOGY_PRESENCE_OPTIONS,
|
|
4652
|
-
size: "sm",
|
|
4653
|
-
fullWidth: true,
|
|
4654
|
-
disabled
|
|
4655
|
-
}
|
|
4656
|
-
)
|
|
4657
|
-
] }),
|
|
4658
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
4659
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: environmentLabel }),
|
|
4660
|
-
/* @__PURE__ */ jsx(
|
|
4661
|
-
SegmentedControl,
|
|
4662
|
-
{
|
|
4663
|
-
value: value.environmentStatus,
|
|
4664
|
-
onChange: (environmentStatus) => onChange({
|
|
4665
|
-
...value,
|
|
4666
|
-
environmentStatus
|
|
4667
|
-
}),
|
|
4668
|
-
data: ENVIRONMENT_STATUS_OPTIONS,
|
|
4669
|
-
size: "sm",
|
|
4670
|
-
fullWidth: true,
|
|
4671
|
-
disabled
|
|
4672
|
-
}
|
|
4673
|
-
)
|
|
4674
|
-
] }),
|
|
4675
|
-
/* @__PURE__ */ jsx(
|
|
4676
|
-
Switch,
|
|
4677
|
-
{
|
|
4678
|
-
label: showIntegrationsLabel,
|
|
4679
|
-
description: "Hide integration resources and their relationship edges.",
|
|
4680
|
-
checked: value.showIntegrations,
|
|
4681
|
-
onChange: (event) => onChange({
|
|
4682
|
-
...value,
|
|
4683
|
-
showIntegrations: event.currentTarget.checked
|
|
4684
|
-
}),
|
|
4685
|
-
size: "sm",
|
|
4686
|
-
disabled
|
|
4687
|
-
}
|
|
4688
|
-
),
|
|
4689
|
-
/* @__PURE__ */ jsx(Group, { justify: "flex-end", children: /* @__PURE__ */ jsx(
|
|
4690
|
-
Button,
|
|
4691
|
-
{
|
|
4692
|
-
variant: "subtle",
|
|
4693
|
-
leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
|
|
4694
|
-
onClick: () => onChange(resetValue),
|
|
4695
|
-
disabled: disabled || !canReset,
|
|
4696
|
-
children: resetLabel
|
|
4697
|
-
}
|
|
4698
|
-
) })
|
|
4699
|
-
] });
|
|
4700
|
-
}
|
|
4701
|
-
var useOrganizationGraphFiltersStore = create((set) => ({
|
|
4702
|
-
filtersByScope: {},
|
|
4703
|
-
initializeScope: (scope, initialFilters) => set((state) => {
|
|
4704
|
-
if (state.filtersByScope[scope]) {
|
|
4705
|
-
return state;
|
|
4706
|
-
}
|
|
4707
|
-
return {
|
|
4708
|
-
filtersByScope: {
|
|
4709
|
-
...state.filtersByScope,
|
|
4710
|
-
[scope]: createOrganizationGraphFilters(initialFilters)
|
|
4711
|
-
}
|
|
4712
|
-
};
|
|
4713
|
-
}),
|
|
4714
|
-
updateScope: (scope, next) => set((state) => ({
|
|
4715
|
-
filtersByScope: {
|
|
4716
|
-
...state.filtersByScope,
|
|
4717
|
-
[scope]: createOrganizationGraphFilters({
|
|
4718
|
-
...state.filtersByScope[scope],
|
|
4719
|
-
...next
|
|
4720
|
-
})
|
|
4721
|
-
}
|
|
4722
|
-
})),
|
|
4723
|
-
resetScope: (scope, initialFilters) => set((state) => ({
|
|
4724
|
-
filtersByScope: {
|
|
4725
|
-
...state.filtersByScope,
|
|
4726
|
-
[scope]: createOrganizationGraphFilters(initialFilters)
|
|
4727
|
-
}
|
|
4728
|
-
}))
|
|
4729
|
-
}));
|
|
4730
|
-
function getOrganizationGraphFilterScope(initialFilters) {
|
|
4731
|
-
return JSON.stringify(createOrganizationGraphFilters(initialFilters));
|
|
4732
|
-
}
|
|
4733
|
-
function useOrganizationGraphFilters(initialFilters) {
|
|
4734
|
-
const scopeRef = useRef(getOrganizationGraphFilterScope(initialFilters));
|
|
4735
|
-
const fallbackFiltersRef = useRef(createOrganizationGraphFilters(initialFilters));
|
|
4736
|
-
const filters = useOrganizationGraphFiltersStore(
|
|
4737
|
-
(state) => state.filtersByScope[scopeRef.current] ?? fallbackFiltersRef.current
|
|
4738
|
-
);
|
|
4739
|
-
const initializeScope = useOrganizationGraphFiltersStore((state) => state.initializeScope);
|
|
4740
|
-
const updateScope = useOrganizationGraphFiltersStore((state) => state.updateScope);
|
|
4741
|
-
const resetScope = useOrganizationGraphFiltersStore((state) => state.resetScope);
|
|
4742
|
-
useEffect(() => {
|
|
4743
|
-
initializeScope(scopeRef.current, initialFilters);
|
|
4744
|
-
}, [initialFilters, initializeScope]);
|
|
4745
|
-
const updateFilters = (next) => {
|
|
4746
|
-
updateScope(scopeRef.current, next);
|
|
4747
|
-
};
|
|
4748
|
-
const setSearch = (search) => {
|
|
4749
|
-
updateFilters({ search });
|
|
4750
|
-
};
|
|
4751
|
-
const setNodeKinds = (nodeKinds) => {
|
|
4752
|
-
updateFilters({ nodeKinds });
|
|
4753
|
-
};
|
|
4754
|
-
const setTopologyPresence = (topologyPresence) => {
|
|
4755
|
-
updateFilters({ topologyPresence });
|
|
4756
|
-
};
|
|
4757
|
-
const resetFilters = () => {
|
|
4758
|
-
resetScope(scopeRef.current, initialFilters);
|
|
4759
|
-
};
|
|
4760
|
-
return {
|
|
4761
|
-
filters,
|
|
4762
|
-
setSearch,
|
|
4763
|
-
setNodeKinds,
|
|
4764
|
-
setTopologyPresence,
|
|
4765
|
-
resetFilters,
|
|
4766
|
-
updateFilters
|
|
4767
|
-
};
|
|
4768
|
-
}
|
|
4769
|
-
|
|
4770
|
-
// src/features/operations/organization-graph/lenses.ts
|
|
4771
|
-
var COMMAND_VIEW_NODE_KINDS = [
|
|
4772
|
-
"organization",
|
|
4773
|
-
"feature",
|
|
4774
|
-
"surface",
|
|
4775
|
-
"entity",
|
|
4776
|
-
"capability",
|
|
4777
|
-
"resource"
|
|
4778
|
-
];
|
|
4779
|
-
function getOrganizationGraphLensConfig(lens) {
|
|
4780
|
-
if (lens === "command-view") {
|
|
4781
|
-
return {
|
|
4782
|
-
title: "Command View",
|
|
4783
|
-
caption: "Operations lens backed by the shared organization graph. This preset focuses the graph on bridged runtime resources and their operational relationships.",
|
|
4784
|
-
initialMode: "map",
|
|
4785
|
-
initialFilters: {
|
|
4786
|
-
nodeKinds: COMMAND_VIEW_NODE_KINDS,
|
|
4787
|
-
topologyPresence: "all"
|
|
4788
|
-
},
|
|
4789
|
-
filterSummary: "Command View lens keeps the organization structure visible while resource visibility is controlled progressively."
|
|
4790
|
-
};
|
|
4791
|
-
}
|
|
4792
|
-
return {
|
|
4793
|
-
title: "Organization Graph",
|
|
4794
|
-
caption: "Cytoscape-based shared graph surface built from the organization model and bridged Command View topology.",
|
|
4795
|
-
initialMode: "map",
|
|
4796
|
-
filterSummary: "Filter by node kind, semantic-vs-topology presence, and free-text search across nodes and relationships."
|
|
4797
|
-
};
|
|
4798
|
-
}
|
|
4799
|
-
|
|
4800
|
-
// src/features/operations/organization-graph/commandViewOperationalSummary.ts
|
|
4801
|
-
function toPercentage(numerator, denominator) {
|
|
4802
|
-
if (denominator <= 0) return null;
|
|
4803
|
-
return numerator / denominator * 100;
|
|
4804
|
-
}
|
|
4805
|
-
function formatPercent(value) {
|
|
4806
|
-
return value == null ? "N/A" : `${Math.round(value)}%`;
|
|
4807
|
-
}
|
|
4808
|
-
function formatTimestamp(value) {
|
|
4809
|
-
if (!value) return "N/A";
|
|
4810
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
4811
|
-
month: "short",
|
|
4812
|
-
day: "numeric",
|
|
4813
|
-
hour: "numeric",
|
|
4814
|
-
minute: "2-digit"
|
|
4815
|
-
}).format(new Date(value));
|
|
4816
|
-
}
|
|
4817
|
-
function getCommandViewNodes2(data) {
|
|
4818
|
-
return [
|
|
4819
|
-
...data.agents,
|
|
4820
|
-
...data.workflows,
|
|
4821
|
-
...data.triggers,
|
|
4822
|
-
...data.integrations,
|
|
4823
|
-
...data.externalResources,
|
|
4824
|
-
...data.humanCheckpoints
|
|
4825
|
-
];
|
|
4826
|
-
}
|
|
4827
|
-
function getNodeByResourceId(data, resourceId) {
|
|
4828
|
-
return getCommandViewNodes2(data).find((node) => node.resourceId === resourceId) ?? null;
|
|
4829
|
-
}
|
|
4830
|
-
function getCommandViewOperationalOverview(data, stats) {
|
|
4831
|
-
if (!stats) {
|
|
4832
|
-
return null;
|
|
4833
|
-
}
|
|
4834
|
-
const resourceEntries = Object.entries(stats.resources);
|
|
4835
|
-
const humanEntries = Object.entries(stats.humanCheckpoints);
|
|
4836
|
-
const totalRuns = resourceEntries.reduce((sum, [, item]) => sum + item.totalRuns, 0);
|
|
4837
|
-
const successCount = resourceEntries.reduce((sum, [, item]) => sum + item.successCount, 0);
|
|
4838
|
-
const failureCount = resourceEntries.reduce((sum, [, item]) => sum + item.failureCount, 0);
|
|
4839
|
-
const warningCount = resourceEntries.reduce((sum, [, item]) => sum + item.warningCount, 0);
|
|
4840
|
-
const pendingApprovals = humanEntries.reduce((sum, [, item]) => sum + item.pendingCount, 0);
|
|
4841
|
-
const activeHumanCheckpoints = humanEntries.filter(([, item]) => item.pendingCount > 0).length;
|
|
4842
|
-
const topFailingResources = resourceEntries.map(([resourceId, item]) => ({
|
|
4843
|
-
id: resourceId,
|
|
4844
|
-
label: data ? getNodeByResourceId(data, resourceId)?.name ?? resourceId : resourceId,
|
|
4845
|
-
failureCount: item.failureCount,
|
|
4846
|
-
warningCount: item.warningCount
|
|
4847
|
-
})).filter((item) => item.failureCount > 0 || item.warningCount > 0).sort((left, right) => {
|
|
4848
|
-
if (right.failureCount !== left.failureCount) {
|
|
4849
|
-
return right.failureCount - left.failureCount;
|
|
4850
|
-
}
|
|
4851
|
-
if (right.warningCount !== left.warningCount) {
|
|
4852
|
-
return right.warningCount - left.warningCount;
|
|
4853
|
-
}
|
|
4854
|
-
return left.label.localeCompare(right.label);
|
|
4855
|
-
}).slice(0, 3);
|
|
4856
|
-
return {
|
|
4857
|
-
totalRuns,
|
|
4858
|
-
successCount,
|
|
4859
|
-
failureCount,
|
|
4860
|
-
warningCount,
|
|
4861
|
-
successRate: toPercentage(successCount, totalRuns),
|
|
4862
|
-
trackedResources: resourceEntries.length,
|
|
4863
|
-
pendingApprovals,
|
|
4864
|
-
activeHumanCheckpoints,
|
|
4865
|
-
topFailingResources,
|
|
4866
|
-
timeRange: stats.timeRange,
|
|
4867
|
-
generatedAt: stats.generatedAt
|
|
4868
|
-
};
|
|
4869
|
-
}
|
|
4870
|
-
function buildResourceSelectionSummary(node, stats) {
|
|
4871
|
-
const successRate = toPercentage(stats.successCount, stats.totalRuns);
|
|
4872
|
-
const metadata = [
|
|
4873
|
-
{ label: "Operational Type", value: node.type },
|
|
4874
|
-
{ label: "Environment", value: node.status.toUpperCase() },
|
|
4875
|
-
{ label: "Version", value: node.version },
|
|
4876
|
-
{ label: "Origin", value: node.origin ? node.origin : "local" }
|
|
4877
|
-
];
|
|
4878
|
-
if (node.category) {
|
|
4879
|
-
metadata.push({ label: "Category", value: node.category });
|
|
4880
|
-
}
|
|
4881
|
-
if (node.links?.length) {
|
|
4882
|
-
metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
|
|
4883
|
-
}
|
|
4884
|
-
if (node.type === "agent") {
|
|
4885
|
-
metadata.push({ label: "Model", value: `${node.modelProvider}/${node.modelId}` });
|
|
4886
|
-
metadata.push({ label: "Tools", value: String(node.toolCount) });
|
|
4887
|
-
metadata.push({ label: "Memory", value: node.hasMemory ? "Enabled" : "Disabled" });
|
|
4888
|
-
}
|
|
4889
|
-
if (node.type === "workflow") {
|
|
4890
|
-
metadata.push({ label: "Entry Point", value: node.entryPoint });
|
|
4891
|
-
metadata.push({ label: "Steps", value: String(node.stepCount) });
|
|
4892
|
-
}
|
|
4893
|
-
if (node.type === "integration") {
|
|
4894
|
-
metadata.push({ label: "Provider", value: node.provider });
|
|
4895
|
-
metadata.push({ label: "Credential", value: node.credentialName });
|
|
4896
|
-
}
|
|
4897
|
-
if (node.type === "trigger") {
|
|
4898
|
-
metadata.push({ label: "Trigger Type", value: node.triggerType });
|
|
4899
|
-
}
|
|
4900
|
-
if (node.type === "external") {
|
|
4901
|
-
metadata.push({ label: "Platform", value: node.platform });
|
|
4902
|
-
}
|
|
4903
|
-
return {
|
|
4904
|
-
title: "Operational Summary",
|
|
4905
|
-
description: "Execution telemetry for this resource inside the Command View lens.",
|
|
4906
|
-
metrics: [
|
|
4907
|
-
{ label: "Runs", value: String(stats.totalRuns), hint: "Total tracked executions in the selected time range" },
|
|
4908
|
-
{ label: "Success rate", value: formatPercent(successRate), hint: "Completed and warning runs as a percentage of all runs" },
|
|
4909
|
-
{ label: "Failures", value: String(stats.failureCount), hint: "Runs that ended in a failed state" },
|
|
4910
|
-
{ label: "Warnings", value: String(stats.warningCount), hint: "Completed runs that surfaced warnings" }
|
|
4911
|
-
],
|
|
4912
|
-
metadata: [...metadata, { label: "Last Run", value: formatTimestamp(stats.lastRunAt) }]
|
|
4913
|
-
};
|
|
4914
|
-
}
|
|
4915
|
-
function buildHumanSelectionSummary(node, stats) {
|
|
4916
|
-
const metadata = [
|
|
4917
|
-
{ label: "Operational Type", value: "human checkpoint" },
|
|
4918
|
-
{ label: "Environment", value: node.status.toUpperCase() },
|
|
4919
|
-
{ label: "Version", value: node.version },
|
|
4920
|
-
{ label: "Origin", value: node.origin ? node.origin : "local" }
|
|
4921
|
-
];
|
|
4922
|
-
if (node.category) {
|
|
4923
|
-
metadata.push({ label: "Category", value: node.category });
|
|
4924
|
-
}
|
|
4925
|
-
if (node.links?.length) {
|
|
4926
|
-
metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
|
|
4927
|
-
}
|
|
4928
|
-
return {
|
|
4929
|
-
title: "Approval Queue Summary",
|
|
4930
|
-
description: "Human checkpoint activity for the current Command View lens.",
|
|
4931
|
-
metrics: [
|
|
4932
|
-
{ label: "Pending", value: String(stats.pendingCount), hint: "Tasks currently waiting on a decision" },
|
|
4933
|
-
{ label: "Completed", value: String(stats.completedCount), hint: "Tasks completed in the selected time range" },
|
|
4934
|
-
{ label: "Expired", value: String(stats.expiredCount), hint: "Tasks that expired before resolution" }
|
|
4935
|
-
],
|
|
4936
|
-
metadata: [...metadata, { label: "Last Decision", value: formatTimestamp(stats.lastDecisionAt) }]
|
|
4937
|
-
};
|
|
4938
|
-
}
|
|
4939
|
-
function getCommandViewSelectionOperationalSummary(data, stats, selectedElement) {
|
|
4940
|
-
if (!data || !stats || !selectedElement || selectedElement.type !== "node") {
|
|
4941
|
-
return null;
|
|
4942
|
-
}
|
|
4943
|
-
if (!selectedElement.id.startsWith("resource:")) {
|
|
4944
|
-
return null;
|
|
4945
|
-
}
|
|
4946
|
-
const resourceId = selectedElement.id.slice("resource:".length);
|
|
4947
|
-
const node = getNodeByResourceId(data, resourceId);
|
|
4948
|
-
if (!node) {
|
|
4949
|
-
return null;
|
|
4950
|
-
}
|
|
4951
|
-
if (node.type === "human") {
|
|
4952
|
-
const checkpointStats = stats.humanCheckpoints[resourceId];
|
|
4953
|
-
return checkpointStats ? buildHumanSelectionSummary(node, checkpointStats) : null;
|
|
4954
|
-
}
|
|
4955
|
-
const resourceStats = stats.resources[resourceId];
|
|
4956
|
-
return resourceStats ? buildResourceSelectionSummary(node, resourceStats) : null;
|
|
4957
|
-
}
|
|
4958
|
-
function formatRelativeTime3(date) {
|
|
4959
|
-
if (!date) return "N/A";
|
|
4960
|
-
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
4961
|
-
return formatDistanceToNow(dateObj, { addSuffix: true });
|
|
4962
|
-
}
|
|
4963
|
-
|
|
4964
|
-
// src/hooks/operations/command-view/utils/mergeStatsWithTopology.ts
|
|
4965
|
-
function mergeStatsWithTopology(topology, stats) {
|
|
4966
|
-
return {
|
|
4967
|
-
...topology,
|
|
4968
|
-
agents: topology.agents.map((agent) => ({
|
|
4969
|
-
...agent,
|
|
4970
|
-
stats: stats.resources[agent.resourceId] || null
|
|
4971
|
-
})),
|
|
4972
|
-
workflows: topology.workflows.map((workflow) => ({
|
|
4973
|
-
...workflow,
|
|
4974
|
-
stats: stats.resources[workflow.resourceId] || null
|
|
4975
|
-
})),
|
|
4976
|
-
humanCheckpoints: topology.humanCheckpoints.map((checkpoint) => ({
|
|
4977
|
-
...checkpoint,
|
|
4978
|
-
stats: stats.humanCheckpoints[checkpoint.resourceId] || null
|
|
4979
|
-
}))
|
|
4980
|
-
};
|
|
4981
|
-
}
|
|
4982
|
-
|
|
4983
|
-
// src/features/operations/organization-graph/commandViewDrillDown.ts
|
|
4984
|
-
function titleCase4(value) {
|
|
4985
|
-
return value.replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
4986
|
-
}
|
|
4987
|
-
function getResourceHref(resourceType, resourceId) {
|
|
4988
|
-
if (resourceType === "agent") {
|
|
4989
|
-
return `/operations/resources/agent/${resourceId}`;
|
|
4990
|
-
}
|
|
4991
|
-
if (resourceType === "workflow") {
|
|
4992
|
-
return `/operations/resources/workflow/${resourceId}`;
|
|
4993
|
-
}
|
|
4994
|
-
if (resourceType === "human_checkpoint") {
|
|
4995
|
-
return `/operations/command-queue?checkpoint=${resourceId}`;
|
|
4996
|
-
}
|
|
4997
|
-
return null;
|
|
4998
|
-
}
|
|
4999
|
-
function getExecutionBadgeColor(status) {
|
|
5000
|
-
switch (status) {
|
|
5001
|
-
case "failed":
|
|
5002
|
-
return "red";
|
|
5003
|
-
case "warning":
|
|
5004
|
-
return "yellow";
|
|
5005
|
-
case "running":
|
|
5006
|
-
return "blue";
|
|
5007
|
-
case "completed":
|
|
5008
|
-
return "green";
|
|
5009
|
-
case "pending":
|
|
5010
|
-
default:
|
|
5011
|
-
return "gray";
|
|
5012
|
-
}
|
|
5013
|
-
}
|
|
5014
|
-
function getTaskBadgeColor(status) {
|
|
5015
|
-
switch (status) {
|
|
5016
|
-
case "pending":
|
|
5017
|
-
return "orange";
|
|
5018
|
-
case "processing":
|
|
5019
|
-
return "blue";
|
|
5020
|
-
case "completed":
|
|
5021
|
-
return "green";
|
|
5022
|
-
case "failed":
|
|
5023
|
-
return "red";
|
|
5024
|
-
case "expired":
|
|
5025
|
-
default:
|
|
5026
|
-
return "gray";
|
|
5027
|
-
}
|
|
5028
|
-
}
|
|
5029
|
-
function getExecutionDescription(execution) {
|
|
5030
|
-
if (execution.errorMessage) {
|
|
5031
|
-
return execution.errorMessage;
|
|
5032
|
-
}
|
|
5033
|
-
if (execution.status === "running") {
|
|
5034
|
-
return "Currently running";
|
|
5035
|
-
}
|
|
5036
|
-
if (execution.status === "warning") {
|
|
5037
|
-
return "Completed with warnings";
|
|
5038
|
-
}
|
|
5039
|
-
if (execution.status === "completed") {
|
|
5040
|
-
return "Completed successfully";
|
|
5041
|
-
}
|
|
5042
|
-
return titleCase4(execution.status);
|
|
5043
|
-
}
|
|
5044
|
-
function getTaskDescription(task) {
|
|
5045
|
-
if (task.description) {
|
|
5046
|
-
return task.description;
|
|
5047
|
-
}
|
|
5048
|
-
if (task.humanCheckpoint) {
|
|
5049
|
-
return `Checkpoint: ${task.humanCheckpoint}`;
|
|
5050
|
-
}
|
|
5051
|
-
return "Pending approval task";
|
|
5052
|
-
}
|
|
5053
|
-
function buildCommandViewDrillDownSections({
|
|
5054
|
-
node,
|
|
5055
|
-
timeRange,
|
|
5056
|
-
executions,
|
|
5057
|
-
checkpointTasks
|
|
5058
|
-
}) {
|
|
5059
|
-
if (!node || node.kind !== "resource" || !node.sourceId || !node.resourceType) {
|
|
5060
|
-
return [];
|
|
5061
|
-
}
|
|
5062
|
-
const sections = [];
|
|
5063
|
-
const resourceHref = getResourceHref(node.resourceType, node.sourceId);
|
|
5064
|
-
if ((node.resourceType === "agent" || node.resourceType === "workflow") && executions) {
|
|
5065
|
-
sections.push({
|
|
5066
|
-
title: "Recent executions",
|
|
5067
|
-
description: `Latest runs for this ${titleCase4(node.resourceType)} in the ${timeRange} window.`,
|
|
5068
|
-
emptyMessage: `No executions were recorded for this ${titleCase4(node.resourceType).toLowerCase()} in the current window.`,
|
|
5069
|
-
primaryAction: resourceHref ? {
|
|
5070
|
-
label: "Open resource",
|
|
5071
|
-
href: resourceHref
|
|
5072
|
-
} : void 0,
|
|
5073
|
-
items: executions.map((execution) => ({
|
|
5074
|
-
id: execution.executionId,
|
|
5075
|
-
label: execution.executionId,
|
|
5076
|
-
href: `${resourceHref ?? "#"}?exec=${execution.executionId}`,
|
|
5077
|
-
description: getExecutionDescription(execution),
|
|
5078
|
-
badgeLabel: execution.status,
|
|
5079
|
-
badgeColor: getExecutionBadgeColor(execution.status),
|
|
5080
|
-
meta: `Started ${formatRelativeTime3(execution.startedAt)}`
|
|
5081
|
-
}))
|
|
5082
|
-
});
|
|
5083
|
-
}
|
|
5084
|
-
if (node.resourceType === "human_checkpoint" && checkpointTasks) {
|
|
5085
|
-
sections.push({
|
|
5086
|
-
title: "Pending tasks",
|
|
5087
|
-
description: "Human approval tasks waiting on this checkpoint.",
|
|
5088
|
-
emptyMessage: "No pending tasks are currently assigned to this checkpoint.",
|
|
5089
|
-
primaryAction: resourceHref ? {
|
|
5090
|
-
label: "Open queue",
|
|
5091
|
-
href: resourceHref
|
|
5092
|
-
} : void 0,
|
|
5093
|
-
items: checkpointTasks.map((task) => ({
|
|
5094
|
-
id: task.id,
|
|
5095
|
-
label: task.description ?? task.id,
|
|
5096
|
-
href: `/operations/command-queue?task=${task.id}`,
|
|
5097
|
-
description: getTaskDescription(task),
|
|
5098
|
-
badgeLabel: task.status,
|
|
5099
|
-
badgeColor: getTaskBadgeColor(task.status),
|
|
5100
|
-
meta: `Created ${formatRelativeTime3(task.createdAt)}`
|
|
5101
|
-
}))
|
|
5102
|
-
});
|
|
5103
|
-
}
|
|
5104
|
-
return sections;
|
|
5105
|
-
}
|
|
5106
|
-
|
|
5107
|
-
// src/features/operations/organization-graph/path-tracing/trace.ts
|
|
5108
|
-
var NODE_KIND_ORDER = {
|
|
5109
|
-
organization: 0,
|
|
5110
|
-
feature: 1,
|
|
5111
|
-
surface: 2,
|
|
5112
|
-
capability: 3,
|
|
5113
|
-
entity: 4,
|
|
5114
|
-
resource: 5,
|
|
5115
|
-
knowledge: 6
|
|
5116
|
-
};
|
|
5117
|
-
var NODE_KIND_LABEL = {
|
|
5118
|
-
organization: "Organization",
|
|
5119
|
-
feature: "Feature",
|
|
5120
|
-
surface: "Surface",
|
|
5121
|
-
capability: "Capability",
|
|
5122
|
-
entity: "Entity",
|
|
5123
|
-
resource: "Resource",
|
|
5124
|
-
knowledge: "Knowledge"
|
|
5125
|
-
};
|
|
5126
|
-
function getNodeLabel(node) {
|
|
5127
|
-
return node.label || node.sourceId || node.id;
|
|
5128
|
-
}
|
|
5129
|
-
function compareTraceNodes(a, b) {
|
|
5130
|
-
const kindDelta = NODE_KIND_ORDER[a.kind] - NODE_KIND_ORDER[b.kind];
|
|
5131
|
-
if (kindDelta !== 0) {
|
|
5132
|
-
return kindDelta;
|
|
5133
|
-
}
|
|
5134
|
-
const labelDelta = getNodeLabel(a).localeCompare(getNodeLabel(b));
|
|
5135
|
-
if (labelDelta !== 0) {
|
|
5136
|
-
return labelDelta;
|
|
5137
|
-
}
|
|
5138
|
-
return a.id.localeCompare(b.id);
|
|
5139
|
-
}
|
|
5140
|
-
function buildMissingNodeMessage(selection, missingNodeIds) {
|
|
5141
|
-
if (missingNodeIds.length === 0) {
|
|
5142
|
-
return "The selected trace is not available.";
|
|
5143
|
-
}
|
|
5144
|
-
if (missingNodeIds.length === 1) {
|
|
5145
|
-
const missingId = missingNodeIds[0];
|
|
5146
|
-
return `Graph node "${missingId}" is not available.`;
|
|
5147
|
-
}
|
|
5148
|
-
return `Graph nodes "${selection.sourceId}" and "${selection.targetId}" are not available.`;
|
|
5149
|
-
}
|
|
5150
|
-
function buildPathNotFoundMessage(source, target) {
|
|
5151
|
-
return `No directed path found from "${source.label}" to "${target.label}".`;
|
|
5152
|
-
}
|
|
5153
|
-
function buildOrganizationGraphTraceIndex(graph) {
|
|
5154
|
-
const nodesById = /* @__PURE__ */ new Map();
|
|
5155
|
-
const edgesById = /* @__PURE__ */ new Map();
|
|
5156
|
-
const outgoingEdgesByNodeId = /* @__PURE__ */ new Map();
|
|
5157
|
-
const incomingEdgesByNodeId = /* @__PURE__ */ new Map();
|
|
5158
|
-
for (const node of graph.nodes) {
|
|
5159
|
-
nodesById.set(node.id, node);
|
|
5160
|
-
outgoingEdgesByNodeId.set(node.id, []);
|
|
5161
|
-
incomingEdgesByNodeId.set(node.id, []);
|
|
5162
|
-
}
|
|
5163
|
-
for (const edge of graph.edges) {
|
|
5164
|
-
edgesById.set(edge.id, edge);
|
|
5165
|
-
const outgoingEdges = outgoingEdgesByNodeId.get(edge.sourceId);
|
|
5166
|
-
if (outgoingEdges) {
|
|
5167
|
-
outgoingEdges.push(edge);
|
|
5168
|
-
}
|
|
5169
|
-
const incomingEdges = incomingEdgesByNodeId.get(edge.targetId);
|
|
5170
|
-
if (incomingEdges) {
|
|
5171
|
-
incomingEdges.push(edge);
|
|
5172
|
-
}
|
|
5173
|
-
}
|
|
5174
|
-
return {
|
|
5175
|
-
nodesById,
|
|
5176
|
-
edgesById,
|
|
5177
|
-
outgoingEdgesByNodeId,
|
|
5178
|
-
incomingEdgesByNodeId
|
|
5179
|
-
};
|
|
5180
|
-
}
|
|
5181
|
-
function getOrganizationGraphTraceNodeKindLabel(kind) {
|
|
5182
|
-
return NODE_KIND_LABEL[kind];
|
|
5183
|
-
}
|
|
5184
|
-
function formatOrganizationGraphTraceNodeOptionLabel(option) {
|
|
5185
|
-
return `${option.label} \xB7 ${getOrganizationGraphTraceNodeKindLabel(option.kind)}`;
|
|
5186
|
-
}
|
|
5187
|
-
function getOrganizationGraphTraceNodeOptions(graph) {
|
|
5188
|
-
return [...graph.nodes].sort(compareTraceNodes).map((node) => ({
|
|
5189
|
-
id: node.id,
|
|
5190
|
-
label: getNodeLabel(node),
|
|
5191
|
-
kind: node.kind,
|
|
5192
|
-
sourceId: node.sourceId,
|
|
5193
|
-
description: node.description,
|
|
5194
|
-
enabled: node.enabled
|
|
5195
|
-
}));
|
|
5196
|
-
}
|
|
5197
|
-
function resolveOrganizationGraphPathTrace(graph, selection) {
|
|
5198
|
-
const index = buildOrganizationGraphTraceIndex(graph);
|
|
5199
|
-
const source = selection.sourceId ? index.nodesById.get(selection.sourceId) ?? null : null;
|
|
5200
|
-
const target = selection.targetId ? index.nodesById.get(selection.targetId) ?? null : null;
|
|
5201
|
-
const missingNodeIds = [
|
|
5202
|
-
selection.sourceId && !source ? selection.sourceId : null,
|
|
5203
|
-
selection.targetId && !target ? selection.targetId : null
|
|
5204
|
-
].filter((value) => Boolean(value));
|
|
5205
|
-
if (!selection.sourceId && !selection.targetId) {
|
|
5206
|
-
return {
|
|
5207
|
-
status: "idle",
|
|
5208
|
-
selection,
|
|
5209
|
-
source,
|
|
5210
|
-
target,
|
|
5211
|
-
missingNodeIds: [],
|
|
5212
|
-
pathNodes: [],
|
|
5213
|
-
pathEdges: [],
|
|
5214
|
-
highlightNodeIds: [],
|
|
5215
|
-
highlightEdgeIds: [],
|
|
5216
|
-
distance: 0,
|
|
5217
|
-
message: "Select a source and target to trace a path."
|
|
5218
|
-
};
|
|
5219
|
-
}
|
|
5220
|
-
if (!selection.sourceId || !selection.targetId) {
|
|
5221
|
-
return {
|
|
5222
|
-
status: "incomplete",
|
|
5223
|
-
selection,
|
|
5224
|
-
source,
|
|
5225
|
-
target,
|
|
5226
|
-
missingNodeIds,
|
|
5227
|
-
pathNodes: [],
|
|
5228
|
-
pathEdges: [],
|
|
5229
|
-
highlightNodeIds: [],
|
|
5230
|
-
highlightEdgeIds: [],
|
|
5231
|
-
distance: 0,
|
|
5232
|
-
message: "Select both a source and a target to resolve a path."
|
|
5233
|
-
};
|
|
5234
|
-
}
|
|
5235
|
-
if (missingNodeIds.length > 0 || !source || !target) {
|
|
5236
|
-
return {
|
|
5237
|
-
status: "missing-node",
|
|
5238
|
-
selection,
|
|
5239
|
-
source,
|
|
5240
|
-
target,
|
|
5241
|
-
missingNodeIds,
|
|
5242
|
-
pathNodes: [],
|
|
5243
|
-
pathEdges: [],
|
|
5244
|
-
highlightNodeIds: [],
|
|
5245
|
-
highlightEdgeIds: [],
|
|
5246
|
-
distance: 0,
|
|
5247
|
-
message: buildMissingNodeMessage(selection, missingNodeIds)
|
|
5248
|
-
};
|
|
5249
|
-
}
|
|
5250
|
-
if (source.id === target.id) {
|
|
5251
|
-
return {
|
|
5252
|
-
status: "found",
|
|
5253
|
-
selection,
|
|
5254
|
-
source,
|
|
5255
|
-
target,
|
|
5256
|
-
missingNodeIds: [],
|
|
5257
|
-
pathNodes: [source],
|
|
5258
|
-
pathEdges: [],
|
|
5259
|
-
highlightNodeIds: [source.id],
|
|
5260
|
-
highlightEdgeIds: [],
|
|
5261
|
-
distance: 0,
|
|
5262
|
-
message: `Source and target already point to "${source.label}".`
|
|
5263
|
-
};
|
|
5264
|
-
}
|
|
5265
|
-
const visitedNodeIds = /* @__PURE__ */ new Set([source.id]);
|
|
5266
|
-
const predecessorByNodeId = /* @__PURE__ */ new Map();
|
|
5267
|
-
const queue = [source.id];
|
|
5268
|
-
while (queue.length > 0) {
|
|
5269
|
-
const currentNodeId = queue.shift();
|
|
5270
|
-
if (!currentNodeId) {
|
|
5271
|
-
continue;
|
|
5272
|
-
}
|
|
5273
|
-
const outgoingEdges = index.outgoingEdgesByNodeId.get(currentNodeId) ?? [];
|
|
5274
|
-
for (const edge of outgoingEdges) {
|
|
5275
|
-
if (visitedNodeIds.has(edge.targetId)) {
|
|
5276
|
-
continue;
|
|
5277
|
-
}
|
|
5278
|
-
visitedNodeIds.add(edge.targetId);
|
|
5279
|
-
predecessorByNodeId.set(edge.targetId, {
|
|
5280
|
-
nodeId: currentNodeId,
|
|
5281
|
-
edgeId: edge.id
|
|
5282
|
-
});
|
|
5283
|
-
if (edge.targetId === target.id) {
|
|
5284
|
-
queue.length = 0;
|
|
5285
|
-
break;
|
|
5286
|
-
}
|
|
5287
|
-
queue.push(edge.targetId);
|
|
5288
|
-
}
|
|
5289
|
-
}
|
|
5290
|
-
if (!predecessorByNodeId.has(target.id)) {
|
|
5291
|
-
return {
|
|
5292
|
-
status: "not-found",
|
|
5293
|
-
selection,
|
|
5294
|
-
source,
|
|
5295
|
-
target,
|
|
5296
|
-
missingNodeIds: [],
|
|
5297
|
-
pathNodes: [],
|
|
5298
|
-
pathEdges: [],
|
|
5299
|
-
highlightNodeIds: [],
|
|
5300
|
-
highlightEdgeIds: [],
|
|
5301
|
-
distance: 0,
|
|
5302
|
-
message: buildPathNotFoundMessage(source, target)
|
|
5303
|
-
};
|
|
5304
|
-
}
|
|
5305
|
-
const pathNodes = [target];
|
|
5306
|
-
const pathEdges = [];
|
|
5307
|
-
let cursorNodeId = target.id;
|
|
5308
|
-
while (cursorNodeId !== source.id) {
|
|
5309
|
-
const predecessor = predecessorByNodeId.get(cursorNodeId);
|
|
5310
|
-
if (!predecessor) {
|
|
5311
|
-
break;
|
|
5312
|
-
}
|
|
5313
|
-
const edge = index.edgesById.get(predecessor.edgeId);
|
|
5314
|
-
const previousNode = index.nodesById.get(predecessor.nodeId);
|
|
5315
|
-
if (edge) {
|
|
5316
|
-
pathEdges.push(edge);
|
|
5317
|
-
}
|
|
5318
|
-
if (previousNode) {
|
|
5319
|
-
pathNodes.push(previousNode);
|
|
5320
|
-
}
|
|
5321
|
-
cursorNodeId = predecessor.nodeId;
|
|
5322
|
-
}
|
|
5323
|
-
pathNodes.reverse();
|
|
5324
|
-
pathEdges.reverse();
|
|
5325
|
-
return {
|
|
5326
|
-
status: "found",
|
|
5327
|
-
selection,
|
|
5328
|
-
source,
|
|
5329
|
-
target,
|
|
5330
|
-
missingNodeIds: [],
|
|
5331
|
-
pathNodes,
|
|
5332
|
-
pathEdges,
|
|
5333
|
-
highlightNodeIds: pathNodes.map((node) => node.id),
|
|
5334
|
-
highlightEdgeIds: pathEdges.map((edge) => edge.id),
|
|
5335
|
-
distance: pathEdges.length,
|
|
5336
|
-
message: `Path found from "${source.label}" to "${target.label}" across ${pathEdges.length} edge${pathEdges.length === 1 ? "" : "s"}.`
|
|
5337
|
-
};
|
|
5338
|
-
}
|
|
5339
|
-
|
|
5340
|
-
// src/features/operations/organization-graph/expand-around/expandAroundGraph.ts
|
|
5341
|
-
var DEFAULT_MAX_DEPTH = 1;
|
|
5342
|
-
var DEFAULT_MAX_RESULTS = 25;
|
|
5343
|
-
var ORG_MODEL_ROOT_KINDS = /* @__PURE__ */ new Set([
|
|
5344
|
-
"feature",
|
|
5345
|
-
"surface",
|
|
5346
|
-
"entity",
|
|
5347
|
-
"capability"
|
|
5348
|
-
]);
|
|
5349
|
-
var PRESET_EDGE_KINDS = {
|
|
5350
|
-
coverage: ["contains", "exposes", "operates-on", "maps_to", "references"],
|
|
5351
|
-
"operational-dependencies": ["references"],
|
|
5352
|
-
"org-context": ["contains", "exposes", "operates-on", "maps_to"],
|
|
5353
|
-
"impact-path": ["references"]
|
|
5354
|
-
};
|
|
5355
|
-
var PRESET_RELATIONSHIP_TYPES = {
|
|
5356
|
-
"operational-dependencies": ["triggers", "uses", "approval"],
|
|
5357
|
-
"impact-path": ["triggers", "uses", "approval"]
|
|
5358
|
-
};
|
|
5359
|
-
var PRESET_DIRECTIONS = {
|
|
5360
|
-
coverage: "both",
|
|
5361
|
-
"operational-dependencies": "both",
|
|
5362
|
-
"org-context": "both",
|
|
5363
|
-
"impact-path": "both"
|
|
5364
|
-
};
|
|
5365
|
-
function toSet(values) {
|
|
5366
|
-
if (!values || values.length === 0) {
|
|
5367
|
-
return null;
|
|
5368
|
-
}
|
|
5369
|
-
return new Set(values);
|
|
5370
|
-
}
|
|
5371
|
-
function clampMaxDepth(maxDepth) {
|
|
5372
|
-
if (maxDepth === 2 || maxDepth === 3) {
|
|
5373
|
-
return maxDepth;
|
|
5374
|
-
}
|
|
5375
|
-
return 1;
|
|
5376
|
-
}
|
|
5377
|
-
function resolvePreset(rootNode, preset) {
|
|
5378
|
-
if (preset) {
|
|
5379
|
-
return preset;
|
|
5380
|
-
}
|
|
5381
|
-
if (!rootNode) {
|
|
5382
|
-
return null;
|
|
5383
|
-
}
|
|
5384
|
-
if (ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
|
|
5385
|
-
return "coverage";
|
|
5386
|
-
}
|
|
5387
|
-
if (rootNode.kind === "resource") {
|
|
5388
|
-
return "operational-dependencies";
|
|
5389
|
-
}
|
|
5390
|
-
return null;
|
|
5391
|
-
}
|
|
5392
|
-
function resolveRequest(rootNode, request) {
|
|
5393
|
-
const preset = resolvePreset(rootNode, request.preset);
|
|
5394
|
-
const maxResults = request.maxResults === void 0 || !Number.isFinite(request.maxResults) ? DEFAULT_MAX_RESULTS : Math.max(0, request.maxResults);
|
|
5395
|
-
return {
|
|
5396
|
-
rootNodeId: request.rootNodeId,
|
|
5397
|
-
direction: request.direction ?? (preset ? PRESET_DIRECTIONS[preset] : "both"),
|
|
5398
|
-
maxDepth: clampMaxDepth(request.maxDepth ?? DEFAULT_MAX_DEPTH),
|
|
5399
|
-
maxResults,
|
|
5400
|
-
edgeKinds: toSet(request.edgeKinds ?? (preset ? PRESET_EDGE_KINDS[preset] : void 0)),
|
|
5401
|
-
relationshipTypes: toSet(
|
|
5402
|
-
request.relationshipTypes ?? (preset ? PRESET_RELATIONSHIP_TYPES[preset] : void 0)
|
|
5403
|
-
),
|
|
5404
|
-
preset,
|
|
5405
|
-
nodeKinds: toSet(request.nodeKinds),
|
|
5406
|
-
resourceTypes: toSet(request.resourceTypes),
|
|
5407
|
-
includeHiddenResources: request.includeHiddenResources ?? false
|
|
5408
|
-
};
|
|
5409
|
-
}
|
|
5410
|
-
function getOppositeNodeId(edge, currentNodeId) {
|
|
5411
|
-
if (edge.sourceId === currentNodeId) {
|
|
5412
|
-
return edge.targetId;
|
|
5413
|
-
}
|
|
5414
|
-
if (edge.targetId === currentNodeId) {
|
|
5415
|
-
return edge.sourceId;
|
|
5416
|
-
}
|
|
5417
|
-
return null;
|
|
5418
|
-
}
|
|
5419
|
-
function getCandidateEdges(index, nodeId, direction) {
|
|
5420
|
-
if (direction === "outgoing") {
|
|
5421
|
-
return index.outgoingEdgesByNodeId.get(nodeId) ?? [];
|
|
5422
|
-
}
|
|
5423
|
-
if (direction === "incoming") {
|
|
5424
|
-
return index.incomingEdgesByNodeId.get(nodeId) ?? [];
|
|
5425
|
-
}
|
|
5426
|
-
const seenEdgeIds = /* @__PURE__ */ new Set();
|
|
5427
|
-
const edges = [];
|
|
5428
|
-
for (const edge of [
|
|
5429
|
-
...index.outgoingEdgesByNodeId.get(nodeId) ?? [],
|
|
5430
|
-
...index.incomingEdgesByNodeId.get(nodeId) ?? []
|
|
5431
|
-
]) {
|
|
5432
|
-
if (seenEdgeIds.has(edge.id)) {
|
|
5433
|
-
continue;
|
|
5434
|
-
}
|
|
5435
|
-
seenEdgeIds.add(edge.id);
|
|
5436
|
-
edges.push(edge);
|
|
5437
|
-
}
|
|
5438
|
-
return edges;
|
|
5439
|
-
}
|
|
5440
|
-
function matchesPresetTraversalDirection(edge, currentNodeId, request) {
|
|
5441
|
-
if (request.preset === "coverage" && (edge.kind === "contains" || edge.kind === "exposes")) {
|
|
5442
|
-
return edge.sourceId === currentNodeId;
|
|
5443
|
-
}
|
|
5444
|
-
return true;
|
|
5445
|
-
}
|
|
5446
|
-
function matchesEdgeFilters(edge, currentNodeId, request) {
|
|
5447
|
-
if (request.edgeKinds && !request.edgeKinds.has(edge.kind)) {
|
|
5448
|
-
return false;
|
|
5449
|
-
}
|
|
5450
|
-
if (request.relationshipTypes && (!edge.relationshipType || !request.relationshipTypes.has(edge.relationshipType))) {
|
|
5451
|
-
return false;
|
|
5452
|
-
}
|
|
5453
|
-
return matchesPresetTraversalDirection(edge, currentNodeId, request);
|
|
5454
|
-
}
|
|
5455
|
-
function matchesNodeFilters(node, request) {
|
|
5456
|
-
if (request.nodeKinds && !request.nodeKinds.has(node.kind)) {
|
|
5457
|
-
return false;
|
|
5458
|
-
}
|
|
5459
|
-
if (request.resourceTypes) {
|
|
5460
|
-
if (node.kind !== "resource") {
|
|
5461
|
-
return false;
|
|
5462
|
-
}
|
|
5463
|
-
if (!node.resourceType || !request.resourceTypes.has(node.resourceType)) {
|
|
5464
|
-
return false;
|
|
5465
|
-
}
|
|
5466
|
-
}
|
|
5467
|
-
return true;
|
|
5468
|
-
}
|
|
5469
|
-
function pluralize(count, singular, plural = `${singular}s`) {
|
|
5470
|
-
return `${count} ${count === 1 ? singular : plural}`;
|
|
5471
|
-
}
|
|
5472
|
-
function getNodeDisplayName(node) {
|
|
5473
|
-
return node.label || node.sourceId || node.id;
|
|
5474
|
-
}
|
|
5475
|
-
function buildSummaryMessages(input) {
|
|
5476
|
-
const { rootNode, preset, expandedNodes, counts, truncated } = input;
|
|
5477
|
-
if (!rootNode) {
|
|
5478
|
-
return ["Select an available node to expand around."];
|
|
5479
|
-
}
|
|
5480
|
-
if (!preset && rootNode.kind === "organization") {
|
|
5481
|
-
return ["Choose a feature, surface, capability, entity, or resource before expanding."];
|
|
5482
|
-
}
|
|
5483
|
-
if (expandedNodes.length === 0) {
|
|
5484
|
-
return [`No matching graph context found around "${getNodeDisplayName(rootNode)}".`];
|
|
5485
|
-
}
|
|
5486
|
-
const resourceCount = expandedNodes.filter((node) => node.kind === "resource").length;
|
|
5487
|
-
const semanticContextCount = expandedNodes.length - resourceCount;
|
|
5488
|
-
const rootLabel = getNodeDisplayName(rootNode);
|
|
5489
|
-
const messages = [];
|
|
5490
|
-
if (preset === "coverage" && ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
|
|
5491
|
-
if (resourceCount > 0 && semanticContextCount > 0) {
|
|
5492
|
-
messages.push(
|
|
5493
|
-
`${pluralize(resourceCount, "resource")} and ${pluralize(
|
|
5494
|
-
semanticContextCount,
|
|
5495
|
-
"semantic context node"
|
|
5496
|
-
)} support "${rootLabel}".`
|
|
5497
|
-
);
|
|
5498
|
-
} else if (resourceCount > 0) {
|
|
5499
|
-
messages.push(`${pluralize(resourceCount, "resource")} support "${rootLabel}".`);
|
|
5500
|
-
} else {
|
|
5501
|
-
messages.push(
|
|
5502
|
-
`${pluralize(semanticContextCount, "semantic context node")} found around "${rootLabel}"; no mapped resources matched this coverage preset.`
|
|
5503
|
-
);
|
|
5504
|
-
}
|
|
5505
|
-
} else if (preset === "operational-dependencies") {
|
|
5506
|
-
messages.push(`${pluralize(resourceCount, "operational dependency resource")} found around "${rootLabel}".`);
|
|
5507
|
-
} else if (preset === "org-context") {
|
|
5508
|
-
messages.push(`${pluralize(expandedNodes.length, "semantic context node")} found around "${rootLabel}".`);
|
|
5509
|
-
} else if (preset === "impact-path") {
|
|
5510
|
-
messages.push(`${pluralize(resourceCount, "resource")} can call or be affected by "${rootLabel}".`);
|
|
5511
|
-
} else {
|
|
5512
|
-
messages.push(`${pluralize(expandedNodes.length, "node")} found around "${rootLabel}".`);
|
|
5513
|
-
}
|
|
5514
|
-
if (counts.hiddenResourceNodes > 0) {
|
|
5515
|
-
messages.push(`${pluralize(counts.hiddenResourceNodes, "hidden resource")} matched current visibility settings.`);
|
|
5516
|
-
}
|
|
5517
|
-
if (counts.alreadyVisibleNodes > 0) {
|
|
5518
|
-
messages.push(`${pluralize(counts.alreadyVisibleNodes, "node")} already visible in the graph.`);
|
|
5519
|
-
}
|
|
5520
|
-
if (truncated) {
|
|
5521
|
-
messages.push(`Results were limited to ${pluralize(expandedNodes.length, "node")}.`);
|
|
5522
|
-
}
|
|
5523
|
-
return messages;
|
|
5524
|
-
}
|
|
5525
|
-
function expandAroundGraph(graph, request, options = {}) {
|
|
5526
|
-
const index = buildOrganizationGraphTraceIndex(graph);
|
|
5527
|
-
const rootNode = index.nodesById.get(request.rootNodeId) ?? null;
|
|
5528
|
-
const resolved = resolveRequest(rootNode, request);
|
|
5529
|
-
const alreadyVisibleNodeIds = new Set(options.alreadyVisibleNodeIds ?? []);
|
|
5530
|
-
const hiddenResourceNodeIds = new Set(options.hiddenResourceNodeIds ?? []);
|
|
5531
|
-
const expandedNodeIds = /* @__PURE__ */ new Set();
|
|
5532
|
-
const expandedEdgeIds = /* @__PURE__ */ new Set();
|
|
5533
|
-
const frontierNodeIds = /* @__PURE__ */ new Set();
|
|
5534
|
-
const visitedDepthByNodeId = /* @__PURE__ */ new Map([[resolved.rootNodeId, 0]]);
|
|
5535
|
-
const hasExplicitTraversalFilter = Boolean(
|
|
5536
|
-
request.preset || request.edgeKinds?.length || request.relationshipTypes?.length || request.nodeKinds?.length || request.resourceTypes?.length
|
|
5537
|
-
);
|
|
5538
|
-
const queue = rootNode && (resolved.preset || hasExplicitTraversalFilter) ? [{ nodeId: rootNode.id, depth: 0 }] : [];
|
|
5539
|
-
let truncated = false;
|
|
5540
|
-
for (let queueIndex = 0; queueIndex < queue.length; queueIndex += 1) {
|
|
5541
|
-
const current = queue[queueIndex];
|
|
5542
|
-
if (current.depth >= resolved.maxDepth) {
|
|
5543
|
-
if (current.nodeId !== resolved.rootNodeId) {
|
|
5544
|
-
frontierNodeIds.add(current.nodeId);
|
|
5545
|
-
}
|
|
5546
|
-
continue;
|
|
5547
|
-
}
|
|
5548
|
-
for (const edge of getCandidateEdges(index, current.nodeId, resolved.direction)) {
|
|
5549
|
-
if (!matchesEdgeFilters(edge, current.nodeId, resolved)) {
|
|
5550
|
-
continue;
|
|
5551
|
-
}
|
|
5552
|
-
const nextNodeId = getOppositeNodeId(edge, current.nodeId);
|
|
5553
|
-
if (!nextNodeId) {
|
|
5554
|
-
continue;
|
|
5555
|
-
}
|
|
5556
|
-
const nextNode = index.nodesById.get(nextNodeId);
|
|
5557
|
-
if (!nextNode || !matchesNodeFilters(nextNode, resolved)) {
|
|
5558
|
-
continue;
|
|
5559
|
-
}
|
|
5560
|
-
if (!resolved.includeHiddenResources && hiddenResourceNodeIds.has(nextNode.id)) {
|
|
5561
|
-
continue;
|
|
5562
|
-
}
|
|
5563
|
-
const nextDepth = current.depth + 1;
|
|
5564
|
-
const previousDepth = visitedDepthByNodeId.get(nextNode.id);
|
|
5565
|
-
if (previousDepth !== void 0) {
|
|
5566
|
-
if (nextNode.id === resolved.rootNodeId || expandedNodeIds.has(nextNode.id)) {
|
|
5567
|
-
expandedEdgeIds.add(edge.id);
|
|
5568
|
-
}
|
|
5569
|
-
continue;
|
|
5570
|
-
}
|
|
5571
|
-
if (expandedNodeIds.size >= resolved.maxResults) {
|
|
5572
|
-
truncated = true;
|
|
5573
|
-
frontierNodeIds.add(nextNode.id);
|
|
5574
|
-
continue;
|
|
5575
|
-
}
|
|
5576
|
-
visitedDepthByNodeId.set(nextNode.id, nextDepth);
|
|
5577
|
-
expandedNodeIds.add(nextNode.id);
|
|
5578
|
-
expandedEdgeIds.add(edge.id);
|
|
5579
|
-
if (nextDepth >= resolved.maxDepth) {
|
|
5580
|
-
frontierNodeIds.add(nextNode.id);
|
|
5581
|
-
continue;
|
|
5582
|
-
}
|
|
5583
|
-
queue.push({ nodeId: nextNode.id, depth: nextDepth });
|
|
5584
|
-
}
|
|
5585
|
-
}
|
|
5586
|
-
const expandedNodes = [...expandedNodeIds].map((nodeId) => index.nodesById.get(nodeId)).filter((node) => Boolean(node));
|
|
5587
|
-
const hiddenResourceNodes = expandedNodes.filter((node) => hiddenResourceNodeIds.has(node.id)).length;
|
|
5588
|
-
const alreadyVisibleNodes = expandedNodes.filter((node) => alreadyVisibleNodeIds.has(node.id)).length;
|
|
5589
|
-
const newNodes = expandedNodes.filter(
|
|
5590
|
-
(node) => !hiddenResourceNodeIds.has(node.id) && !alreadyVisibleNodeIds.has(node.id)
|
|
5591
|
-
).length;
|
|
5592
|
-
const counts = {
|
|
5593
|
-
newNodes,
|
|
5594
|
-
newEdges: expandedEdgeIds.size,
|
|
5595
|
-
alreadyVisibleNodes,
|
|
5596
|
-
hiddenResourceNodes
|
|
5597
|
-
};
|
|
5598
|
-
const summaryMessages = buildSummaryMessages({
|
|
5599
|
-
rootNode,
|
|
5600
|
-
preset: resolved.preset,
|
|
5601
|
-
expandedNodes,
|
|
5602
|
-
counts,
|
|
5603
|
-
truncated
|
|
5604
|
-
});
|
|
5605
|
-
return {
|
|
5606
|
-
rootNodeId: request.rootNodeId,
|
|
5607
|
-
rootNode,
|
|
5608
|
-
preset: resolved.preset,
|
|
5609
|
-
direction: resolved.direction,
|
|
5610
|
-
maxDepth: resolved.maxDepth,
|
|
5611
|
-
maxResults: resolved.maxResults,
|
|
5612
|
-
expandedNodeIds: [...expandedNodeIds],
|
|
5613
|
-
expandedEdgeIds: [...expandedEdgeIds],
|
|
5614
|
-
frontierNodeIds: [...frontierNodeIds].filter((nodeId) => nodeId !== resolved.rootNodeId),
|
|
5615
|
-
truncated,
|
|
5616
|
-
counts,
|
|
5617
|
-
summaryMessages,
|
|
5618
|
-
message: summaryMessages[0] ?? ""
|
|
5619
|
-
};
|
|
5620
|
-
}
|
|
5621
|
-
var PRESET_OPTIONS = [
|
|
5622
|
-
{ value: "coverage", label: "Coverage" },
|
|
5623
|
-
{ value: "operational-dependencies", label: "Operational dependencies" },
|
|
5624
|
-
{ value: "org-context", label: "Org context" },
|
|
5625
|
-
{ value: "impact-path", label: "Impact path" }
|
|
5626
|
-
];
|
|
5627
|
-
var DIRECTION_OPTIONS = [
|
|
5628
|
-
{ value: "both", label: "Both" },
|
|
5629
|
-
{ value: "outgoing", label: "Outgoing" },
|
|
5630
|
-
{ value: "incoming", label: "Incoming" }
|
|
5631
|
-
];
|
|
5632
|
-
var EDGE_KIND_OPTIONS = [
|
|
5633
|
-
{ value: "contains", label: "Containment" },
|
|
5634
|
-
{ value: "references", label: "References" },
|
|
5635
|
-
{ value: "exposes", label: "Exposes" },
|
|
5636
|
-
{ value: "maps_to", label: "Maps to" },
|
|
5637
|
-
{ value: "operates-on", label: "Operates on" },
|
|
5638
|
-
{ value: "uses", label: "Uses" }
|
|
5639
|
-
];
|
|
5640
|
-
var RELATIONSHIP_OPTIONS = [
|
|
5641
|
-
{ value: "triggers", label: "Triggers" },
|
|
5642
|
-
{ value: "uses", label: "Uses" },
|
|
5643
|
-
{ value: "approval", label: "Approval" }
|
|
5644
|
-
];
|
|
5645
|
-
var RESOURCE_TYPE_OPTIONS = [
|
|
5646
|
-
{ value: "workflow", label: "Workflow" },
|
|
5647
|
-
{ value: "agent", label: "Agent" },
|
|
5648
|
-
{ value: "trigger", label: "Trigger" },
|
|
5649
|
-
{ value: "integration", label: "Integration" },
|
|
5650
|
-
{ value: "external", label: "External" },
|
|
5651
|
-
{ value: "human_checkpoint", label: "Human checkpoint" }
|
|
5652
|
-
];
|
|
5653
|
-
function updateValue(value, key, nextValue, onChange) {
|
|
5654
|
-
onChange({
|
|
5655
|
-
...value,
|
|
5656
|
-
[key]: nextValue
|
|
5657
|
-
});
|
|
5658
|
-
}
|
|
5659
|
-
function toOptionalArray(values) {
|
|
5660
|
-
return values.length > 0 ? values : void 0;
|
|
5661
|
-
}
|
|
5662
|
-
function toMaxDepth(value) {
|
|
5663
|
-
const numeric = typeof value === "number" ? value : Number.parseInt(value, 10);
|
|
5664
|
-
if (numeric === 3) return 3;
|
|
5665
|
-
if (numeric === 2) return 2;
|
|
5666
|
-
return 1;
|
|
5667
|
-
}
|
|
5668
|
-
function ExpandAroundPanel({
|
|
5669
|
-
selectedNode,
|
|
5670
|
-
value,
|
|
5671
|
-
result,
|
|
5672
|
-
appliedNodeCount,
|
|
5673
|
-
appliedEdgeCount,
|
|
5674
|
-
onChange,
|
|
5675
|
-
onPreview,
|
|
5676
|
-
onApply,
|
|
5677
|
-
onClear
|
|
5678
|
-
}) {
|
|
5679
|
-
const disabled = !selectedNode;
|
|
5680
|
-
const canApply = Boolean(result && result.expandedNodeIds.length > 0);
|
|
5681
|
-
const rootIsTooBroad = selectedNode?.kind === "organization" && !value.preset;
|
|
5682
|
-
return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5683
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "wrap", children: [
|
|
5684
|
-
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
5685
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 800, children: "Expand Around" }),
|
|
5686
|
-
/* @__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." })
|
|
5687
|
-
] }),
|
|
5688
|
-
appliedNodeCount > 0 || appliedEdgeCount > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
|
|
5689
|
-
appliedNodeCount,
|
|
5690
|
-
" nodes / ",
|
|
5691
|
-
appliedEdgeCount,
|
|
5692
|
-
" edges applied"
|
|
5693
|
-
] }) : null
|
|
5694
|
-
] }),
|
|
5695
|
-
/* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
|
|
5696
|
-
/* @__PURE__ */ jsx(
|
|
5697
|
-
Select,
|
|
5698
|
-
{
|
|
5699
|
-
label: "Preset",
|
|
5700
|
-
placeholder: "Auto",
|
|
5701
|
-
data: PRESET_OPTIONS,
|
|
5702
|
-
value: value.preset ?? null,
|
|
5703
|
-
onChange: (preset) => updateValue(value, "preset", preset ?? void 0, onChange),
|
|
5704
|
-
disabled,
|
|
5705
|
-
clearable: true
|
|
5706
|
-
}
|
|
5707
|
-
),
|
|
5708
|
-
/* @__PURE__ */ jsx(
|
|
5709
|
-
Select,
|
|
5710
|
-
{
|
|
5711
|
-
label: "Direction",
|
|
5712
|
-
data: DIRECTION_OPTIONS,
|
|
5713
|
-
value: value.direction ?? "both",
|
|
5714
|
-
onChange: (direction) => updateValue(value, "direction", direction ?? "both", onChange),
|
|
5715
|
-
disabled
|
|
5716
|
-
}
|
|
5717
|
-
),
|
|
5718
|
-
/* @__PURE__ */ jsx(
|
|
5719
|
-
NumberInput,
|
|
5720
|
-
{
|
|
5721
|
-
label: "Depth",
|
|
5722
|
-
min: 1,
|
|
5723
|
-
max: 3,
|
|
5724
|
-
value: value.maxDepth ?? 1,
|
|
5725
|
-
onChange: (maxDepth) => updateValue(value, "maxDepth", toMaxDepth(maxDepth), onChange),
|
|
5726
|
-
disabled
|
|
5727
|
-
}
|
|
5728
|
-
),
|
|
5729
|
-
/* @__PURE__ */ jsx(
|
|
5730
|
-
NumberInput,
|
|
5731
|
-
{
|
|
5732
|
-
label: "Max results",
|
|
5733
|
-
min: 1,
|
|
5734
|
-
max: 100,
|
|
5735
|
-
value: value.maxResults ?? 25,
|
|
5736
|
-
onChange: (maxResults) => updateValue(
|
|
5737
|
-
value,
|
|
5738
|
-
"maxResults",
|
|
5739
|
-
Math.max(1, typeof maxResults === "number" ? maxResults : Number.parseInt(maxResults, 10) || 25),
|
|
5740
|
-
onChange
|
|
5741
|
-
),
|
|
5742
|
-
disabled
|
|
5743
|
-
}
|
|
5744
|
-
)
|
|
5745
|
-
] }),
|
|
5746
|
-
/* @__PURE__ */ jsx(
|
|
5747
|
-
MultiSelect,
|
|
5748
|
-
{
|
|
5749
|
-
label: "Relationship filters",
|
|
5750
|
-
placeholder: "Preset defaults",
|
|
5751
|
-
data: RELATIONSHIP_OPTIONS,
|
|
5752
|
-
value: value.relationshipTypes ?? [],
|
|
5753
|
-
onChange: (relationshipTypes) => updateValue(value, "relationshipTypes", toOptionalArray(relationshipTypes), onChange),
|
|
5754
|
-
disabled,
|
|
5755
|
-
clearable: true
|
|
5756
|
-
}
|
|
5757
|
-
),
|
|
5758
|
-
/* @__PURE__ */ jsx(
|
|
5759
|
-
MultiSelect,
|
|
5760
|
-
{
|
|
5761
|
-
label: "Edge kind filters",
|
|
5762
|
-
placeholder: "Preset defaults",
|
|
5763
|
-
data: EDGE_KIND_OPTIONS,
|
|
5764
|
-
value: value.edgeKinds ?? [],
|
|
5765
|
-
onChange: (edgeKinds) => updateValue(value, "edgeKinds", toOptionalArray(edgeKinds), onChange),
|
|
5766
|
-
disabled,
|
|
5767
|
-
clearable: true
|
|
5768
|
-
}
|
|
5769
|
-
),
|
|
5770
|
-
/* @__PURE__ */ jsx(
|
|
5771
|
-
MultiSelect,
|
|
5772
|
-
{
|
|
5773
|
-
label: "Resource type filters",
|
|
5774
|
-
placeholder: "All resource types",
|
|
5775
|
-
data: RESOURCE_TYPE_OPTIONS,
|
|
5776
|
-
value: value.resourceTypes ?? [],
|
|
5777
|
-
onChange: (resourceTypes) => updateValue(value, "resourceTypes", toOptionalArray(resourceTypes), onChange),
|
|
5778
|
-
disabled,
|
|
5779
|
-
clearable: true
|
|
5780
|
-
}
|
|
5781
|
-
),
|
|
5782
|
-
/* @__PURE__ */ jsx(
|
|
5783
|
-
Switch,
|
|
5784
|
-
{
|
|
5785
|
-
label: "Include hidden resources",
|
|
5786
|
-
checked: value.includeHiddenResources ?? true,
|
|
5787
|
-
onChange: (event) => updateValue(value, "includeHiddenResources", event.currentTarget.checked, onChange),
|
|
5788
|
-
disabled
|
|
5789
|
-
}
|
|
5790
|
-
),
|
|
5791
|
-
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,
|
|
5792
|
-
result ? /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
|
|
5793
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
5794
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
5795
|
-
result.counts.newNodes,
|
|
5796
|
-
" new"
|
|
5797
|
-
] }),
|
|
5798
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
5799
|
-
result.counts.alreadyVisibleNodes,
|
|
5800
|
-
" visible"
|
|
5801
|
-
] }),
|
|
5802
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: result.counts.hiddenResourceNodes > 0 ? "orange" : "gray", children: [
|
|
5803
|
-
result.counts.hiddenResourceNodes,
|
|
5804
|
-
" hidden"
|
|
5805
|
-
] }),
|
|
5806
|
-
result.truncated ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", children: "Truncated" }) : null
|
|
5807
|
-
] }),
|
|
5808
|
-
result.summaryMessages.map((message) => /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: message }, message))
|
|
5809
|
-
] }) }) : null,
|
|
5810
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "wrap", children: [
|
|
5811
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
5812
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: onPreview, disabled: disabled || rootIsTooBroad, children: "Preview" }),
|
|
5813
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", onClick: onApply, disabled: !canApply, children: "Apply" })
|
|
5814
|
-
] }),
|
|
5815
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClear, disabled: !result && appliedNodeCount === 0, children: "Clear expansion" })
|
|
5816
|
-
] })
|
|
5817
|
-
] }) });
|
|
5818
|
-
}
|
|
5819
|
-
var cellStyle = {
|
|
5820
|
-
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
5821
|
-
display: "flex",
|
|
5822
|
-
alignItems: "center",
|
|
5823
|
-
gap: "var(--mantine-spacing-sm)",
|
|
5824
|
-
minWidth: 0
|
|
5825
|
-
};
|
|
5826
|
-
function CommandViewHealthStrip({
|
|
5827
|
-
overview,
|
|
5828
|
-
hotspots,
|
|
5829
|
-
visibleResources,
|
|
5830
|
-
hiddenResources = 0,
|
|
5831
|
-
resourcesHidden,
|
|
5832
|
-
selectedLabel,
|
|
5833
|
-
onFocusHotspot,
|
|
5834
|
-
onResourcesHiddenChange,
|
|
5835
|
-
onResetFocus
|
|
5836
|
-
}) {
|
|
5837
|
-
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
5838
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5839
|
-
/* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5840
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
|
|
5841
|
-
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
5842
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
|
|
5843
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
|
|
5844
|
-
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
|
|
5845
|
-
] }),
|
|
5846
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
|
|
5847
|
-
] }),
|
|
5848
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5849
|
-
/* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5850
|
-
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(
|
|
5851
|
-
Badge,
|
|
5852
|
-
{
|
|
5853
|
-
variant: "light",
|
|
5854
|
-
color: "red",
|
|
5855
|
-
size: "xs",
|
|
5856
|
-
style: { cursor: "pointer", flexShrink: 0 },
|
|
5857
|
-
onClick: () => onFocusHotspot(hotspot.resourceId),
|
|
5858
|
-
children: hotspot.label
|
|
5859
|
-
}
|
|
5860
|
-
) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
|
|
5861
|
-
] }),
|
|
5862
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5863
|
-
/* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5864
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
|
|
5865
|
-
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
|
|
5866
|
-
"pending / ",
|
|
5867
|
-
overview?.activeHumanCheckpoints ?? 0,
|
|
5868
|
-
" queues"
|
|
5869
|
-
] })
|
|
5870
|
-
] }),
|
|
5871
|
-
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
5872
|
-
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
5873
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
|
|
5874
|
-
/* @__PURE__ */ jsx(
|
|
5875
|
-
Button,
|
|
5876
|
-
{
|
|
5877
|
-
size: "compact-xs",
|
|
5878
|
-
variant: resourcesHidden ? "light" : "subtle",
|
|
5879
|
-
onClick: () => onResourcesHiddenChange(!resourcesHidden),
|
|
5880
|
-
style: { flexShrink: 0 },
|
|
5881
|
-
children: resourcesHidden ? "Show resources" : "Hide resources"
|
|
5882
|
-
}
|
|
5883
|
-
),
|
|
5884
|
-
/* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
|
|
5885
|
-
] })
|
|
5886
|
-
] });
|
|
5887
|
-
}
|
|
5888
|
-
var FILTER_STATE_ICONS2 = {
|
|
5889
|
-
neutral: IconCircleDashed,
|
|
5890
|
-
include: IconCircleCheck,
|
|
5891
|
-
exclude: IconCircleX
|
|
5892
|
-
};
|
|
5893
|
-
var FILTER_STATE_COLORS2 = {
|
|
5894
|
-
neutral: "var(--color-text-dimmed)",
|
|
5895
|
-
include: "var(--mantine-color-green-6)",
|
|
5896
|
-
exclude: "var(--mantine-color-red-6)"
|
|
5897
|
-
};
|
|
5898
|
-
var FILTER_STATE_LABELS2 = {
|
|
5899
|
-
neutral: "Not filtered",
|
|
5900
|
-
include: "Include only",
|
|
5901
|
-
exclude: "Exclude"
|
|
5902
|
-
};
|
|
5903
|
-
function getCommandViewResources(commandViewData) {
|
|
5904
|
-
if (!commandViewData) {
|
|
5905
|
-
return [];
|
|
5906
|
-
}
|
|
5907
|
-
return [
|
|
5908
|
-
...commandViewData.agents,
|
|
5909
|
-
...commandViewData.workflows,
|
|
5910
|
-
...commandViewData.triggers,
|
|
5911
|
-
...commandViewData.integrations,
|
|
5912
|
-
...commandViewData.externalResources,
|
|
5913
|
-
...commandViewData.humanCheckpoints
|
|
5914
|
-
];
|
|
5915
|
-
}
|
|
5916
|
-
function nextDomainFilterState(current) {
|
|
5917
|
-
if (current === "neutral") return "include";
|
|
5918
|
-
if (current === "include") return "exclude";
|
|
5919
|
-
return "neutral";
|
|
5920
|
-
}
|
|
5921
|
-
function FilterPanel({
|
|
5922
|
-
filters,
|
|
5923
|
-
onChangeFilters,
|
|
5924
|
-
resetValue,
|
|
5925
|
-
disabled = false,
|
|
5926
|
-
commandViewData,
|
|
5927
|
-
lens,
|
|
5928
|
-
resourcesHidden,
|
|
5929
|
-
diagnosticsHidden,
|
|
5930
|
-
onResourcesHiddenChange,
|
|
5931
|
-
onDiagnosticsHiddenChange,
|
|
5932
|
-
onRevealResources,
|
|
5933
|
-
onResetFilters,
|
|
5934
|
-
visibilityCounts,
|
|
5935
|
-
graph,
|
|
5936
|
-
baseGraph,
|
|
5937
|
-
layout = "grid"
|
|
5938
|
-
}) {
|
|
5939
|
-
const resourceFacets = collectResourceFilterFacets(getCommandViewResources(commandViewData));
|
|
5940
|
-
const Section = ({ children }) => layout === "stack" ? /* @__PURE__ */ jsx(
|
|
5941
|
-
Stack,
|
|
5942
|
-
{
|
|
5943
|
-
gap: "sm",
|
|
5944
|
-
pb: "sm",
|
|
5945
|
-
style: {
|
|
5946
|
-
borderBottom: "1px solid var(--color-border)"
|
|
5947
|
-
},
|
|
5948
|
-
children
|
|
5949
|
-
}
|
|
5950
|
-
) : /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", style: { background: "var(--color-surface)" }, children });
|
|
5951
|
-
const updateDomainFilter = (domainId) => {
|
|
5952
|
-
const current = filters.domainFilters[domainId] ?? "neutral";
|
|
5953
|
-
onChangeFilters({
|
|
5954
|
-
...filters,
|
|
5955
|
-
domainFilters: {
|
|
5956
|
-
...filters.domainFilters,
|
|
5957
|
-
[domainId]: nextDomainFilterState(current)
|
|
5958
|
-
}
|
|
5959
|
-
});
|
|
5960
|
-
};
|
|
5961
|
-
const handleResourceVisibilityAction = () => {
|
|
5962
|
-
if (resourcesHidden) {
|
|
5963
|
-
onRevealResources();
|
|
5964
|
-
return;
|
|
5965
|
-
}
|
|
5966
|
-
onResourcesHiddenChange(true);
|
|
5967
|
-
};
|
|
5968
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5969
|
-
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5970
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Filters" }),
|
|
5971
|
-
/* @__PURE__ */ jsx(
|
|
5972
|
-
OrganizationGraphFilterToolbar,
|
|
5973
|
-
{
|
|
5974
|
-
value: filters,
|
|
5975
|
-
onChange: onChangeFilters,
|
|
5976
|
-
disabled,
|
|
5977
|
-
resetValue
|
|
5978
|
-
}
|
|
5979
|
-
)
|
|
5980
|
-
] }) }),
|
|
5981
|
-
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5982
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
|
|
5983
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Visibility" }),
|
|
5984
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
|
|
5985
|
-
visibilityCounts.visibleResourceCount,
|
|
5986
|
-
"/",
|
|
5987
|
-
visibilityCounts.totalResourceCount,
|
|
5988
|
-
" resources"
|
|
5989
|
-
] })
|
|
5990
|
-
] }),
|
|
5991
|
-
lens === "command-view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5992
|
-
/* @__PURE__ */ jsx(
|
|
5993
|
-
Checkbox,
|
|
5994
|
-
{
|
|
5995
|
-
label: "Hide resource nodes",
|
|
5996
|
-
description: "Keep the organization structure readable and reveal resource nodes as needed.",
|
|
5997
|
-
checked: resourcesHidden,
|
|
5998
|
-
onChange: (event) => onResourcesHiddenChange(event.currentTarget.checked),
|
|
5999
|
-
disabled
|
|
6000
|
-
}
|
|
6001
|
-
),
|
|
6002
|
-
/* @__PURE__ */ jsx(
|
|
6003
|
-
Checkbox,
|
|
6004
|
-
{
|
|
6005
|
-
label: "Hide diagnostic and testing resources",
|
|
6006
|
-
description: "Diagnostics stay available through filters, trace, impact, and contextual reveal.",
|
|
6007
|
-
checked: diagnosticsHidden,
|
|
6008
|
-
onChange: (event) => onDiagnosticsHiddenChange(event.currentTarget.checked),
|
|
6009
|
-
disabled
|
|
6010
|
-
}
|
|
6011
|
-
),
|
|
6012
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
6013
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenResourceCount > 0 ? "yellow" : "green", children: [
|
|
6014
|
-
visibilityCounts.hiddenResourceCount,
|
|
6015
|
-
" hidden"
|
|
6016
|
-
] }),
|
|
6017
|
-
/* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenDiagnosticResourceCount > 0 ? "yellow" : "gray", children: [
|
|
6018
|
-
visibilityCounts.hiddenDiagnosticResourceCount,
|
|
6019
|
-
" diagnostic/testing"
|
|
6020
|
-
] })
|
|
6021
|
-
] }),
|
|
6022
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
|
|
6023
|
-
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: handleResourceVisibilityAction, disabled, children: resourcesHidden ? "Reveal resources" : "Hide resources" }),
|
|
6024
|
-
/* @__PURE__ */ jsx(
|
|
6025
|
-
Button,
|
|
6026
|
-
{
|
|
6027
|
-
size: "xs",
|
|
6028
|
-
variant: "subtle",
|
|
6029
|
-
leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
|
|
6030
|
-
onClick: onResetFilters,
|
|
6031
|
-
disabled,
|
|
6032
|
-
children: "Reset filters"
|
|
6033
|
-
}
|
|
6034
|
-
)
|
|
6035
|
-
] })
|
|
6036
|
-
] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Visibility controls are available in the Command View lens." })
|
|
6037
|
-
] }) }),
|
|
6038
|
-
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
6039
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Resource Facets" }),
|
|
6040
|
-
resourceFacets.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: resourceFacets.map((facet) => {
|
|
6041
|
-
const filterState = filters.domainFilters[facet.id] ?? "neutral";
|
|
6042
|
-
const StateIcon = FILTER_STATE_ICONS2[filterState];
|
|
6043
|
-
return /* @__PURE__ */ jsx(
|
|
6044
|
-
UnstyledButton,
|
|
6045
|
-
{
|
|
6046
|
-
title: FILTER_STATE_LABELS2[filterState],
|
|
6047
|
-
onClick: () => updateDomainFilter(facet.id),
|
|
6048
|
-
disabled,
|
|
6049
|
-
style: {
|
|
6050
|
-
border: "1px solid var(--color-border)",
|
|
6051
|
-
borderRadius: "var(--mantine-radius-sm)",
|
|
6052
|
-
padding: "6px 8px"
|
|
6053
|
-
},
|
|
6054
|
-
children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
|
|
6055
|
-
/* @__PURE__ */ jsx(StateIcon, { size: 16, style: { color: FILTER_STATE_COLORS2[filterState], flexShrink: 0 } }),
|
|
6056
|
-
/* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, c: filterState === "neutral" ? "dimmed" : void 0, children: facet.label })
|
|
6057
|
-
] })
|
|
6058
|
-
},
|
|
6059
|
-
facet.id
|
|
6060
|
-
);
|
|
6061
|
-
}) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No resource facets are available for the current topology." }),
|
|
6062
|
-
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
|
|
6063
|
-
"Showing ",
|
|
6064
|
-
graph?.nodes.length ?? 0,
|
|
6065
|
-
" nodes and ",
|
|
6066
|
-
graph?.edges.length ?? 0,
|
|
6067
|
-
" edges from",
|
|
6068
|
-
" ",
|
|
6069
|
-
baseGraph?.nodes.length ?? 0,
|
|
6070
|
-
" total nodes."
|
|
6071
|
-
] })
|
|
6072
|
-
] }) })
|
|
6073
|
-
] });
|
|
6074
|
-
if (layout === "stack") {
|
|
6075
|
-
return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: content });
|
|
6076
|
-
}
|
|
6077
|
-
return /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, lg: 3 }, spacing: "md", children: content });
|
|
3382
|
+
function CommandViewHealthStrip({
|
|
3383
|
+
overview,
|
|
3384
|
+
hotspots,
|
|
3385
|
+
visibleResources,
|
|
3386
|
+
hiddenResources = 0,
|
|
3387
|
+
resourcesHidden,
|
|
3388
|
+
selectedLabel,
|
|
3389
|
+
onFocusHotspot,
|
|
3390
|
+
onResourcesHiddenChange,
|
|
3391
|
+
onResetFocus
|
|
3392
|
+
}) {
|
|
3393
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
|
|
3394
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
3395
|
+
/* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
3396
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
|
|
3397
|
+
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
3398
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
|
|
3399
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
|
|
3400
|
+
/* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
|
|
3401
|
+
] }),
|
|
3402
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
|
|
3403
|
+
] }),
|
|
3404
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
3405
|
+
/* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
3406
|
+
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(
|
|
3407
|
+
Badge,
|
|
3408
|
+
{
|
|
3409
|
+
variant: "light",
|
|
3410
|
+
color: "red",
|
|
3411
|
+
size: "xs",
|
|
3412
|
+
style: { cursor: "pointer", flexShrink: 0 },
|
|
3413
|
+
onClick: () => onFocusHotspot(hotspot.resourceId),
|
|
3414
|
+
children: hotspot.label
|
|
3415
|
+
}
|
|
3416
|
+
) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
|
|
3417
|
+
] }),
|
|
3418
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
3419
|
+
/* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
3420
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
|
|
3421
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
|
|
3422
|
+
"pending / ",
|
|
3423
|
+
overview?.activeHumanCheckpoints ?? 0,
|
|
3424
|
+
" queues"
|
|
3425
|
+
] })
|
|
3426
|
+
] }),
|
|
3427
|
+
/* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
|
|
3428
|
+
/* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
|
|
3429
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
|
|
3430
|
+
/* @__PURE__ */ jsx(
|
|
3431
|
+
Button,
|
|
3432
|
+
{
|
|
3433
|
+
size: "compact-xs",
|
|
3434
|
+
variant: resourcesHidden ? "light" : "subtle",
|
|
3435
|
+
onClick: () => onResourcesHiddenChange(!resourcesHidden),
|
|
3436
|
+
style: { flexShrink: 0 },
|
|
3437
|
+
children: resourcesHidden ? "Show resources" : "Hide resources"
|
|
3438
|
+
}
|
|
3439
|
+
),
|
|
3440
|
+
/* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
|
|
3441
|
+
] })
|
|
3442
|
+
] });
|
|
6078
3443
|
}
|
|
6079
3444
|
|
|
6080
3445
|
// src/features/operations/organization-graph/commandViewGraphHealth.ts
|
|
@@ -7863,362 +5228,6 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
7863
5228
|
function CommandViewPage({ timeRange }) {
|
|
7864
5229
|
return /* @__PURE__ */ jsx(OrganizationGraphPage, { lens: "command-view", timeRange });
|
|
7865
5230
|
}
|
|
7866
|
-
var EXECUTION_SECTIONS = [
|
|
7867
|
-
{ status: "failed", title: "Failed Executions", badgeColor: "red" },
|
|
7868
|
-
{ status: "warning", title: "Warning Executions", badgeColor: "yellow" },
|
|
7869
|
-
{ status: "completed", title: "Successful Executions", badgeColor: null }
|
|
7870
|
-
];
|
|
7871
|
-
var HOVER_CARD_STYLE = {
|
|
7872
|
-
cursor: "pointer",
|
|
7873
|
-
transition: "box-shadow var(--duration-fast) var(--easing)",
|
|
7874
|
-
textDecoration: "none",
|
|
7875
|
-
color: "inherit"
|
|
7876
|
-
};
|
|
7877
|
-
function handleHoverEnter(e) {
|
|
7878
|
-
e.currentTarget.style.boxShadow = "var(--standard-box-shadow)";
|
|
7879
|
-
}
|
|
7880
|
-
function handleHoverLeave(e) {
|
|
7881
|
-
e.currentTarget.style.boxShadow = "";
|
|
7882
|
-
}
|
|
7883
|
-
function ExecutionStatusSection({ executions, status, title, badgeColor, resourceUrl }) {
|
|
7884
|
-
const filtered = executions.filter((e) => e.status === status);
|
|
7885
|
-
if (filtered.length === 0) return null;
|
|
7886
|
-
return /* @__PURE__ */ jsxs("div", { children: [
|
|
7887
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
7888
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: title }),
|
|
7889
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: filtered.length })
|
|
7890
|
-
] }),
|
|
7891
|
-
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: filtered.map((execution) => /* @__PURE__ */ jsxs(
|
|
7892
|
-
Card,
|
|
7893
|
-
{
|
|
7894
|
-
padding: "xs",
|
|
7895
|
-
withBorder: true,
|
|
7896
|
-
component: "a",
|
|
7897
|
-
href: `${resourceUrl}?exec=${execution.executionId}`,
|
|
7898
|
-
target: "_blank",
|
|
7899
|
-
rel: "noopener noreferrer",
|
|
7900
|
-
style: HOVER_CARD_STYLE,
|
|
7901
|
-
onMouseEnter: handleHoverEnter,
|
|
7902
|
-
onMouseLeave: handleHoverLeave,
|
|
7903
|
-
children: [
|
|
7904
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: status === "failed" && execution.errorMessage ? 4 : 0, children: [
|
|
7905
|
-
badgeColor ? /* @__PURE__ */ jsx(Badge, { size: "xs", color: badgeColor, variant: "light", children: status }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "green", children: "\u2713 Completed" }),
|
|
7906
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(execution.startedAt) })
|
|
7907
|
-
] }),
|
|
7908
|
-
status === "failed" && execution.errorMessage && /* @__PURE__ */ jsx(Text, { size: "xs", c: "red", lineClamp: 2, children: execution.errorMessage })
|
|
7909
|
-
]
|
|
7910
|
-
},
|
|
7911
|
-
execution.executionId
|
|
7912
|
-
)) }),
|
|
7913
|
-
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
7914
|
-
] });
|
|
7915
|
-
}
|
|
7916
|
-
function CommandViewSidebarContent({ timeRange }) {
|
|
7917
|
-
const theme = useMantineTheme();
|
|
7918
|
-
const colors = useCyberColors();
|
|
7919
|
-
const { organizationModel } = useElevasisFeatures();
|
|
7920
|
-
const lensConfig = useMemo(() => getOrganizationGraphLensConfig("command-view"), []);
|
|
7921
|
-
const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
|
|
7922
|
-
const toolbarResetValue = useMemo(
|
|
7923
|
-
() => createOrganizationGraphFilters(lensConfig.initialFilters),
|
|
7924
|
-
[lensConfig.initialFilters]
|
|
7925
|
-
);
|
|
7926
|
-
const selectedNodeId = useCommandViewStore((s) => s.selectedNodeId);
|
|
7927
|
-
const resourcesHidden = useCommandViewStore((s) => s.resourcesHidden);
|
|
7928
|
-
const setResourcesHidden = useCommandViewStore((s) => s.setResourcesHidden);
|
|
7929
|
-
const diagnosticsHidden = useCommandViewStore((s) => s.diagnosticsHidden);
|
|
7930
|
-
const setDiagnosticsHidden = useCommandViewStore((s) => s.setDiagnosticsHidden);
|
|
7931
|
-
const diagnosticCategories = useCommandViewStore((s) => s.diagnosticCategories);
|
|
7932
|
-
const revealedIds = useCommandViewStore((s) => s.revealedIds);
|
|
7933
|
-
const clearRevealedIds = useCommandViewStore((s) => s.clearRevealedIds);
|
|
7934
|
-
const { data, isLoading } = useCommandViewData();
|
|
7935
|
-
const { data: statsData } = useCommandViewStats(timeRange);
|
|
7936
|
-
const cleanData = data ?? null;
|
|
7937
|
-
const dataWithStats = useMemo(() => {
|
|
7938
|
-
if (!cleanData) return null;
|
|
7939
|
-
if (!statsData) return cleanData;
|
|
7940
|
-
return mergeStatsWithTopology(cleanData, statsData);
|
|
7941
|
-
}, [cleanData, statsData]);
|
|
7942
|
-
const baseGraph = useMemo(() => {
|
|
7943
|
-
if (!organizationModel) {
|
|
7944
|
-
return null;
|
|
7945
|
-
}
|
|
7946
|
-
return buildOrganizationGraph({
|
|
7947
|
-
organizationModel,
|
|
7948
|
-
commandViewData: cleanData ?? void 0
|
|
7949
|
-
});
|
|
7950
|
-
}, [cleanData, organizationModel]);
|
|
7951
|
-
const graph = useMemo(() => {
|
|
7952
|
-
if (!baseGraph) {
|
|
7953
|
-
return null;
|
|
7954
|
-
}
|
|
7955
|
-
return filterOrganizationGraph(baseGraph, filters, {
|
|
7956
|
-
commandViewData: cleanData
|
|
7957
|
-
});
|
|
7958
|
-
}, [baseGraph, cleanData, filters]);
|
|
7959
|
-
const visibilityProjection = useMemo(() => {
|
|
7960
|
-
if (!graph) {
|
|
7961
|
-
return {
|
|
7962
|
-
hiddenIds: /* @__PURE__ */ new Set(),
|
|
7963
|
-
hiddenEdgeIds: /* @__PURE__ */ new Set(),
|
|
7964
|
-
totalResourceCount: 0,
|
|
7965
|
-
visibleResourceCount: 0,
|
|
7966
|
-
hiddenResourceCount: 0,
|
|
7967
|
-
hiddenDiagnosticResourceCount: 0
|
|
7968
|
-
};
|
|
7969
|
-
}
|
|
7970
|
-
return getCommandViewVisibilityProjection({
|
|
7971
|
-
graph,
|
|
7972
|
-
commandViewData: cleanData,
|
|
7973
|
-
resourcesHidden,
|
|
7974
|
-
diagnosticsHidden,
|
|
7975
|
-
diagnosticCategories,
|
|
7976
|
-
revealedIds,
|
|
7977
|
-
mode: "map"
|
|
7978
|
-
});
|
|
7979
|
-
}, [cleanData, diagnosticCategories, diagnosticsHidden, graph, resourcesHidden, revealedIds]);
|
|
7980
|
-
const visibleGraph = useMemo(() => {
|
|
7981
|
-
if (!graph || visibilityProjection.hiddenIds.size === 0) {
|
|
7982
|
-
return graph;
|
|
7983
|
-
}
|
|
7984
|
-
return {
|
|
7985
|
-
...graph,
|
|
7986
|
-
nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
|
|
7987
|
-
edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
|
|
7988
|
-
};
|
|
7989
|
-
}, [graph, visibilityProjection]);
|
|
7990
|
-
const handleResetFilters = () => {
|
|
7991
|
-
resetFilters();
|
|
7992
|
-
clearRevealedIds();
|
|
7993
|
-
};
|
|
7994
|
-
const handleResourcesHiddenChange = (value) => {
|
|
7995
|
-
setResourcesHidden(value);
|
|
7996
|
-
if (value) {
|
|
7997
|
-
clearRevealedIds();
|
|
7998
|
-
}
|
|
7999
|
-
};
|
|
8000
|
-
const handleDiagnosticsHiddenChange = (value) => {
|
|
8001
|
-
setDiagnosticsHidden(value);
|
|
8002
|
-
if (value) {
|
|
8003
|
-
clearRevealedIds();
|
|
8004
|
-
}
|
|
8005
|
-
};
|
|
8006
|
-
const revealAllResources = () => {
|
|
8007
|
-
setResourcesHidden(false);
|
|
8008
|
-
setDiagnosticsHidden(false);
|
|
8009
|
-
clearRevealedIds();
|
|
8010
|
-
};
|
|
8011
|
-
const { donutSuccessCount, donutFailedCount } = useMemo(() => {
|
|
8012
|
-
if (!cleanData || !statsData) return { donutSuccessCount: 0, donutFailedCount: 0 };
|
|
8013
|
-
const allResources = [
|
|
8014
|
-
...cleanData.agents,
|
|
8015
|
-
...cleanData.workflows,
|
|
8016
|
-
...cleanData.triggers,
|
|
8017
|
-
...cleanData.integrations,
|
|
8018
|
-
...cleanData.externalResources ?? [],
|
|
8019
|
-
...cleanData.humanCheckpoints ?? []
|
|
8020
|
-
];
|
|
8021
|
-
const filteredIds = new Set(allResources.map((resource) => resource.resourceId));
|
|
8022
|
-
let success = 0;
|
|
8023
|
-
let failed = 0;
|
|
8024
|
-
for (const [id, stats] of Object.entries(statsData.resources)) {
|
|
8025
|
-
if (filteredIds.has(id)) {
|
|
8026
|
-
success += stats.successCount;
|
|
8027
|
-
failed += stats.failureCount;
|
|
8028
|
-
}
|
|
8029
|
-
}
|
|
8030
|
-
return { donutSuccessCount: success, donutFailedCount: failed };
|
|
8031
|
-
}, [cleanData, statsData]);
|
|
8032
|
-
const selectedNode = useMemo(() => {
|
|
8033
|
-
if (!selectedNodeId || !dataWithStats) return null;
|
|
8034
|
-
const allNodes = [
|
|
8035
|
-
...dataWithStats.agents || [],
|
|
8036
|
-
...dataWithStats.workflows || [],
|
|
8037
|
-
...dataWithStats.triggers || [],
|
|
8038
|
-
...dataWithStats.integrations || [],
|
|
8039
|
-
...dataWithStats.externalResources || [],
|
|
8040
|
-
...dataWithStats.humanCheckpoints || []
|
|
8041
|
-
];
|
|
8042
|
-
return allNodes.find((node) => {
|
|
8043
|
-
const nodeId = getNodeId(node);
|
|
8044
|
-
return nodeId === selectedNodeId || node.name === selectedNodeId;
|
|
8045
|
-
}) || null;
|
|
8046
|
-
}, [selectedNodeId, dataWithStats]);
|
|
8047
|
-
const isNavigable = selectedNode?.type === "agent" || selectedNode?.type === "workflow";
|
|
8048
|
-
const isHumanCheckpoint = selectedNode?.type === "human";
|
|
8049
|
-
const selectedResourceId = useMemo(() => {
|
|
8050
|
-
if (!selectedNode) return null;
|
|
8051
|
-
return getNodeId(selectedNode);
|
|
8052
|
-
}, [selectedNode]);
|
|
8053
|
-
const {
|
|
8054
|
-
page: executionPage,
|
|
8055
|
-
setPage: setExecutionPage,
|
|
8056
|
-
totalPages: totalExecutionPages
|
|
8057
|
-
} = usePaginationState(10, [selectedResourceId, timeRange]);
|
|
8058
|
-
const getNavigationUrl = () => {
|
|
8059
|
-
if (!selectedNode || !selectedResourceId) return null;
|
|
8060
|
-
if (selectedNode.type === "agent") return `/operations/resources/agent/${selectedResourceId}`;
|
|
8061
|
-
if (selectedNode.type === "workflow") return `/operations/resources/workflow/${selectedResourceId}`;
|
|
8062
|
-
if (selectedNode.type === "human") return `/operations/command-queue?checkpoint=${selectedResourceId}`;
|
|
8063
|
-
return null;
|
|
8064
|
-
};
|
|
8065
|
-
const resourceUrl = selectedNode?.type === "agent" ? `/operations/resources/agent/${selectedResourceId}` : `/operations/resources/workflow/${selectedResourceId}`;
|
|
8066
|
-
const {
|
|
8067
|
-
data: executionsData,
|
|
8068
|
-
isLoading: executionsLoading,
|
|
8069
|
-
error: executionsError
|
|
8070
|
-
} = useResourceExecutions({
|
|
8071
|
-
resourceId: selectedResourceId,
|
|
8072
|
-
timeRange,
|
|
8073
|
-
page: executionPage,
|
|
8074
|
-
limit: 10,
|
|
8075
|
-
enabled: isNavigable
|
|
8076
|
-
});
|
|
8077
|
-
const {
|
|
8078
|
-
data: checkpointTasksData,
|
|
8079
|
-
isLoading: checkpointTasksLoading,
|
|
8080
|
-
error: checkpointTasksError
|
|
8081
|
-
} = useCheckpointTasks({
|
|
8082
|
-
checkpointId: selectedResourceId,
|
|
8083
|
-
enabled: isHumanCheckpoint
|
|
8084
|
-
});
|
|
8085
|
-
const totalExecutions = donutSuccessCount + donutFailedCount;
|
|
8086
|
-
const successRate = totalExecutions > 0 ? donutSuccessCount / totalExecutions * 100 : 0;
|
|
8087
|
-
const healthSegments = [
|
|
8088
|
-
{ name: "Completed", value: donutSuccessCount, color: colors.green },
|
|
8089
|
-
{ name: "Failed", value: donutFailedCount, color: colors.red }
|
|
8090
|
-
];
|
|
8091
|
-
const centerValueColor = totalExecutions === 0 ? "var(--mantine-color-dimmed)" : successRate >= 95 ? colors.green : successRate >= 80 ? colors.yellow : colors.red;
|
|
8092
|
-
if (isLoading && !data) {
|
|
8093
|
-
return /* @__PURE__ */ jsx(SubshellSidebarLoader, {});
|
|
8094
|
-
}
|
|
8095
|
-
return /* @__PURE__ */ jsx(
|
|
8096
|
-
Box,
|
|
8097
|
-
{
|
|
8098
|
-
style: {
|
|
8099
|
-
flex: 1,
|
|
8100
|
-
height: "100%",
|
|
8101
|
-
minHeight: 0,
|
|
8102
|
-
display: "flex",
|
|
8103
|
-
flexDirection: "column",
|
|
8104
|
-
overflow: "hidden"
|
|
8105
|
-
},
|
|
8106
|
-
children: /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", overflowX: "hidden" }, children: [
|
|
8107
|
-
/* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconSitemap, label: "Command View" }),
|
|
8108
|
-
/* @__PURE__ */ jsx(Box, { style: { padding: theme.spacing.sm, paddingBottom: 0 }, children: /* @__PURE__ */ jsx(Box, { pb: "xs", mb: 4, children: /* @__PURE__ */ jsx(
|
|
8109
|
-
CyberDonut,
|
|
8110
|
-
{
|
|
8111
|
-
title: `Execution Health (${timeRange})`,
|
|
8112
|
-
segments: healthSegments,
|
|
8113
|
-
centerValue: totalExecutions === 0 ? "\u2014" : `${Math.round(successRate)}%`,
|
|
8114
|
-
centerLabel: `${totalExecutions} runs`,
|
|
8115
|
-
centerValueColor,
|
|
8116
|
-
glowId: "cvHealthGlow",
|
|
8117
|
-
colors
|
|
8118
|
-
}
|
|
8119
|
-
) }) }),
|
|
8120
|
-
/* @__PURE__ */ jsx(Box, { p: "sm", children: /* @__PURE__ */ jsx(
|
|
8121
|
-
FilterPanel,
|
|
8122
|
-
{
|
|
8123
|
-
filters,
|
|
8124
|
-
onChangeFilters: updateFilters,
|
|
8125
|
-
resetValue: toolbarResetValue,
|
|
8126
|
-
disabled: !baseGraph,
|
|
8127
|
-
commandViewData: cleanData,
|
|
8128
|
-
lens: "command-view",
|
|
8129
|
-
resourcesHidden,
|
|
8130
|
-
diagnosticsHidden,
|
|
8131
|
-
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
8132
|
-
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
8133
|
-
onRevealResources: revealAllResources,
|
|
8134
|
-
onResetFilters: handleResetFilters,
|
|
8135
|
-
visibilityCounts: visibilityProjection,
|
|
8136
|
-
graph: visibleGraph,
|
|
8137
|
-
baseGraph,
|
|
8138
|
-
layout: "stack"
|
|
8139
|
-
}
|
|
8140
|
-
) }),
|
|
8141
|
-
selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8142
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
8143
|
-
/* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
|
|
8144
|
-
/* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
|
|
8145
|
-
selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
|
|
8146
|
-
(isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
|
|
8147
|
-
Button,
|
|
8148
|
-
{
|
|
8149
|
-
component: "a",
|
|
8150
|
-
href: getNavigationUrl() || "#",
|
|
8151
|
-
target: "_blank",
|
|
8152
|
-
rel: "noopener noreferrer",
|
|
8153
|
-
variant: "light",
|
|
8154
|
-
size: "xs",
|
|
8155
|
-
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
|
|
8156
|
-
mt: 4,
|
|
8157
|
-
children: [
|
|
8158
|
-
"Go to",
|
|
8159
|
-
" ",
|
|
8160
|
-
selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
|
|
8161
|
-
]
|
|
8162
|
-
}
|
|
8163
|
-
),
|
|
8164
|
-
/* @__PURE__ */ jsx(Space, { h: "sm" })
|
|
8165
|
-
] })
|
|
8166
|
-
] }),
|
|
8167
|
-
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: [
|
|
8168
|
-
EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
|
|
8169
|
-
ExecutionStatusSection,
|
|
8170
|
-
{
|
|
8171
|
-
executions: executionsData.executions,
|
|
8172
|
-
status: section.status,
|
|
8173
|
-
title: section.title,
|
|
8174
|
-
badgeColor: section.badgeColor,
|
|
8175
|
-
resourceUrl
|
|
8176
|
-
},
|
|
8177
|
-
section.status
|
|
8178
|
-
)),
|
|
8179
|
-
totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
|
|
8180
|
-
Pagination,
|
|
8181
|
-
{
|
|
8182
|
-
size: "sm",
|
|
8183
|
-
total: totalExecutionPages(executionsData.totalExecutions),
|
|
8184
|
-
value: executionPage,
|
|
8185
|
-
onChange: setExecutionPage,
|
|
8186
|
-
boundaries: 1
|
|
8187
|
-
}
|
|
8188
|
-
) })
|
|
8189
|
-
] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
|
|
8190
|
-
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: [
|
|
8191
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
|
|
8192
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
|
|
8193
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
|
|
8194
|
-
] }),
|
|
8195
|
-
/* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
|
|
8196
|
-
Card,
|
|
8197
|
-
{
|
|
8198
|
-
padding: "xs",
|
|
8199
|
-
withBorder: true,
|
|
8200
|
-
component: "a",
|
|
8201
|
-
href: `/operations/command-queue?task=${task.id}`,
|
|
8202
|
-
target: "_blank",
|
|
8203
|
-
rel: "noopener noreferrer",
|
|
8204
|
-
style: HOVER_CARD_STYLE,
|
|
8205
|
-
onMouseEnter: handleHoverEnter,
|
|
8206
|
-
onMouseLeave: handleHoverLeave,
|
|
8207
|
-
children: [
|
|
8208
|
-
/* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: task.description ? 4 : 0, children: [
|
|
8209
|
-
/* @__PURE__ */ jsx(Badge, { size: "xs", color: "orange", variant: "light", children: "pending" }),
|
|
8210
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(task.createdAt) })
|
|
8211
|
-
] }),
|
|
8212
|
-
task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
|
|
8213
|
-
]
|
|
8214
|
-
},
|
|
8215
|
-
task.id
|
|
8216
|
-
)) })
|
|
8217
|
-
] }) : checkpointTasksData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending tasks" }) : null })
|
|
8218
|
-
] })
|
|
8219
|
-
}
|
|
8220
|
-
);
|
|
8221
|
-
}
|
|
8222
5231
|
function WorkflowExecutionPanel({
|
|
8223
5232
|
resourceId,
|
|
8224
5233
|
resourceDefinition,
|
|
@@ -8403,6 +5412,81 @@ function ExecutionPanel({
|
|
|
8403
5412
|
return isWorkflowDefinition2(resourceDefinition) ? /* @__PURE__ */ jsx(WorkflowExecutionPanel, { ...diProps, resourceDefinition }) : /* @__PURE__ */ jsx(ResourceDefinitionError, { resourceId, resourceType, resourceName });
|
|
8404
5413
|
}
|
|
8405
5414
|
}
|
|
5415
|
+
function ExecuteWorkflowModal({
|
|
5416
|
+
opened,
|
|
5417
|
+
onClose,
|
|
5418
|
+
resource,
|
|
5419
|
+
isPending = false,
|
|
5420
|
+
error,
|
|
5421
|
+
result,
|
|
5422
|
+
onViewExecution,
|
|
5423
|
+
onReset,
|
|
5424
|
+
children
|
|
5425
|
+
}) {
|
|
5426
|
+
const canClose = !isPending;
|
|
5427
|
+
const title = resource.name ?? resource.resourceId;
|
|
5428
|
+
return /* @__PURE__ */ jsx(
|
|
5429
|
+
Modal,
|
|
5430
|
+
{
|
|
5431
|
+
opened,
|
|
5432
|
+
onClose: canClose ? onClose : () => void 0,
|
|
5433
|
+
centered: true,
|
|
5434
|
+
size: "lg",
|
|
5435
|
+
closeOnClickOutside: canClose,
|
|
5436
|
+
closeOnEscape: canClose,
|
|
5437
|
+
withCloseButton: canClose,
|
|
5438
|
+
title: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
|
|
5439
|
+
/* @__PURE__ */ jsxs(Text, { fw: 600, children: [
|
|
5440
|
+
"Run ",
|
|
5441
|
+
resource.resourceType
|
|
5442
|
+
] }),
|
|
5443
|
+
/* @__PURE__ */ jsx(Badge, { color: "blue", variant: "light", size: "sm", children: resource.resourceType })
|
|
5444
|
+
] }),
|
|
5445
|
+
children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
|
|
5446
|
+
/* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
5447
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Target:" }),
|
|
5448
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: title }),
|
|
5449
|
+
/* @__PURE__ */ jsx(Code, { children: resource.resourceId })
|
|
5450
|
+
] }),
|
|
5451
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
5452
|
+
result ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5453
|
+
/* @__PURE__ */ jsx(Alert, { variant: "light", color: "teal", title: "Execution started", icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }), children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
5454
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", children: [
|
|
5455
|
+
"The ",
|
|
5456
|
+
resource.resourceType,
|
|
5457
|
+
" is now running."
|
|
5458
|
+
] }),
|
|
5459
|
+
/* @__PURE__ */ jsxs(Group, { gap: 4, children: [
|
|
5460
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Execution ID:" }),
|
|
5461
|
+
/* @__PURE__ */ jsx(Code, { children: result.executionId })
|
|
5462
|
+
] })
|
|
5463
|
+
] }) }),
|
|
5464
|
+
/* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
|
|
5465
|
+
onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Run again" }),
|
|
5466
|
+
onViewExecution && /* @__PURE__ */ jsx(
|
|
5467
|
+
Button,
|
|
5468
|
+
{
|
|
5469
|
+
leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 16 }),
|
|
5470
|
+
onClick: () => onViewExecution(result.executionId),
|
|
5471
|
+
children: "View execution"
|
|
5472
|
+
}
|
|
5473
|
+
),
|
|
5474
|
+
/* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
|
|
5475
|
+
] })
|
|
5476
|
+
] }) : error ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
5477
|
+
/* @__PURE__ */ jsx(Alert, { variant: "light", color: "red", title: "Execution failed to start", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: /* @__PURE__ */ jsx(Text, { size: "sm", children: error.message || "An unknown error occurred." }) }),
|
|
5478
|
+
/* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
|
|
5479
|
+
onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Try again" }),
|
|
5480
|
+
/* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
|
|
5481
|
+
] })
|
|
5482
|
+
] }) : /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
5483
|
+
/* @__PURE__ */ jsx(LoadingOverlay, { visible: isPending, zIndex: 1e3, overlayProps: { blur: 2 } }),
|
|
5484
|
+
children ?? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No input form provided." })
|
|
5485
|
+
] })
|
|
5486
|
+
] })
|
|
5487
|
+
}
|
|
5488
|
+
);
|
|
5489
|
+
}
|
|
8406
5490
|
function SessionListItem({ session, onClick, isSelected = false, onDeleted }) {
|
|
8407
5491
|
const deleteSession = useDeleteSession();
|
|
8408
5492
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
@@ -9536,4 +6620,4 @@ var operationsManifest = {
|
|
|
9536
6620
|
sidebarWidth: ({ currentPath }) => currentPath.startsWith("/knowledge/command-view") ? commandViewSidebarWidth : defaultOperationsSidebarWidth
|
|
9537
6621
|
};
|
|
9538
6622
|
|
|
9539
|
-
export { ActionModal, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionPanel, AgentSessionGroup, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, CheckpointGroup, CollapsibleJsonSection, CommandQueueDetailPage, CommandQueuePage, CommandQueueShell, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewPage,
|
|
6623
|
+
export { ActionModal, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionPanel, AgentSessionGroup, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, CheckpointGroup, CollapsibleJsonSection, CommandQueueDetailPage, CommandQueuePage, CommandQueueShell, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewPage, ConfigCard, ContentSections, ContextUsageBadge, ContractDisplay, ExecuteWorkflowModal, ExecutionErrorSection, ExecutionPanel, LogEntry, LogGroup, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, OperationsSidebar, OperationsSidebarMiddle, OperationsSidebarTop, OrganizationGraphPage, ResourceDefinitionSection, ResourceDetailPage, ResourceErrorState, 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 };
|