@elevasis/ui 2.29.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CoreAuthKitInner-QC62UHTZ.js → CoreAuthKitInner-KSEGSB67.js} +1 -1
- package/dist/api/index.js +3 -3
- package/dist/app/index.d.ts +176 -1
- package/dist/app/index.js +11 -11
- package/dist/auth/context.js +1 -1
- package/dist/auth/index.js +5 -5
- package/dist/charts/index.d.ts +2 -1
- package/dist/charts/index.js +9 -9
- package/dist/{chunk-XTVZFT7U.js → chunk-2Q2JQSQO.js} +1 -1
- package/dist/{chunk-LH4GPYDX.js → chunk-3BAPR3KA.js} +19 -3
- package/dist/{chunk-HLFFKKT3.js → chunk-3FV6HBXS.js} +17 -17
- package/dist/{chunk-WKJ47GIW.js → chunk-533DUEQY.js} +1 -1
- package/dist/{chunk-SZWXQHKO.js → chunk-542WPQU2.js} +9 -8
- package/dist/{chunk-5CW2HXQA.js → chunk-5LJAEZMA.js} +7 -28
- package/dist/{chunk-V3HUIZJX.js → chunk-6IXOKUBC.js} +1 -1
- package/dist/{chunk-VKMNWHTL.js → chunk-6YT4IKJ7.js} +3 -3
- package/dist/{chunk-CEHUFNAL.js → chunk-7HMCB26R.js} +12 -12
- package/dist/chunk-7KC4P3AU.js +357 -0
- package/dist/{chunk-OWESKPTJ.js → chunk-CQZ3DNQY.js} +30 -11
- package/dist/{chunk-ROSMICXG.js → chunk-CXY7FMUM.js} +35 -20
- package/dist/{chunk-I2KLQ2HA.js → chunk-DZTG5IAC.js} +7 -1
- package/dist/{chunk-JCGD4GM6.js → chunk-GRDLB6LM.js} +1 -0
- package/dist/{chunk-FGDUK74A.js → chunk-HQGF4ATG.js} +10 -56
- package/dist/{chunk-HOIT677G.js → chunk-HUJCU55S.js} +1 -1
- package/dist/{chunk-OIMPGKDB.js → chunk-HYNYEBHM.js} +4 -4
- package/dist/{chunk-GESXCQWY.js → chunk-JA5ECJJB.js} +1 -1
- package/dist/{chunk-KU7ZDWQ7.js → chunk-JBWJ6WHZ.js} +1 -1
- package/dist/{chunk-HNFQCOD2.js → chunk-JKSUN5GN.js} +1107 -370
- package/dist/{chunk-5WWZXCS5.js → chunk-KJ3QUBNU.js} +9 -2
- package/dist/{chunk-OHGNCWJP.js → chunk-L2NVFLXU.js} +3 -3
- package/dist/{chunk-6WXDE5LZ.js → chunk-L3BVJWML.js} +1 -1
- package/dist/{chunk-3DUOPXOJ.js → chunk-MVFCLZSK.js} +691 -222
- package/dist/{chunk-A7R2URMV.js → chunk-ND42LPY4.js} +44 -10
- package/dist/{chunk-CLUP5H3C.js → chunk-O2QOPJI5.js} +360 -126
- package/dist/{chunk-VMJVQAFZ.js → chunk-OAVTMITG.js} +1 -1
- package/dist/{chunk-X2SUMO3P.js → chunk-P55BJZZW.js} +2 -1
- package/dist/{chunk-QNL7UI5G.js → chunk-Q6OYNEGR.js} +6 -6
- package/dist/{chunk-Y3YJKKEB.js → chunk-QDEETKYT.js} +5 -2
- package/dist/{chunk-XBMCDGHA.js → chunk-QHEWXU7I.js} +1 -1
- package/dist/chunk-R2XR4FCV.js +48 -0
- package/dist/chunk-R66W5UDG.js +26 -0
- package/dist/{chunk-65RQE3XF.js → chunk-SHQXMW4F.js} +1051 -380
- package/dist/{chunk-AK5E6ILJ.js → chunk-T3IPHEYJ.js} +1893 -305
- package/dist/{chunk-7E3FUTND.js → chunk-TOIXUWR6.js} +1 -1
- package/dist/{chunk-FFDAE2QI.js → chunk-TVRQ6AQI.js} +172 -26
- package/dist/{chunk-CN2HC4D4.js → chunk-UFTM5SZZ.js} +2 -2
- package/dist/{chunk-WFTNY755.js → chunk-VKIZUUPM.js} +1 -1
- package/dist/{chunk-KVJ3LFH2.js → chunk-VNFR57DF.js} +4 -24
- package/dist/{chunk-S66IQSSR.js → chunk-WF227UBV.js} +1 -1
- package/dist/{chunk-6NHCE7JM.js → chunk-Y4FWCG7Y.js} +159 -314
- package/dist/components/chat/index.d.ts +2 -1
- package/dist/components/chat/index.js +2 -2
- package/dist/components/index.d.ts +205 -11
- package/dist/components/index.js +51 -48
- package/dist/components/navigation/index.js +9 -9
- package/dist/execution/index.d.ts +2 -1
- package/dist/execution/index.js +1 -1
- package/dist/features/auth/index.d.ts +121 -0
- package/dist/features/auth/index.js +6 -6
- package/dist/features/clients/index.css +611 -0
- package/dist/features/clients/index.d.ts +86 -0
- package/dist/features/clients/index.js +719 -0
- package/dist/features/crm/index.d.ts +148 -2
- package/dist/features/crm/index.js +27 -25
- package/dist/features/dashboard/index.d.ts +36 -1
- package/dist/features/dashboard/index.js +23 -23
- package/dist/features/delivery/index.d.ts +121 -0
- package/dist/features/delivery/index.js +27 -25
- package/dist/features/knowledge/index.js +52 -29
- package/dist/features/lead-gen/index.d.ts +116 -12
- package/dist/features/lead-gen/index.js +28 -26
- package/dist/features/monitoring/index.js +26 -25
- package/dist/features/monitoring/requests/index.js +23 -22
- package/dist/features/operations/index.d.ts +38 -2
- package/dist/features/operations/index.js +32 -31
- package/dist/features/seo/index.js +1 -1
- package/dist/features/settings/index.d.ts +121 -0
- package/dist/features/settings/index.js +25 -24
- package/dist/graph/index.js +1 -1
- package/dist/hooks/delivery/index.d.ts +140 -0
- package/dist/hooks/delivery/index.js +4 -4
- package/dist/hooks/index.d.ts +844 -21
- package/dist/hooks/index.js +21 -21
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +82 -1
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.js +1 -1
- package/dist/hooks/published.d.ts +844 -21
- package/dist/hooks/published.js +21 -21
- package/dist/index.d.ts +1056 -27
- package/dist/index.js +22 -22
- package/dist/initialization/index.d.ts +121 -0
- package/dist/initialization/index.js +5 -5
- package/dist/knowledge/index.d.ts +151 -1
- package/dist/knowledge/index.js +1692 -1039
- package/dist/layout/index.d.ts +6 -0
- package/dist/layout/index.js +4 -4
- package/dist/organization/index.js +5 -5
- package/dist/profile/index.d.ts +121 -0
- package/dist/profile/index.js +3 -3
- package/dist/provider/ElevasisServiceContext.d.ts +11 -5
- package/dist/provider/ElevasisServiceContext.js +2 -2
- package/dist/provider/index.d.ts +337 -7
- package/dist/provider/index.js +18 -18
- package/dist/provider/published.d.ts +337 -7
- package/dist/provider/published.js +14 -14
- package/dist/router/context.js +1 -1
- package/dist/router/index.js +1 -1
- package/dist/sse/index.js +1 -1
- package/dist/supabase/index.d.ts +232 -0
- package/dist/supabase/index.js +1 -1
- package/dist/test-utils/index.d.ts +3 -0
- package/dist/test-utils/index.js +31 -7
- package/dist/test-utils/setup-integration.js +1 -1
- package/dist/test-utils/setup.js +2 -2
- package/dist/theme/index.js +4 -4
- package/dist/theme/presets/index.js +2 -2
- package/dist/typeform/index.js +1 -1
- package/dist/typeform/schemas.js +1 -1
- package/dist/types/index.d.ts +204 -1
- package/dist/utils/index.d.ts +36 -1
- package/dist/utils/index.js +2 -2
- package/dist/vite/index.js +3 -3
- package/dist/vite-plugin-knowledge/index.js +2 -2
- package/dist/zustand/index.js +1 -1
- package/package.json +14 -5
- /package/dist/{chunk-HXZQWMKE.js → chunk-XQHZBA65.js} +0 -0
|
@@ -1,35 +1,36 @@
|
|
|
1
|
-
import { ChatHeader, ChatSidebar } from './chunk-
|
|
2
|
-
import { getOrganizationGraphLensConfig, useOrganizationGraphFilters, createOrganizationGraphFilters, buildOrganizationGraph, filterOrganizationGraph, getCommandViewVisibilityProjection, resolveOrganizationGraphPathTrace, getCommandViewOperationalOverview, getCommandViewSelectionOperationalSummary, buildCommandViewDrillDownSections, expandAroundGraph, getConnectedHiddenResourceIds, FilterPanel, OrganizationGraphDetailPanel, ExpandAroundPanel, CommandViewSidebarContent, getOrganizationGraphTraceNodeOptions, formatOrganizationGraphTraceNodeOptionLabel } from './chunk-
|
|
1
|
+
import { ChatHeader, ChatSidebar } from './chunk-CXY7FMUM.js';
|
|
2
|
+
import { getOrganizationGraphLensConfig, useOrganizationGraphFilters, createOrganizationGraphFilters, buildOrganizationGraph, filterOrganizationGraph, getCommandViewVisibilityProjection, resolveOrganizationGraphPathTrace, getCommandViewOperationalOverview, getCommandViewSelectionOperationalSummary, buildCommandViewDrillDownSections, expandAroundGraph, getConnectedHiddenResourceIds, FilterPanel, OrganizationGraphDetailPanel, ExpandAroundPanel, CommandViewSidebarContent, getOrganizationGraphTraceNodeOptions, formatOrganizationGraphTraceNodeOptionLabel } from './chunk-MVFCLZSK.js';
|
|
3
3
|
import { SubshellLoader } from './chunk-JDNEWB5F.js';
|
|
4
|
-
import { resolveSemanticIconComponent } from './chunk-
|
|
4
|
+
import { resolveSemanticIconComponent } from './chunk-GRDLB6LM.js';
|
|
5
5
|
import { SubshellSidebarLoader } from './chunk-XQQEKWTL.js';
|
|
6
|
-
import { BaseNode, useGraphTheme, BaseEdge, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-
|
|
6
|
+
import { BaseNode, useGraphTheme, BaseEdge, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-Q6OYNEGR.js';
|
|
7
7
|
import { FormFieldRenderer } from './chunk-3MEXPLWT.js';
|
|
8
|
-
import { ResourceHealthPanel } from './chunk-
|
|
8
|
+
import { ResourceHealthPanel } from './chunk-L2NVFLXU.js';
|
|
9
9
|
import { useCyberColors, CyberDonut } from './chunk-CW3UNAF2.js';
|
|
10
|
+
import { ConfirmationModal } from './chunk-VNFR57DF.js';
|
|
11
|
+
import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
|
|
10
12
|
import { AppShellLoader } from './chunk-RYTEQBAO.js';
|
|
11
13
|
import { PageContainer } from './chunk-BZZCNLT6.js';
|
|
12
|
-
import {
|
|
13
|
-
import { CustomModal, ConfirmationModal } from './chunk-KVJ3LFH2.js';
|
|
14
|
+
import { CustomModal } from './chunk-R66W5UDG.js';
|
|
14
15
|
import { useGraphHighlighting, calculateGraphHeight, Graph_module_css_default, GRAPH_CONSTANTS } from './chunk-22UVE3RA.js';
|
|
15
16
|
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-
|
|
17
|
-
import { showApiErrorNotification, showSuccessNotification } from './chunk-
|
|
17
|
+
import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, collectResourceFilterFacets, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, getDefaultParameters, useResourceExecutions, useCheckpointTasks, EXPLORE_OM_ROOT_ID, COMMAND_VIEW_VISUALIZATION_MODES, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, buildCommandViewGraphIndex, getCommandViewClusterZoneLabels, getCommandViewSwimlaneLaneLabels, exploreNodeHasChildren, getNextExpandedSetForToggle, getExploreProjection, getRadialFromAnchorProjection, DOMAIN_ZONE_TINT_COLOR, useBulkDeleteExecutions, getCommandViewNodeDomain, getCommandViewGraphPositions, getExploreFocusSet, DEFAULT_CLUSTER_PARAMETERS, DEFAULT_SWIMLANE_PARAMETERS, DEFAULT_FOCUS_PARAMETERS, DEFAULT_NETWORK_PARAMETERS, DEFAULT_FORCE_PARAMETERS } from './chunk-JKSUN5GN.js';
|
|
18
|
+
import { showApiErrorNotification, showSuccessNotification } from './chunk-7HMCB26R.js';
|
|
18
19
|
import { useMergedExecution } from './chunk-3ZMAGTWF.js';
|
|
19
|
-
import {
|
|
20
|
+
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-6IXOKUBC.js';
|
|
21
|
+
import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-L3BVJWML.js';
|
|
20
22
|
import { StyledMarkdown } from './chunk-3KMDHCAR.js';
|
|
21
|
-
import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-V3HUIZJX.js';
|
|
22
23
|
import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
|
|
23
|
-
import { NavigationButton } from './chunk-NYBEU5TE.js';
|
|
24
24
|
import { useRouterContext } from './chunk-Q7DJKLEN.js';
|
|
25
25
|
import { useAppearance } from './chunk-E565XMTQ.js';
|
|
26
26
|
import { topbarHeight } from './chunk-DT3QYZVU.js';
|
|
27
|
-
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, debounce } from './chunk-
|
|
27
|
+
import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, debounce } from './chunk-XQHZBA65.js';
|
|
28
28
|
import { ResourceStatusColors, toWorkflowLogMessages } from './chunk-KRWALB24.js';
|
|
29
|
-
import { useInitialization } from './chunk-
|
|
29
|
+
import { useInitialization } from './chunk-533DUEQY.js';
|
|
30
30
|
import { useOrganization } from './chunk-DD3CCMCZ.js';
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
31
|
+
import { __require } from './chunk-DZTG5IAC.js';
|
|
32
|
+
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, Popover, Breadcrumbs, Anchor, NumberInput } from '@mantine/core';
|
|
33
|
+
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, IconAdjustments, IconHistory } from '@tabler/icons-react';
|
|
33
34
|
import { useForm } from '@mantine/form';
|
|
34
35
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
35
36
|
import { memo, useState, useMemo, useRef, useCallback, useEffect, useDeferredValue, useEffectEvent } from 'react';
|
|
@@ -3372,6 +3373,52 @@ function CommandQueueDetailPage({
|
|
|
3372
3373
|
] }) })
|
|
3373
3374
|
] });
|
|
3374
3375
|
}
|
|
3376
|
+
var forceLayoutAvailable = false;
|
|
3377
|
+
try {
|
|
3378
|
+
const fcose = __require("cytoscape-fcose");
|
|
3379
|
+
cytoscape.use(fcose.default ?? fcose);
|
|
3380
|
+
forceLayoutAvailable = true;
|
|
3381
|
+
} catch {
|
|
3382
|
+
}
|
|
3383
|
+
function useForceLayoutController(parameters) {
|
|
3384
|
+
const available = forceLayoutAvailable;
|
|
3385
|
+
const runLayout = useCallback(
|
|
3386
|
+
(cy) => {
|
|
3387
|
+
if (!available) return;
|
|
3388
|
+
const p = parameters ?? { nodeRepulsion: 4500, idealEdgeLength: 80, gravity: 0.25 };
|
|
3389
|
+
cy.layout({
|
|
3390
|
+
name: "fcose",
|
|
3391
|
+
animate: true,
|
|
3392
|
+
animationDuration: 600,
|
|
3393
|
+
randomize: false,
|
|
3394
|
+
nodeRepulsion: p.nodeRepulsion,
|
|
3395
|
+
idealEdgeLength: p.idealEdgeLength,
|
|
3396
|
+
gravity: p.gravity,
|
|
3397
|
+
fit: true,
|
|
3398
|
+
padding: 44
|
|
3399
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3400
|
+
}).run();
|
|
3401
|
+
},
|
|
3402
|
+
// parameters is intentionally in the dep array so runLayout re-captures fresh values on every render.
|
|
3403
|
+
[available, parameters]
|
|
3404
|
+
);
|
|
3405
|
+
const alertElement = !available && parameters !== null ? /* @__PURE__ */ jsx(
|
|
3406
|
+
Box,
|
|
3407
|
+
{
|
|
3408
|
+
style: {
|
|
3409
|
+
position: "absolute",
|
|
3410
|
+
inset: 0,
|
|
3411
|
+
zIndex: 10,
|
|
3412
|
+
display: "flex",
|
|
3413
|
+
alignItems: "center",
|
|
3414
|
+
justifyContent: "center",
|
|
3415
|
+
pointerEvents: "none"
|
|
3416
|
+
},
|
|
3417
|
+
children: /* @__PURE__ */ jsx(Alert, { color: "yellow", maw: 420, style: { pointerEvents: "auto" }, children: "Force layout unavailable \u2014 `cytoscape-fcose` is not installed. Pick another mode or install the optional dependency." })
|
|
3418
|
+
}
|
|
3419
|
+
) : null;
|
|
3420
|
+
return { available, runLayout, alertElement };
|
|
3421
|
+
}
|
|
3375
3422
|
var cellStyle = {
|
|
3376
3423
|
padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
|
|
3377
3424
|
display: "flex",
|
|
@@ -3441,6 +3488,449 @@ function CommandViewHealthStrip({
|
|
|
3441
3488
|
] })
|
|
3442
3489
|
] });
|
|
3443
3490
|
}
|
|
3491
|
+
var DOMAIN_LABELS = {
|
|
3492
|
+
operations: "Operations",
|
|
3493
|
+
runtime: "Runtime",
|
|
3494
|
+
business: "Business",
|
|
3495
|
+
delivery: "Delivery",
|
|
3496
|
+
knowledge: "Knowledge",
|
|
3497
|
+
admin: "Admin",
|
|
3498
|
+
system: "System",
|
|
3499
|
+
platform: "Platform",
|
|
3500
|
+
other: "Other"
|
|
3501
|
+
};
|
|
3502
|
+
var DOMAIN_ORDER = [
|
|
3503
|
+
"platform",
|
|
3504
|
+
"operations",
|
|
3505
|
+
"runtime",
|
|
3506
|
+
"business",
|
|
3507
|
+
"delivery",
|
|
3508
|
+
"knowledge",
|
|
3509
|
+
"admin",
|
|
3510
|
+
"system",
|
|
3511
|
+
"other"
|
|
3512
|
+
];
|
|
3513
|
+
function ClusterLegend() {
|
|
3514
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3515
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Domain zones" }),
|
|
3516
|
+
/* @__PURE__ */ jsx(Group, { gap: "xs", wrap: "wrap", children: DOMAIN_ORDER.map((domain) => {
|
|
3517
|
+
const tint = DOMAIN_ZONE_TINT_COLOR[domain] ?? "#868e96";
|
|
3518
|
+
return /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
3519
|
+
/* @__PURE__ */ jsx(
|
|
3520
|
+
Box,
|
|
3521
|
+
{
|
|
3522
|
+
style: {
|
|
3523
|
+
width: 10,
|
|
3524
|
+
height: 10,
|
|
3525
|
+
borderRadius: 2,
|
|
3526
|
+
backgroundColor: tint,
|
|
3527
|
+
opacity: 0.7,
|
|
3528
|
+
flexShrink: 0
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
),
|
|
3532
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: DOMAIN_LABELS[domain] ?? domain })
|
|
3533
|
+
] }, domain);
|
|
3534
|
+
}) })
|
|
3535
|
+
] });
|
|
3536
|
+
}
|
|
3537
|
+
function SwimlaneLegend() {
|
|
3538
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3539
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Domain lanes" }),
|
|
3540
|
+
/* @__PURE__ */ jsx(Stack, { gap: 2, children: DOMAIN_ORDER.map((domain) => {
|
|
3541
|
+
const tint = DOMAIN_ZONE_TINT_COLOR[domain] ?? "#868e96";
|
|
3542
|
+
return /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3543
|
+
/* @__PURE__ */ jsx(
|
|
3544
|
+
Box,
|
|
3545
|
+
{
|
|
3546
|
+
style: {
|
|
3547
|
+
width: 16,
|
|
3548
|
+
height: 2,
|
|
3549
|
+
borderRadius: 1,
|
|
3550
|
+
backgroundColor: tint,
|
|
3551
|
+
opacity: 0.7,
|
|
3552
|
+
flexShrink: 0
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
),
|
|
3556
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: DOMAIN_LABELS[domain] ?? domain })
|
|
3557
|
+
] }, domain);
|
|
3558
|
+
}) })
|
|
3559
|
+
] });
|
|
3560
|
+
}
|
|
3561
|
+
function FocusLegend() {
|
|
3562
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3563
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Focus rings" }),
|
|
3564
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3565
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3566
|
+
/* @__PURE__ */ jsx(
|
|
3567
|
+
Box,
|
|
3568
|
+
{
|
|
3569
|
+
style: {
|
|
3570
|
+
width: 10,
|
|
3571
|
+
height: 10,
|
|
3572
|
+
borderRadius: "50%",
|
|
3573
|
+
border: "2px solid var(--mantine-color-blue-5)",
|
|
3574
|
+
flexShrink: 0
|
|
3575
|
+
}
|
|
3576
|
+
}
|
|
3577
|
+
),
|
|
3578
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Selected node (center)" })
|
|
3579
|
+
] }),
|
|
3580
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3581
|
+
/* @__PURE__ */ jsx(
|
|
3582
|
+
Box,
|
|
3583
|
+
{
|
|
3584
|
+
style: {
|
|
3585
|
+
width: 10,
|
|
3586
|
+
height: 10,
|
|
3587
|
+
borderRadius: "50%",
|
|
3588
|
+
border: "2px solid var(--mantine-color-teal-5)",
|
|
3589
|
+
flexShrink: 0
|
|
3590
|
+
}
|
|
3591
|
+
}
|
|
3592
|
+
),
|
|
3593
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Ring 1 \u2014 direct neighbors" })
|
|
3594
|
+
] }),
|
|
3595
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3596
|
+
/* @__PURE__ */ jsx(
|
|
3597
|
+
Box,
|
|
3598
|
+
{
|
|
3599
|
+
style: {
|
|
3600
|
+
width: 10,
|
|
3601
|
+
height: 10,
|
|
3602
|
+
borderRadius: "50%",
|
|
3603
|
+
border: "2px solid var(--mantine-color-gray-5)",
|
|
3604
|
+
flexShrink: 0
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
),
|
|
3608
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Ring 2 \u2014 second-degree neighbors" })
|
|
3609
|
+
] })
|
|
3610
|
+
] })
|
|
3611
|
+
] });
|
|
3612
|
+
}
|
|
3613
|
+
function NetworkLegend() {
|
|
3614
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3615
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Network layout" }),
|
|
3616
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3617
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3618
|
+
/* @__PURE__ */ jsx(
|
|
3619
|
+
Box,
|
|
3620
|
+
{
|
|
3621
|
+
style: {
|
|
3622
|
+
width: 10,
|
|
3623
|
+
height: 10,
|
|
3624
|
+
borderRadius: "50%",
|
|
3625
|
+
border: "2px solid var(--mantine-color-blue-5)",
|
|
3626
|
+
flexShrink: 0
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
),
|
|
3630
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Highest-degree node (center)" })
|
|
3631
|
+
] }),
|
|
3632
|
+
/* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
|
|
3633
|
+
/* @__PURE__ */ jsx(
|
|
3634
|
+
Box,
|
|
3635
|
+
{
|
|
3636
|
+
style: {
|
|
3637
|
+
width: 24,
|
|
3638
|
+
height: 1,
|
|
3639
|
+
backgroundColor: "var(--mantine-color-gray-5)",
|
|
3640
|
+
flexShrink: 0
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
),
|
|
3644
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Phyllotaxis spiral by degree" })
|
|
3645
|
+
] })
|
|
3646
|
+
] })
|
|
3647
|
+
] });
|
|
3648
|
+
}
|
|
3649
|
+
function ForceLegend() {
|
|
3650
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3651
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Force layout" }),
|
|
3652
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3653
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Physics simulation via cytoscape-fcose. Node positions are non-deterministic and are not persisted across reloads." }),
|
|
3654
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: 'Use the "Re-run layout" button in layout parameters to trigger a fresh simulation with the current force settings.' })
|
|
3655
|
+
] })
|
|
3656
|
+
] });
|
|
3657
|
+
}
|
|
3658
|
+
function ExploreLegend() {
|
|
3659
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3660
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: "dimmed", tt: "uppercase", children: "Multi-level drill-down" }),
|
|
3661
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
3662
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Click any node with children to expand its subgraph; siblings at the same level auto-collapse; click a higher segment in the breadcrumb to collapse downward; Esc collapses all." }),
|
|
3663
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Expansion recurses up to 3 levels deep: zone centroid \u2192 feature \u2192 surface/capability." }),
|
|
3664
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Resource visibility inside expanded zones is controlled by the existing Show/Hide resources toggle." })
|
|
3665
|
+
] })
|
|
3666
|
+
] });
|
|
3667
|
+
}
|
|
3668
|
+
function Legend({ visualizationMode, onDismiss }) {
|
|
3669
|
+
const modeLabel = visualizationMode === "explore" ? "Explore" : visualizationMode === "cluster" ? "Cluster" : visualizationMode === "swimlane" ? "Swimlane" : visualizationMode === "focus" ? "Focus" : visualizationMode === "force" ? "Force" : "Network";
|
|
3670
|
+
return /* @__PURE__ */ jsxs(
|
|
3671
|
+
Box,
|
|
3672
|
+
{
|
|
3673
|
+
style: {
|
|
3674
|
+
background: "var(--glass-background, rgba(11,16,21,0.88))",
|
|
3675
|
+
backdropFilter: "var(--glass-blur, blur(8px))",
|
|
3676
|
+
border: "1px solid var(--color-border)",
|
|
3677
|
+
borderRadius: "var(--mantine-radius-md)",
|
|
3678
|
+
padding: "var(--mantine-spacing-xs)",
|
|
3679
|
+
minWidth: 180,
|
|
3680
|
+
maxWidth: 260
|
|
3681
|
+
},
|
|
3682
|
+
children: [
|
|
3683
|
+
/* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", mb: 6, wrap: "nowrap", children: [
|
|
3684
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", fw: 700, children: [
|
|
3685
|
+
modeLabel,
|
|
3686
|
+
" Legend"
|
|
3687
|
+
] }),
|
|
3688
|
+
/* @__PURE__ */ jsx(Tooltip, { label: "Dismiss legend", children: /* @__PURE__ */ jsx(ActionIcon, { size: "xs", variant: "subtle", onClick: onDismiss, "aria-label": "Dismiss legend", children: /* @__PURE__ */ jsx(IconX, { size: 12 }) }) })
|
|
3689
|
+
] }),
|
|
3690
|
+
visualizationMode === "explore" && /* @__PURE__ */ jsx(ExploreLegend, {}),
|
|
3691
|
+
visualizationMode === "cluster" && /* @__PURE__ */ jsx(ClusterLegend, {}),
|
|
3692
|
+
visualizationMode === "swimlane" && /* @__PURE__ */ jsx(SwimlaneLegend, {}),
|
|
3693
|
+
visualizationMode === "focus" && /* @__PURE__ */ jsx(FocusLegend, {}),
|
|
3694
|
+
visualizationMode === "network" && /* @__PURE__ */ jsx(NetworkLegend, {}),
|
|
3695
|
+
visualizationMode === "force" && /* @__PURE__ */ jsx(ForceLegend, {})
|
|
3696
|
+
]
|
|
3697
|
+
}
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
function ExploreBreadcrumb() {
|
|
3701
|
+
const expandedNodeIds = useCommandViewStore((s) => s.expandedNodeIds);
|
|
3702
|
+
const clearExpandedNodes = useCommandViewStore((s) => s.clearExpandedNodes);
|
|
3703
|
+
if (expandedNodeIds.size === 0) return null;
|
|
3704
|
+
const expandedCount = expandedNodeIds.size;
|
|
3705
|
+
return /* @__PURE__ */ jsxs(Breadcrumbs, { separator: "\u203A", "data-testid": "explore-breadcrumb", children: [
|
|
3706
|
+
/* @__PURE__ */ jsx(Anchor, { onClick: clearExpandedNodes, component: "button", type: "button", children: "OM" }),
|
|
3707
|
+
/* @__PURE__ */ jsx("span", { children: expandedCount === 1 ? Array.from(expandedNodeIds)[0] : `${expandedCount} expanded` })
|
|
3708
|
+
] });
|
|
3709
|
+
}
|
|
3710
|
+
function ClusterControls({ value, onChange }) {
|
|
3711
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3712
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Cluster parameters" }),
|
|
3713
|
+
/* @__PURE__ */ jsx(
|
|
3714
|
+
NumberInput,
|
|
3715
|
+
{
|
|
3716
|
+
label: "Zone padding",
|
|
3717
|
+
description: "Row height within each domain zone",
|
|
3718
|
+
value: value.zonePadding,
|
|
3719
|
+
onChange: (v) => onChange({ ...value, zonePadding: typeof v === "number" ? v : DEFAULT_CLUSTER_PARAMETERS.zonePadding }),
|
|
3720
|
+
min: 40,
|
|
3721
|
+
max: 200,
|
|
3722
|
+
step: 4,
|
|
3723
|
+
size: "xs"
|
|
3724
|
+
}
|
|
3725
|
+
),
|
|
3726
|
+
/* @__PURE__ */ jsx(
|
|
3727
|
+
NumberInput,
|
|
3728
|
+
{
|
|
3729
|
+
label: "Inter-zone gap",
|
|
3730
|
+
description: "Vertical spacing between domain zone tiers",
|
|
3731
|
+
value: value.interZoneGap,
|
|
3732
|
+
onChange: (v) => onChange({ ...value, interZoneGap: typeof v === "number" ? v : DEFAULT_CLUSTER_PARAMETERS.interZoneGap }),
|
|
3733
|
+
min: 100,
|
|
3734
|
+
max: 800,
|
|
3735
|
+
step: 25,
|
|
3736
|
+
size: "xs"
|
|
3737
|
+
}
|
|
3738
|
+
)
|
|
3739
|
+
] });
|
|
3740
|
+
}
|
|
3741
|
+
function FocusControls({ value, onChange }) {
|
|
3742
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3743
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Focus parameters" }),
|
|
3744
|
+
/* @__PURE__ */ jsx(
|
|
3745
|
+
NumberInput,
|
|
3746
|
+
{
|
|
3747
|
+
label: "Depth",
|
|
3748
|
+
description: "Number of relationship rings around the focused node",
|
|
3749
|
+
value: value.depth,
|
|
3750
|
+
onChange: (v) => onChange({ ...value, depth: typeof v === "number" ? v : DEFAULT_FOCUS_PARAMETERS.depth }),
|
|
3751
|
+
min: 1,
|
|
3752
|
+
max: 3,
|
|
3753
|
+
step: 1,
|
|
3754
|
+
size: "xs"
|
|
3755
|
+
}
|
|
3756
|
+
),
|
|
3757
|
+
/* @__PURE__ */ jsx(
|
|
3758
|
+
NumberInput,
|
|
3759
|
+
{
|
|
3760
|
+
label: "Ring radius",
|
|
3761
|
+
description: "Distance of the first-degree ring from the focused node",
|
|
3762
|
+
value: value.radius,
|
|
3763
|
+
onChange: (v) => onChange({ ...value, radius: typeof v === "number" ? v : DEFAULT_FOCUS_PARAMETERS.radius }),
|
|
3764
|
+
min: 150,
|
|
3765
|
+
max: 800,
|
|
3766
|
+
step: 20,
|
|
3767
|
+
size: "xs"
|
|
3768
|
+
}
|
|
3769
|
+
)
|
|
3770
|
+
] });
|
|
3771
|
+
}
|
|
3772
|
+
function ForceControls({ value, onChange, onRerun }) {
|
|
3773
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3774
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Force parameters" }),
|
|
3775
|
+
/* @__PURE__ */ jsx(
|
|
3776
|
+
NumberInput,
|
|
3777
|
+
{
|
|
3778
|
+
label: "Node repulsion",
|
|
3779
|
+
description: "Repulsive force between nodes \u2014 higher spreads nodes further apart",
|
|
3780
|
+
value: value.nodeRepulsion,
|
|
3781
|
+
onChange: (v) => onChange({
|
|
3782
|
+
...value,
|
|
3783
|
+
nodeRepulsion: typeof v === "number" ? v : DEFAULT_FORCE_PARAMETERS.nodeRepulsion
|
|
3784
|
+
}),
|
|
3785
|
+
min: 500,
|
|
3786
|
+
step: 250,
|
|
3787
|
+
size: "xs"
|
|
3788
|
+
}
|
|
3789
|
+
),
|
|
3790
|
+
/* @__PURE__ */ jsx(
|
|
3791
|
+
NumberInput,
|
|
3792
|
+
{
|
|
3793
|
+
label: "Ideal edge length",
|
|
3794
|
+
description: "Target length for edges in the physics simulation",
|
|
3795
|
+
value: value.idealEdgeLength,
|
|
3796
|
+
onChange: (v) => onChange({
|
|
3797
|
+
...value,
|
|
3798
|
+
idealEdgeLength: typeof v === "number" ? v : DEFAULT_FORCE_PARAMETERS.idealEdgeLength
|
|
3799
|
+
}),
|
|
3800
|
+
min: 30,
|
|
3801
|
+
step: 10,
|
|
3802
|
+
size: "xs"
|
|
3803
|
+
}
|
|
3804
|
+
),
|
|
3805
|
+
/* @__PURE__ */ jsx(
|
|
3806
|
+
NumberInput,
|
|
3807
|
+
{
|
|
3808
|
+
label: "Gravity",
|
|
3809
|
+
description: "Attraction toward the center \u2014 prevents disconnected components from flying apart",
|
|
3810
|
+
value: value.gravity,
|
|
3811
|
+
onChange: (v) => onChange({
|
|
3812
|
+
...value,
|
|
3813
|
+
gravity: typeof v === "number" ? v : DEFAULT_FORCE_PARAMETERS.gravity
|
|
3814
|
+
}),
|
|
3815
|
+
min: 0,
|
|
3816
|
+
max: 1,
|
|
3817
|
+
step: 0.05,
|
|
3818
|
+
decimalScale: 2,
|
|
3819
|
+
size: "xs"
|
|
3820
|
+
}
|
|
3821
|
+
),
|
|
3822
|
+
/* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: onRerun, children: "Re-run layout" })
|
|
3823
|
+
] });
|
|
3824
|
+
}
|
|
3825
|
+
function NetworkControls({ value, onChange }) {
|
|
3826
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3827
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Network parameters" }),
|
|
3828
|
+
/* @__PURE__ */ jsx(
|
|
3829
|
+
NumberInput,
|
|
3830
|
+
{
|
|
3831
|
+
label: "Link length",
|
|
3832
|
+
description: "Radial growth factor per node in the spiral layout",
|
|
3833
|
+
value: value.linkLength,
|
|
3834
|
+
onChange: (v) => onChange({ ...value, linkLength: typeof v === "number" ? v : DEFAULT_NETWORK_PARAMETERS.linkLength }),
|
|
3835
|
+
min: 20,
|
|
3836
|
+
max: 250,
|
|
3837
|
+
step: 5,
|
|
3838
|
+
size: "xs"
|
|
3839
|
+
}
|
|
3840
|
+
),
|
|
3841
|
+
/* @__PURE__ */ jsx(
|
|
3842
|
+
NumberInput,
|
|
3843
|
+
{
|
|
3844
|
+
label: "Repulsion",
|
|
3845
|
+
description: "Base radius offset from the graph center",
|
|
3846
|
+
value: value.repulsion,
|
|
3847
|
+
onChange: (v) => onChange({ ...value, repulsion: typeof v === "number" ? v : DEFAULT_NETWORK_PARAMETERS.repulsion }),
|
|
3848
|
+
min: 50,
|
|
3849
|
+
max: 500,
|
|
3850
|
+
step: 10,
|
|
3851
|
+
size: "xs"
|
|
3852
|
+
}
|
|
3853
|
+
)
|
|
3854
|
+
] });
|
|
3855
|
+
}
|
|
3856
|
+
var SORT_KEY_OPTIONS = [
|
|
3857
|
+
{ label: "Kind", value: "kind" },
|
|
3858
|
+
{ label: "Domain", value: "domain" },
|
|
3859
|
+
{ label: "Health", value: "health" }
|
|
3860
|
+
];
|
|
3861
|
+
function SwimlaneControls({ value, onChange }) {
|
|
3862
|
+
return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
3863
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Swimlane parameters" }),
|
|
3864
|
+
/* @__PURE__ */ jsx(
|
|
3865
|
+
NumberInput,
|
|
3866
|
+
{
|
|
3867
|
+
label: "Lane height",
|
|
3868
|
+
description: "Vertical spacing between domain lanes",
|
|
3869
|
+
value: value.laneHeight,
|
|
3870
|
+
onChange: (v) => onChange({ ...value, laneHeight: typeof v === "number" ? v : DEFAULT_SWIMLANE_PARAMETERS.laneHeight }),
|
|
3871
|
+
min: 80,
|
|
3872
|
+
max: 300,
|
|
3873
|
+
step: 10,
|
|
3874
|
+
size: "xs"
|
|
3875
|
+
}
|
|
3876
|
+
),
|
|
3877
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
|
|
3878
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", fw: 500, children: "Sort key" }),
|
|
3879
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Node ordering within each lane" }),
|
|
3880
|
+
/* @__PURE__ */ jsx(
|
|
3881
|
+
SegmentedControl,
|
|
3882
|
+
{
|
|
3883
|
+
value: value.sortKey,
|
|
3884
|
+
onChange: (v) => onChange({ ...value, sortKey: v }),
|
|
3885
|
+
data: SORT_KEY_OPTIONS,
|
|
3886
|
+
size: "xs",
|
|
3887
|
+
fullWidth: true
|
|
3888
|
+
}
|
|
3889
|
+
)
|
|
3890
|
+
] })
|
|
3891
|
+
] });
|
|
3892
|
+
}
|
|
3893
|
+
function VisualizationModeControls({
|
|
3894
|
+
visualizationMode,
|
|
3895
|
+
parameters,
|
|
3896
|
+
onChangeParameters,
|
|
3897
|
+
onRerunForceLayout
|
|
3898
|
+
}) {
|
|
3899
|
+
return /* @__PURE__ */ jsxs(Popover, { width: 240, position: "bottom-end", withArrow: true, shadow: "md", withinPortal: true, children: [
|
|
3900
|
+
/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(Tooltip, { label: "Layout parameters", children: /* @__PURE__ */ jsx(
|
|
3901
|
+
ActionIcon,
|
|
3902
|
+
{
|
|
3903
|
+
variant: "light",
|
|
3904
|
+
radius: "xl",
|
|
3905
|
+
size: "lg",
|
|
3906
|
+
style: {
|
|
3907
|
+
background: "var(--glass-background)",
|
|
3908
|
+
backdropFilter: "var(--glass-blur)",
|
|
3909
|
+
color: "var(--color-text)",
|
|
3910
|
+
flexShrink: 0
|
|
3911
|
+
},
|
|
3912
|
+
"aria-label": "Layout parameters",
|
|
3913
|
+
children: /* @__PURE__ */ jsx(IconAdjustments, { size: 18 })
|
|
3914
|
+
}
|
|
3915
|
+
) }) }),
|
|
3916
|
+
/* @__PURE__ */ jsxs(
|
|
3917
|
+
Popover.Dropdown,
|
|
3918
|
+
{
|
|
3919
|
+
style: {
|
|
3920
|
+
background: "var(--color-surface)",
|
|
3921
|
+
border: "1px solid var(--color-border)"
|
|
3922
|
+
},
|
|
3923
|
+
children: [
|
|
3924
|
+
visualizationMode === "cluster" && parameters.mode === "cluster" && /* @__PURE__ */ jsx(ClusterControls, { value: parameters, onChange: onChangeParameters }),
|
|
3925
|
+
visualizationMode === "swimlane" && parameters.mode === "swimlane" && /* @__PURE__ */ jsx(SwimlaneControls, { value: parameters, onChange: onChangeParameters }),
|
|
3926
|
+
visualizationMode === "focus" && parameters.mode === "focus" && /* @__PURE__ */ jsx(FocusControls, { value: parameters, onChange: onChangeParameters }),
|
|
3927
|
+
visualizationMode === "network" && parameters.mode === "network" && /* @__PURE__ */ jsx(NetworkControls, { value: parameters, onChange: onChangeParameters }),
|
|
3928
|
+
visualizationMode === "force" && parameters.mode === "force" && /* @__PURE__ */ jsx(ForceControls, { value: parameters, onChange: onChangeParameters, onRerun: onRerunForceLayout })
|
|
3929
|
+
]
|
|
3930
|
+
}
|
|
3931
|
+
)
|
|
3932
|
+
] });
|
|
3933
|
+
}
|
|
3444
3934
|
|
|
3445
3935
|
// src/features/operations/organization-graph/commandViewGraphHealth.ts
|
|
3446
3936
|
function toResourceHealth(node, stats) {
|
|
@@ -3697,6 +4187,8 @@ function OrganizationGraphPathTraceControls({
|
|
|
3697
4187
|
] });
|
|
3698
4188
|
}
|
|
3699
4189
|
var HIDE_SCROLLBAR_CLASS_NAME = "hide-scrollbar";
|
|
4190
|
+
var GRAPH_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
4191
|
+
var EXPLORE_EXPANSION_ANIMATION_LIMIT = 28;
|
|
3700
4192
|
var ORGANIZATION_NODE_ID = "organization-model";
|
|
3701
4193
|
var EMPTY_TRACE_SELECTION = {
|
|
3702
4194
|
sourceId: null,
|
|
@@ -3783,6 +4275,13 @@ function withAlpha(color, alpha) {
|
|
|
3783
4275
|
}
|
|
3784
4276
|
return toRgbaString({ ...parsed, a: alpha });
|
|
3785
4277
|
}
|
|
4278
|
+
function shouldReduceGraphMotion() {
|
|
4279
|
+
return typeof window !== "undefined" && window.matchMedia(GRAPH_MOTION_QUERY).matches;
|
|
4280
|
+
}
|
|
4281
|
+
function getGraphPixelRatio() {
|
|
4282
|
+
if (typeof window === "undefined") return "auto";
|
|
4283
|
+
return window.devicePixelRatio > 1.5 ? 1.25 : "auto";
|
|
4284
|
+
}
|
|
3786
4285
|
function getRelativeLuminance(color) {
|
|
3787
4286
|
const parsed = parseColor(color);
|
|
3788
4287
|
if (!parsed) {
|
|
@@ -3832,8 +4331,8 @@ function getNodeThemeByKind(tokens) {
|
|
|
3832
4331
|
};
|
|
3833
4332
|
return Object.fromEntries(
|
|
3834
4333
|
Object.entries(accentByKind).map(([kind, accent]) => {
|
|
3835
|
-
const background = mixColors(accent, tokens.surface === "transparent" ? tokens.background : tokens.surface, 0.
|
|
3836
|
-
const border = mixColors(accent, tokens.border, 0.
|
|
4334
|
+
const background = mixColors(accent, tokens.surface === "transparent" ? tokens.background : tokens.surface, 0.18);
|
|
4335
|
+
const border = mixColors(accent, tokens.border, 0.5);
|
|
3837
4336
|
return [
|
|
3838
4337
|
kind,
|
|
3839
4338
|
{
|
|
@@ -3861,6 +4360,22 @@ function getEdgeColor(edge, tokens) {
|
|
|
3861
4360
|
return mixColors(tokens.primary, tokens.success, 0.32);
|
|
3862
4361
|
}
|
|
3863
4362
|
}
|
|
4363
|
+
function getNodeHaloColor(node, fallback) {
|
|
4364
|
+
const domain = getCommandViewNodeDomain(node);
|
|
4365
|
+
return DOMAIN_ZONE_TINT_COLOR[domain] ?? fallback;
|
|
4366
|
+
}
|
|
4367
|
+
function getExploreEdgeColor(sourceId, targetId, nodeById, tokens) {
|
|
4368
|
+
if (sourceId.startsWith("centroid:")) {
|
|
4369
|
+
const zone = sourceId.slice("centroid:".length);
|
|
4370
|
+
return mixColors(DOMAIN_ZONE_TINT_COLOR[zone] ?? tokens.primary, tokens.textDimmed, 0.46);
|
|
4371
|
+
}
|
|
4372
|
+
const sourceNode = nodeById.get(sourceId);
|
|
4373
|
+
const targetNode = nodeById.get(targetId);
|
|
4374
|
+
const sourceTint = sourceNode ? getNodeHaloColor(sourceNode, tokens.primary) : null;
|
|
4375
|
+
const targetTint = targetNode ? getNodeHaloColor(targetNode, tokens.primary) : null;
|
|
4376
|
+
const tint = sourceTint ?? targetTint ?? tokens.primary;
|
|
4377
|
+
return mixColors(tint, tokens.textDimmed, 0.42);
|
|
4378
|
+
}
|
|
3864
4379
|
function getNodeSize(kind) {
|
|
3865
4380
|
if (kind === "organization") {
|
|
3866
4381
|
return { width: 230, height: 88 };
|
|
@@ -3870,9 +4385,21 @@ function getNodeSize(kind) {
|
|
|
3870
4385
|
}
|
|
3871
4386
|
return { width: 174, height: 66 };
|
|
3872
4387
|
}
|
|
3873
|
-
function
|
|
3874
|
-
const
|
|
3875
|
-
|
|
4388
|
+
function getDegreeWeightedSize(kind, degree) {
|
|
4389
|
+
const base = getNodeSize(kind);
|
|
4390
|
+
if (kind === "organization") {
|
|
4391
|
+
return base;
|
|
4392
|
+
}
|
|
4393
|
+
const minScale = 0.75;
|
|
4394
|
+
const maxScale = 1.55;
|
|
4395
|
+
const scale = Math.min(maxScale, minScale + degree / 8 * (maxScale - minScale));
|
|
4396
|
+
return {
|
|
4397
|
+
width: Math.round(base.width * scale),
|
|
4398
|
+
height: Math.round(base.height * scale)
|
|
4399
|
+
};
|
|
4400
|
+
}
|
|
4401
|
+
function getNodeScore(node, degreeByNodeId) {
|
|
4402
|
+
return Math.max(1, degreeByNodeId.get(node.id) ?? 0);
|
|
3876
4403
|
}
|
|
3877
4404
|
function getCommandViewRingColor(level, tokens) {
|
|
3878
4405
|
switch (level) {
|
|
@@ -3887,39 +4414,254 @@ function getCommandViewRingColor(level, tokens) {
|
|
|
3887
4414
|
return mixColors(tokens.textDimmed, tokens.border, 0.6);
|
|
3888
4415
|
}
|
|
3889
4416
|
}
|
|
3890
|
-
function
|
|
4417
|
+
function getDomainCardPosition(domain) {
|
|
4418
|
+
const zoneOrigins = {
|
|
4419
|
+
operations: { x: -520, y: -270 },
|
|
4420
|
+
runtime: { x: 130, y: -270 },
|
|
4421
|
+
business: { x: -520, y: 95 },
|
|
4422
|
+
delivery: { x: 130, y: 95 },
|
|
4423
|
+
knowledge: { x: 0, y: 605 },
|
|
4424
|
+
admin: { x: -520, y: 420 },
|
|
4425
|
+
system: { x: 130, y: 420 },
|
|
4426
|
+
platform: { x: 0, y: -520 },
|
|
4427
|
+
other: { x: 0, y: 800 }
|
|
4428
|
+
};
|
|
4429
|
+
return zoneOrigins[domain] ?? { x: 0, y: 0 };
|
|
4430
|
+
}
|
|
4431
|
+
var DOMAIN_DISPLAY_LABELS = {
|
|
4432
|
+
operations: "Operations",
|
|
4433
|
+
runtime: "Runtime",
|
|
4434
|
+
business: "Business",
|
|
4435
|
+
delivery: "Delivery",
|
|
4436
|
+
knowledge: "Knowledge",
|
|
4437
|
+
admin: "Admin",
|
|
4438
|
+
system: "System",
|
|
4439
|
+
platform: "Platform",
|
|
4440
|
+
other: "Other"
|
|
4441
|
+
};
|
|
4442
|
+
function toCytoscapeElementsWithHealth(graph, graphIndex, tokens, commandViewHealthByNodeId, visualizationMode, selectedElement, expandedClusterDomains, parameters, expandedNodeIds) {
|
|
3891
4443
|
const nodeThemeByKind = getNodeThemeByKind(tokens);
|
|
4444
|
+
if (visualizationMode === "explore") {
|
|
4445
|
+
const { syntheticNodes, backboneEdges, positions } = getExploreProjection();
|
|
4446
|
+
const elements = [];
|
|
4447
|
+
for (const sNode of syntheticNodes) {
|
|
4448
|
+
const isOmRoot = sNode.isOmRoot === true;
|
|
4449
|
+
const fillColor = sNode.zoneTint ? mixColors(withAlpha(sNode.zoneTint, 0.22), tokens.background, 0.22) : mixColors(tokens.primary, tokens.surface === "transparent" ? tokens.background : tokens.surface, 0.18);
|
|
4450
|
+
const borderColor = sNode.zoneTint ? mixColors(sNode.zoneTint, tokens.border, 0.48) : mixColors(tokens.primary, tokens.border, 0.52);
|
|
4451
|
+
const haloColor = sNode.zoneTint ?? tokens.primary;
|
|
4452
|
+
elements.push({
|
|
4453
|
+
data: {
|
|
4454
|
+
id: sNode.id,
|
|
4455
|
+
kind: isOmRoot ? "organization" : "centroid",
|
|
4456
|
+
label: sNode.label,
|
|
4457
|
+
isCentroid: sNode.isCentroid,
|
|
4458
|
+
domainZone: sNode.domainZone ?? void 0,
|
|
4459
|
+
zoneTint: sNode.zoneTint ?? void 0,
|
|
4460
|
+
fillColor,
|
|
4461
|
+
borderColor,
|
|
4462
|
+
textColor: tokens.text,
|
|
4463
|
+
haloColor,
|
|
4464
|
+
edgeHaloColor: withAlpha(haloColor, 0.1),
|
|
4465
|
+
hasChildren: isOmRoot ? "false" : "true",
|
|
4466
|
+
width: isOmRoot ? 100 : 140,
|
|
4467
|
+
height: isOmRoot ? 100 : 140
|
|
4468
|
+
},
|
|
4469
|
+
position: positions.get(sNode.id)
|
|
4470
|
+
});
|
|
4471
|
+
}
|
|
4472
|
+
for (const edge of backboneEdges) {
|
|
4473
|
+
elements.push({
|
|
4474
|
+
data: {
|
|
4475
|
+
id: `backbone:${edge.source}:${edge.target}`,
|
|
4476
|
+
source: edge.source,
|
|
4477
|
+
target: edge.target,
|
|
4478
|
+
kind: "contains",
|
|
4479
|
+
label: "",
|
|
4480
|
+
strokeColor: mixColors(tokens.border, tokens.textDimmed, 0.45),
|
|
4481
|
+
edgeHaloColor: withAlpha(tokens.primary, 0.05),
|
|
4482
|
+
isExploreBackbone: "true"
|
|
4483
|
+
}
|
|
4484
|
+
});
|
|
4485
|
+
}
|
|
4486
|
+
if (expandedNodeIds && expandedNodeIds.size > 0) {
|
|
4487
|
+
const addedRealNodeIds = /* @__PURE__ */ new Set();
|
|
4488
|
+
const addedExpansionEdgeIds = /* @__PURE__ */ new Set();
|
|
4489
|
+
for (const nodeId of expandedNodeIds) {
|
|
4490
|
+
const anchorPos = positions.get(nodeId) ?? { x: 0, y: 0 };
|
|
4491
|
+
const level = nodeId.startsWith("centroid:") ? 1 : 2;
|
|
4492
|
+
const childPositions = getRadialFromAnchorProjection(graph, nodeId, anchorPos, level, graphIndex);
|
|
4493
|
+
for (const [childId, childPos] of childPositions) {
|
|
4494
|
+
positions.set(childId, childPos);
|
|
4495
|
+
if (addedRealNodeIds.has(childId)) {
|
|
4496
|
+
const edgeId2 = `expand:${nodeId}:${childId}`;
|
|
4497
|
+
if (!addedExpansionEdgeIds.has(edgeId2)) {
|
|
4498
|
+
addedExpansionEdgeIds.add(edgeId2);
|
|
4499
|
+
const strokeColor = getExploreEdgeColor(nodeId, childId, graphIndex.nodeById, tokens);
|
|
4500
|
+
elements.push({
|
|
4501
|
+
data: {
|
|
4502
|
+
id: edgeId2,
|
|
4503
|
+
source: nodeId,
|
|
4504
|
+
target: childId,
|
|
4505
|
+
kind: "contains",
|
|
4506
|
+
label: "",
|
|
4507
|
+
strokeColor,
|
|
4508
|
+
edgeHaloColor: withAlpha(strokeColor, 0.08),
|
|
4509
|
+
isExploreExpansion: "true",
|
|
4510
|
+
exploreDepth: String(level)
|
|
4511
|
+
}
|
|
4512
|
+
});
|
|
4513
|
+
}
|
|
4514
|
+
continue;
|
|
4515
|
+
}
|
|
4516
|
+
const node = graphIndex.nodeById.get(childId);
|
|
4517
|
+
if (!node) continue;
|
|
4518
|
+
addedRealNodeIds.add(childId);
|
|
4519
|
+
const degree = getNodeScore(node, graphIndex.degreeByNodeId);
|
|
4520
|
+
const size = getDegreeWeightedSize(node.kind, degree);
|
|
4521
|
+
const theme = nodeThemeByKind[node.kind];
|
|
4522
|
+
const health = commandViewHealthByNodeId?.get(node.id) ?? null;
|
|
4523
|
+
const fillColor = health && node.kind === "resource" ? mixColors(tokens.surfaceHover, tokens.background, 0.76) : theme.background;
|
|
4524
|
+
const borderColor = health ? getCommandViewRingColor(health.healthLevel, tokens) : theme.border;
|
|
4525
|
+
const label = truncateGraphLabel(node.label, node.kind === "resource" ? 22 : 30);
|
|
4526
|
+
const displayLabel = health ? `${label}
|
|
4527
|
+
${health.summaryLabel}` : label;
|
|
4528
|
+
const nodeDomain = getCommandViewNodeDomain(node);
|
|
4529
|
+
const zoneTint = DOMAIN_ZONE_TINT_COLOR[nodeDomain] ?? null;
|
|
4530
|
+
const haloColor = health ? borderColor : zoneTint ?? theme.border;
|
|
4531
|
+
elements.push({
|
|
4532
|
+
data: {
|
|
4533
|
+
...node,
|
|
4534
|
+
width: size.width,
|
|
4535
|
+
height: size.height,
|
|
4536
|
+
score: degree,
|
|
4537
|
+
label: displayLabel,
|
|
4538
|
+
fillColor,
|
|
4539
|
+
borderColor,
|
|
4540
|
+
textColor: health ? tokens.text : theme.color,
|
|
4541
|
+
zoneTint: zoneTint ?? void 0,
|
|
4542
|
+
haloColor,
|
|
4543
|
+
edgeHaloColor: withAlpha(haloColor, 0.08),
|
|
4544
|
+
hasChildren: exploreNodeHasChildren(graph, node.id, graphIndex) ? "true" : "false"
|
|
4545
|
+
},
|
|
4546
|
+
position: childPos
|
|
4547
|
+
});
|
|
4548
|
+
const edgeId = `expand:${nodeId}:${childId}`;
|
|
4549
|
+
if (!addedExpansionEdgeIds.has(edgeId)) {
|
|
4550
|
+
addedExpansionEdgeIds.add(edgeId);
|
|
4551
|
+
const strokeColor = getExploreEdgeColor(nodeId, childId, graphIndex.nodeById, tokens);
|
|
4552
|
+
elements.push({
|
|
4553
|
+
data: {
|
|
4554
|
+
id: edgeId,
|
|
4555
|
+
source: nodeId,
|
|
4556
|
+
target: childId,
|
|
4557
|
+
kind: "contains",
|
|
4558
|
+
label: "",
|
|
4559
|
+
strokeColor,
|
|
4560
|
+
edgeHaloColor: withAlpha(strokeColor, 0.08),
|
|
4561
|
+
isExploreExpansion: "true",
|
|
4562
|
+
exploreDepth: String(level)
|
|
4563
|
+
}
|
|
4564
|
+
});
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
}
|
|
4569
|
+
return elements;
|
|
4570
|
+
}
|
|
3892
4571
|
const presetPositions = getCommandViewGraphPositions({
|
|
3893
4572
|
graph,
|
|
3894
4573
|
visualizationMode,
|
|
3895
|
-
selectedNodeId: selectedElement?.type === "node" ? selectedElement.id : null
|
|
4574
|
+
selectedNodeId: selectedElement?.type === "node" ? selectedElement.id : null,
|
|
4575
|
+
parameters
|
|
3896
4576
|
});
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
4577
|
+
const isCluster = visualizationMode === "cluster";
|
|
4578
|
+
const expandedSet = new Set(expandedClusterDomains);
|
|
4579
|
+
const domainGroups = isCluster ? graph.nodes.reduce((acc, node) => {
|
|
4580
|
+
const domain = getCommandViewNodeDomain(node);
|
|
4581
|
+
const existing = acc.get(domain);
|
|
4582
|
+
if (existing) {
|
|
4583
|
+
existing.push(node);
|
|
4584
|
+
} else {
|
|
4585
|
+
acc.set(domain, [node]);
|
|
4586
|
+
}
|
|
4587
|
+
return acc;
|
|
4588
|
+
}, /* @__PURE__ */ new Map()) : null;
|
|
4589
|
+
const hiddenBehindCardIds = /* @__PURE__ */ new Set();
|
|
4590
|
+
if (isCluster && domainGroups) {
|
|
4591
|
+
for (const [domain, members] of domainGroups) {
|
|
4592
|
+
if (!expandedSet.has(domain)) {
|
|
4593
|
+
for (const member of members) {
|
|
4594
|
+
hiddenBehindCardIds.add(member.id);
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
const domainCardElements = [];
|
|
4600
|
+
if (isCluster && domainGroups) {
|
|
4601
|
+
const cardBackground = withAlpha(tokens.surface === "transparent" ? tokens.background : tokens.surface, 0.92);
|
|
4602
|
+
const cardBorder = mixColors(tokens.border, tokens.textDimmed, 0.35);
|
|
4603
|
+
const cardText = tokens.textDimmed;
|
|
4604
|
+
for (const [domain, members] of domainGroups) {
|
|
4605
|
+
if (!expandedSet.has(domain)) {
|
|
4606
|
+
const position = getDomainCardPosition(domain);
|
|
4607
|
+
const displayName = DOMAIN_DISPLAY_LABELS[domain] ?? domain;
|
|
4608
|
+
domainCardElements.push({
|
|
4609
|
+
data: {
|
|
4610
|
+
id: `domain-card:${domain}`,
|
|
4611
|
+
kind: "domain-card",
|
|
4612
|
+
label: `${displayName}
|
|
4613
|
+
${members.length} node${members.length === 1 ? "" : "s"}`,
|
|
4614
|
+
domain,
|
|
4615
|
+
count: members.length,
|
|
4616
|
+
fillColor: cardBackground,
|
|
4617
|
+
borderColor: cardBorder,
|
|
4618
|
+
textColor: cardText,
|
|
4619
|
+
haloColor: cardBorder,
|
|
4620
|
+
edgeHaloColor: withAlpha(cardBorder, 0.06),
|
|
4621
|
+
hasChildren: "true",
|
|
4622
|
+
width: 200,
|
|
4623
|
+
height: 88
|
|
4624
|
+
},
|
|
4625
|
+
position
|
|
4626
|
+
});
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
const memberElements = graph.nodes.filter((node) => !hiddenBehindCardIds.has(node.id)).map((node) => {
|
|
4631
|
+
const degree = getNodeScore(node, graphIndex.degreeByNodeId);
|
|
4632
|
+
const size = getDegreeWeightedSize(node.kind, degree);
|
|
4633
|
+
const theme = nodeThemeByKind[node.kind];
|
|
4634
|
+
const health = commandViewHealthByNodeId?.get(node.id) ?? null;
|
|
4635
|
+
const fillColor = health && node.kind === "resource" ? mixColors(tokens.surfaceHover, tokens.background, 0.76) : theme.background;
|
|
4636
|
+
const borderColor = health ? getCommandViewRingColor(health.healthLevel, tokens) : theme.border;
|
|
4637
|
+
const maxLabelLength = node.kind === "resource" ? 22 : 30;
|
|
4638
|
+
const label = truncateGraphLabel(node.label, maxLabelLength);
|
|
4639
|
+
const displayLabel = health ? `${label}
|
|
3907
4640
|
${health.summaryLabel}` : label;
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
4641
|
+
const nodeDomain = getCommandViewNodeDomain(node);
|
|
4642
|
+
const zoneTint = DOMAIN_ZONE_TINT_COLOR[nodeDomain] ?? null;
|
|
4643
|
+
const haloColor = health ? borderColor : zoneTint ?? theme.border;
|
|
4644
|
+
return {
|
|
4645
|
+
data: {
|
|
4646
|
+
...node,
|
|
4647
|
+
width: size.width,
|
|
4648
|
+
height: size.height,
|
|
4649
|
+
score: degree,
|
|
4650
|
+
label: displayLabel,
|
|
4651
|
+
fillColor,
|
|
4652
|
+
borderColor,
|
|
4653
|
+
textColor: health ? tokens.text : theme.color,
|
|
4654
|
+
zoneTint: zoneTint ?? void 0,
|
|
4655
|
+
haloColor,
|
|
4656
|
+
edgeHaloColor: withAlpha(haloColor, 0.08),
|
|
4657
|
+
hasChildren: exploreNodeHasChildren(graph, node.id, graphIndex) ? "true" : "false"
|
|
4658
|
+
},
|
|
4659
|
+
position: presetPositions.get(node.id)
|
|
4660
|
+
};
|
|
4661
|
+
});
|
|
4662
|
+
const edgeElements = graph.edges.filter((edge) => !hiddenBehindCardIds.has(edge.sourceId) && !hiddenBehindCardIds.has(edge.targetId)).map((edge) => {
|
|
4663
|
+
const strokeColor = getEdgeColor(edge, tokens);
|
|
4664
|
+
return {
|
|
3923
4665
|
data: {
|
|
3924
4666
|
id: edge.id,
|
|
3925
4667
|
source: edge.sourceId,
|
|
@@ -3927,12 +4669,15 @@ ${health.summaryLabel}` : label;
|
|
|
3927
4669
|
kind: edge.kind,
|
|
3928
4670
|
label: edge.label ?? edge.relationshipType ?? edge.kind.replace(/_/g, " "),
|
|
3929
4671
|
relationshipType: edge.relationshipType,
|
|
3930
|
-
strokeColor
|
|
4672
|
+
strokeColor,
|
|
4673
|
+
edgeHaloColor: withAlpha(strokeColor, 0.08)
|
|
3931
4674
|
}
|
|
3932
|
-
}
|
|
3933
|
-
|
|
4675
|
+
};
|
|
4676
|
+
});
|
|
4677
|
+
return [...domainCardElements, ...memberElements, ...edgeElements];
|
|
3934
4678
|
}
|
|
3935
4679
|
function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
4680
|
+
const reducedMotion = shouldReduceGraphMotion();
|
|
3936
4681
|
const selectedNodeId = selectedElement?.type === "node" ? selectedElement.id : void 0;
|
|
3937
4682
|
const traceRootId = traceResult?.source?.id;
|
|
3938
4683
|
const impactRootId = selectedNodeId ?? traceResult?.target?.id ?? traceRootId ?? ORGANIZATION_NODE_ID;
|
|
@@ -3941,8 +4686,8 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
3941
4686
|
return {
|
|
3942
4687
|
name: "concentric",
|
|
3943
4688
|
fit: true,
|
|
3944
|
-
animate:
|
|
3945
|
-
animationDuration: 220,
|
|
4689
|
+
animate: !reducedMotion,
|
|
4690
|
+
animationDuration: reducedMotion ? 0 : 220,
|
|
3946
4691
|
padding: 48,
|
|
3947
4692
|
spacingFactor: 1,
|
|
3948
4693
|
concentric: (node) => {
|
|
@@ -3958,8 +4703,8 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
3958
4703
|
return {
|
|
3959
4704
|
name: "breadthfirst",
|
|
3960
4705
|
fit: true,
|
|
3961
|
-
animate:
|
|
3962
|
-
animationDuration: 220,
|
|
4706
|
+
animate: !reducedMotion,
|
|
4707
|
+
animationDuration: reducedMotion ? 0 : 220,
|
|
3963
4708
|
directed: true,
|
|
3964
4709
|
circle: false,
|
|
3965
4710
|
spacingFactor: 1.08,
|
|
@@ -3974,10 +4719,12 @@ function getLayoutOptions(mode, selectedElement, traceResult) {
|
|
|
3974
4719
|
padding: 48
|
|
3975
4720
|
};
|
|
3976
4721
|
}
|
|
3977
|
-
function createCytoscapeStyle(tokens) {
|
|
3978
|
-
const selectedBorder = mixColors(tokens.
|
|
3979
|
-
const traceBorder = mixColors(tokens.warning, tokens.
|
|
3980
|
-
const edgeLabelBackground = withAlpha(tokens.background, 0.
|
|
4722
|
+
function createCytoscapeStyle(tokens, visualizationMode) {
|
|
4723
|
+
const selectedBorder = mixColors(tokens.primary, tokens.textDimmed, 0.58);
|
|
4724
|
+
const traceBorder = mixColors(tokens.warning, tokens.border, 0.58);
|
|
4725
|
+
const edgeLabelBackground = withAlpha(tokens.background, 0.86);
|
|
4726
|
+
const reducedMotion = shouldReduceGraphMotion();
|
|
4727
|
+
const baseEdgeOpacity = visualizationMode === "cluster" || visualizationMode === "swimlane" ? 0.16 : visualizationMode === "focus" ? 0.42 : 0.28;
|
|
3981
4728
|
return [
|
|
3982
4729
|
{
|
|
3983
4730
|
selector: "node",
|
|
@@ -3987,60 +4734,238 @@ function createCytoscapeStyle(tokens) {
|
|
|
3987
4734
|
width: "data(width)",
|
|
3988
4735
|
height: "data(height)",
|
|
3989
4736
|
"background-color": "data(fillColor)",
|
|
3990
|
-
"
|
|
4737
|
+
"background-opacity": 0.86,
|
|
4738
|
+
"border-width": 1.4,
|
|
3991
4739
|
"border-style": "solid",
|
|
3992
4740
|
"border-color": "data(borderColor)",
|
|
3993
4741
|
color: "data(textColor)",
|
|
3994
|
-
"font-size":
|
|
3995
|
-
"font-weight":
|
|
4742
|
+
"font-size": 9.5,
|
|
4743
|
+
"font-weight": 650,
|
|
3996
4744
|
"text-wrap": "wrap",
|
|
3997
4745
|
"text-max-width": "120px",
|
|
3998
4746
|
"text-valign": "center",
|
|
3999
4747
|
"text-halign": "center",
|
|
4000
4748
|
padding: "10px",
|
|
4001
4749
|
"overlay-opacity": 0,
|
|
4002
|
-
"text-outline-width":
|
|
4750
|
+
"text-outline-width": 1,
|
|
4751
|
+
"text-outline-color": tokens.background,
|
|
4752
|
+
"text-outline-opacity": 0.56,
|
|
4753
|
+
"underlay-color": "data(haloColor)",
|
|
4754
|
+
"underlay-opacity": 0,
|
|
4755
|
+
"underlay-padding": 7,
|
|
4756
|
+
"underlay-shape": "ellipse",
|
|
4757
|
+
"outline-width": 0,
|
|
4758
|
+
"transition-property": "opacity, border-color, border-width, background-opacity, underlay-opacity, underlay-padding, outline-opacity",
|
|
4759
|
+
"transition-duration": reducedMotion ? 0 : 90,
|
|
4760
|
+
"transition-timing-function": "ease-out-cubic",
|
|
4761
|
+
"z-index-compare": "manual",
|
|
4762
|
+
"z-index": 2
|
|
4003
4763
|
}
|
|
4004
4764
|
},
|
|
4005
4765
|
{
|
|
4766
|
+
// OD-9: organization node — largest ellipse, anchors the graph.
|
|
4006
4767
|
selector: 'node[kind = "organization"]',
|
|
4007
4768
|
style: {
|
|
4008
|
-
shape: "
|
|
4009
|
-
|
|
4010
|
-
|
|
4769
|
+
shape: "ellipse",
|
|
4770
|
+
width: 100,
|
|
4771
|
+
height: 100,
|
|
4772
|
+
"border-width": 2.4,
|
|
4773
|
+
"font-size": 13.5,
|
|
4774
|
+
"font-weight": 800,
|
|
4775
|
+
"text-valign": "center",
|
|
4776
|
+
"text-halign": "center",
|
|
4777
|
+
"text-max-width": "100px",
|
|
4778
|
+
"min-zoomed-font-size": 12
|
|
4011
4779
|
}
|
|
4012
4780
|
},
|
|
4013
4781
|
{
|
|
4014
|
-
|
|
4782
|
+
// OD-9: feature nodes — large ellipse.
|
|
4783
|
+
selector: 'node[kind = "feature"]',
|
|
4015
4784
|
style: {
|
|
4016
|
-
"
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
"
|
|
4020
|
-
"
|
|
4021
|
-
"
|
|
4785
|
+
shape: "ellipse",
|
|
4786
|
+
width: 80,
|
|
4787
|
+
height: 80,
|
|
4788
|
+
"font-size": 12.5,
|
|
4789
|
+
"font-weight": 700,
|
|
4790
|
+
"text-valign": "center",
|
|
4791
|
+
"text-halign": "center",
|
|
4792
|
+
"text-max-width": "100px",
|
|
4793
|
+
"min-zoomed-font-size": 11
|
|
4022
4794
|
}
|
|
4023
4795
|
},
|
|
4024
4796
|
{
|
|
4025
|
-
|
|
4797
|
+
// OD-9: surface and capability nodes — medium ellipse.
|
|
4798
|
+
selector: 'node[kind = "surface"], node[kind = "capability"]',
|
|
4026
4799
|
style: {
|
|
4027
|
-
|
|
4028
|
-
|
|
4800
|
+
shape: "ellipse",
|
|
4801
|
+
width: 70,
|
|
4802
|
+
height: 70,
|
|
4803
|
+
"font-size": 12,
|
|
4804
|
+
"font-weight": 700,
|
|
4805
|
+
"text-valign": "center",
|
|
4806
|
+
"text-halign": "center",
|
|
4807
|
+
"text-max-width": "100px",
|
|
4808
|
+
"min-zoomed-font-size": 11
|
|
4809
|
+
}
|
|
4810
|
+
},
|
|
4811
|
+
{
|
|
4812
|
+
// OD-9: entity, stage, knowledge nodes — compact ellipse.
|
|
4813
|
+
selector: 'node[kind = "entity"], node[kind = "stage"], node[kind = "knowledge"]',
|
|
4814
|
+
style: {
|
|
4815
|
+
shape: "ellipse",
|
|
4816
|
+
width: 65,
|
|
4817
|
+
height: 65,
|
|
4818
|
+
"font-size": 11.5,
|
|
4819
|
+
"font-weight": 600,
|
|
4820
|
+
"text-valign": "center",
|
|
4821
|
+
"text-halign": "center",
|
|
4822
|
+
"text-max-width": "100px",
|
|
4823
|
+
"min-zoomed-font-size": 11
|
|
4824
|
+
}
|
|
4825
|
+
},
|
|
4826
|
+
{
|
|
4827
|
+
// OD-9: resource nodes — smallest ellipse (kept from polish slice).
|
|
4828
|
+
selector: 'node[kind = "resource"]',
|
|
4829
|
+
style: {
|
|
4830
|
+
shape: "ellipse",
|
|
4831
|
+
width: 60,
|
|
4832
|
+
height: 60,
|
|
4833
|
+
"border-width": 1.2,
|
|
4834
|
+
"font-size": 11,
|
|
4835
|
+
"font-weight": 600,
|
|
4836
|
+
"text-valign": "center",
|
|
4837
|
+
"text-halign": "center",
|
|
4838
|
+
"text-max-width": "100px",
|
|
4839
|
+
"background-opacity": 0.82,
|
|
4840
|
+
"min-zoomed-font-size": 11
|
|
4841
|
+
}
|
|
4842
|
+
},
|
|
4843
|
+
{
|
|
4844
|
+
// OD-10: zone-tinted node fills — any node with a zoneTint data attribute gets a tinted background.
|
|
4845
|
+
selector: "node[zoneTint]",
|
|
4846
|
+
style: {
|
|
4847
|
+
"background-color": "data(fillColor)",
|
|
4848
|
+
"background-opacity": 0.82,
|
|
4849
|
+
"border-color": "data(borderColor)",
|
|
4850
|
+
"underlay-color": "data(haloColor)",
|
|
4851
|
+
"underlay-opacity": 0,
|
|
4852
|
+
"underlay-padding": 6
|
|
4853
|
+
}
|
|
4854
|
+
},
|
|
4855
|
+
{
|
|
4856
|
+
// Explore centroids — larger circles with bolder labels so they read as zone anchors.
|
|
4857
|
+
selector: 'node[isCentroid = "true"]',
|
|
4858
|
+
style: {
|
|
4859
|
+
shape: "ellipse",
|
|
4860
|
+
width: 140,
|
|
4861
|
+
height: 140,
|
|
4862
|
+
"background-opacity": 0.76,
|
|
4863
|
+
"border-width": 1.8,
|
|
4864
|
+
"border-opacity": 0.9,
|
|
4865
|
+
"outline-width": 1,
|
|
4866
|
+
"outline-color": "data(haloColor)",
|
|
4867
|
+
"outline-opacity": 0.08,
|
|
4868
|
+
"outline-offset": 4,
|
|
4869
|
+
"underlay-opacity": 0.025,
|
|
4870
|
+
"underlay-padding": 9,
|
|
4871
|
+
"font-size": 14,
|
|
4872
|
+
"font-weight": 700,
|
|
4873
|
+
"text-valign": "center",
|
|
4874
|
+
"text-halign": "center",
|
|
4875
|
+
"text-max-width": "120px",
|
|
4876
|
+
"min-zoomed-font-size": 13
|
|
4877
|
+
}
|
|
4878
|
+
},
|
|
4879
|
+
{
|
|
4880
|
+
selector: 'node[hasChildren = "true"]',
|
|
4881
|
+
style: {
|
|
4882
|
+
"outline-width": 1,
|
|
4883
|
+
"outline-style": "solid",
|
|
4884
|
+
"outline-color": "data(haloColor)",
|
|
4885
|
+
"outline-opacity": 0.07,
|
|
4886
|
+
"outline-offset": 3
|
|
4887
|
+
}
|
|
4888
|
+
},
|
|
4889
|
+
{
|
|
4890
|
+
// Domain-card virtual nodes: rounded rect, muted background, crisp border.
|
|
4891
|
+
selector: 'node[kind = "domain-card"]',
|
|
4892
|
+
style: {
|
|
4893
|
+
shape: "round-rectangle",
|
|
4894
|
+
width: 200,
|
|
4895
|
+
height: 88,
|
|
4896
|
+
"background-color": "data(fillColor)",
|
|
4897
|
+
"border-width": 1,
|
|
4898
|
+
"border-color": "data(borderColor)",
|
|
4899
|
+
color: "data(textColor)",
|
|
4900
|
+
"font-size": 12,
|
|
4901
|
+
"font-weight": 700,
|
|
4902
|
+
"text-wrap": "wrap",
|
|
4903
|
+
"text-max-width": "180px",
|
|
4904
|
+
"text-valign": "center",
|
|
4905
|
+
"text-halign": "center",
|
|
4906
|
+
"overlay-opacity": 0,
|
|
4907
|
+
"underlay-shape": "round-rectangle"
|
|
4908
|
+
}
|
|
4909
|
+
},
|
|
4910
|
+
{
|
|
4911
|
+
selector: 'node[kind = "domain-card"]:active, node[kind = "domain-card"]:hover',
|
|
4912
|
+
style: {
|
|
4913
|
+
"border-width": 2,
|
|
4914
|
+
"border-color": selectedBorder
|
|
4915
|
+
}
|
|
4916
|
+
},
|
|
4917
|
+
{
|
|
4918
|
+
selector: "edge",
|
|
4919
|
+
style: {
|
|
4920
|
+
width: 1.05,
|
|
4921
|
+
label: "",
|
|
4029
4922
|
color: tokens.text,
|
|
4030
4923
|
"font-size": 10,
|
|
4031
4924
|
"font-weight": 700,
|
|
4032
4925
|
"curve-style": "bezier",
|
|
4926
|
+
"line-cap": "round",
|
|
4033
4927
|
"line-color": "data(strokeColor)",
|
|
4928
|
+
"line-outline-color": "data(edgeHaloColor)",
|
|
4929
|
+
"line-outline-width": 0.35,
|
|
4034
4930
|
"target-arrow-color": "data(strokeColor)",
|
|
4035
4931
|
"target-arrow-shape": "triangle",
|
|
4036
|
-
"arrow-scale": 0.
|
|
4932
|
+
"arrow-scale": 0.78,
|
|
4037
4933
|
"text-background-color": edgeLabelBackground,
|
|
4038
4934
|
"text-background-opacity": 1,
|
|
4039
4935
|
"text-background-padding": "4px",
|
|
4040
4936
|
"text-border-opacity": 0,
|
|
4041
4937
|
"text-rotation": "autorotate",
|
|
4042
4938
|
"overlay-opacity": 0,
|
|
4043
|
-
"line-opacity":
|
|
4939
|
+
"line-opacity": baseEdgeOpacity,
|
|
4940
|
+
"underlay-color": "data(edgeHaloColor)",
|
|
4941
|
+
"underlay-opacity": 0,
|
|
4942
|
+
"underlay-padding": 2,
|
|
4943
|
+
"transition-property": "opacity, width, line-opacity, line-color, underlay-opacity",
|
|
4944
|
+
"transition-duration": reducedMotion ? 0 : 90,
|
|
4945
|
+
"transition-timing-function": "ease-out-cubic",
|
|
4946
|
+
"z-index": 1
|
|
4947
|
+
}
|
|
4948
|
+
},
|
|
4949
|
+
{
|
|
4950
|
+
selector: 'edge[isExploreBackbone = "true"]',
|
|
4951
|
+
style: {
|
|
4952
|
+
width: 1.45,
|
|
4953
|
+
"line-opacity": visualizationMode === "explore" ? 0.22 : baseEdgeOpacity,
|
|
4954
|
+
"line-style": "dashed",
|
|
4955
|
+
"line-dash-pattern": [7, 8],
|
|
4956
|
+
"arrow-scale": 0.6,
|
|
4957
|
+
"line-outline-width": 0
|
|
4958
|
+
}
|
|
4959
|
+
},
|
|
4960
|
+
{
|
|
4961
|
+
selector: 'edge[isExploreExpansion = "true"]',
|
|
4962
|
+
style: {
|
|
4963
|
+
width: 1.55,
|
|
4964
|
+
"line-opacity": 0.56,
|
|
4965
|
+
"line-outline-width": 0.7,
|
|
4966
|
+
"underlay-opacity": 0,
|
|
4967
|
+
"underlay-padding": 0,
|
|
4968
|
+
"arrow-scale": 0.7
|
|
4044
4969
|
}
|
|
4045
4970
|
},
|
|
4046
4971
|
{
|
|
@@ -4062,18 +4987,66 @@ function createCytoscapeStyle(tokens) {
|
|
|
4062
4987
|
opacity: 0.1
|
|
4063
4988
|
}
|
|
4064
4989
|
},
|
|
4990
|
+
{
|
|
4991
|
+
selector: "node.is-faded",
|
|
4992
|
+
style: {
|
|
4993
|
+
"underlay-opacity": 0,
|
|
4994
|
+
"outline-opacity": 0
|
|
4995
|
+
}
|
|
4996
|
+
},
|
|
4997
|
+
{
|
|
4998
|
+
selector: "edge.is-faded",
|
|
4999
|
+
style: {
|
|
5000
|
+
"underlay-opacity": 0,
|
|
5001
|
+
"line-outline-width": 0
|
|
5002
|
+
}
|
|
5003
|
+
},
|
|
4065
5004
|
{
|
|
4066
5005
|
selector: "node.is-context",
|
|
4067
5006
|
style: {
|
|
4068
|
-
opacity: 1
|
|
5007
|
+
opacity: 1,
|
|
5008
|
+
"underlay-opacity": 0.025
|
|
5009
|
+
}
|
|
5010
|
+
},
|
|
5011
|
+
{
|
|
5012
|
+
selector: "node.is-hovered",
|
|
5013
|
+
style: {
|
|
5014
|
+
opacity: 1,
|
|
5015
|
+
"border-width": 2,
|
|
5016
|
+
"border-color": selectedBorder,
|
|
5017
|
+
"background-opacity": 0.92,
|
|
5018
|
+
"underlay-opacity": 0.045,
|
|
5019
|
+
"underlay-padding": 10,
|
|
5020
|
+
"outline-opacity": 0.12,
|
|
5021
|
+
"z-index": 20
|
|
5022
|
+
}
|
|
5023
|
+
},
|
|
5024
|
+
{
|
|
5025
|
+
selector: "node.is-hover-neighbor",
|
|
5026
|
+
style: {
|
|
5027
|
+
opacity: 1,
|
|
5028
|
+
"underlay-opacity": 0.02
|
|
4069
5029
|
}
|
|
4070
5030
|
},
|
|
4071
5031
|
{
|
|
4072
5032
|
selector: "edge.is-connected",
|
|
4073
5033
|
style: {
|
|
4074
5034
|
opacity: 1,
|
|
4075
|
-
width:
|
|
4076
|
-
"line-opacity": 0.
|
|
5035
|
+
width: 1.9,
|
|
5036
|
+
"line-opacity": 0.72,
|
|
5037
|
+
"underlay-opacity": 0,
|
|
5038
|
+
"line-outline-width": 0.8
|
|
5039
|
+
}
|
|
5040
|
+
},
|
|
5041
|
+
{
|
|
5042
|
+
selector: "edge.is-hover-connected",
|
|
5043
|
+
style: {
|
|
5044
|
+
opacity: 1,
|
|
5045
|
+
width: 1.8,
|
|
5046
|
+
"line-opacity": 0.76,
|
|
5047
|
+
"underlay-opacity": 0,
|
|
5048
|
+
"line-outline-width": 0.8,
|
|
5049
|
+
"z-index": 10
|
|
4077
5050
|
}
|
|
4078
5051
|
},
|
|
4079
5052
|
{
|
|
@@ -4081,8 +5054,15 @@ function createCytoscapeStyle(tokens) {
|
|
|
4081
5054
|
style: {
|
|
4082
5055
|
opacity: 1,
|
|
4083
5056
|
"border-color": selectedBorder,
|
|
4084
|
-
"border-width":
|
|
4085
|
-
"background-opacity":
|
|
5057
|
+
"border-width": 2.8,
|
|
5058
|
+
"background-opacity": 0.95,
|
|
5059
|
+
"underlay-color": selectedBorder,
|
|
5060
|
+
"underlay-opacity": 0.06,
|
|
5061
|
+
"underlay-padding": 12,
|
|
5062
|
+
"outline-color": selectedBorder,
|
|
5063
|
+
"outline-opacity": 0.16,
|
|
5064
|
+
"outline-width": 1,
|
|
5065
|
+
"z-index": 30
|
|
4086
5066
|
}
|
|
4087
5067
|
},
|
|
4088
5068
|
{
|
|
@@ -4090,23 +5070,28 @@ function createCytoscapeStyle(tokens) {
|
|
|
4090
5070
|
style: {
|
|
4091
5071
|
opacity: 1,
|
|
4092
5072
|
"border-color": traceBorder,
|
|
4093
|
-
"border-width":
|
|
5073
|
+
"border-width": 2.6,
|
|
5074
|
+
"underlay-color": traceBorder,
|
|
5075
|
+
"underlay-opacity": 0.05,
|
|
5076
|
+
"underlay-padding": 11
|
|
4094
5077
|
}
|
|
4095
5078
|
},
|
|
4096
5079
|
{
|
|
4097
5080
|
selector: "node.is-trace-endpoint",
|
|
4098
5081
|
style: {
|
|
4099
5082
|
opacity: 1,
|
|
4100
|
-
"border-color": mixColors(tokens.warning, tokens.
|
|
4101
|
-
"border-width":
|
|
5083
|
+
"border-color": mixColors(tokens.warning, tokens.textDimmed, 0.58),
|
|
5084
|
+
"border-width": 3
|
|
4102
5085
|
}
|
|
4103
5086
|
},
|
|
4104
5087
|
{
|
|
4105
5088
|
selector: "edge.is-selected",
|
|
4106
5089
|
style: {
|
|
4107
5090
|
opacity: 1,
|
|
4108
|
-
width:
|
|
4109
|
-
"line-opacity":
|
|
5091
|
+
width: 2.6,
|
|
5092
|
+
"line-opacity": 0.9,
|
|
5093
|
+
"line-outline-width": 1,
|
|
5094
|
+
"underlay-opacity": 0,
|
|
4110
5095
|
label: "data(label)"
|
|
4111
5096
|
}
|
|
4112
5097
|
},
|
|
@@ -4114,134 +5099,236 @@ function createCytoscapeStyle(tokens) {
|
|
|
4114
5099
|
selector: "edge.is-trace-edge",
|
|
4115
5100
|
style: {
|
|
4116
5101
|
opacity: 1,
|
|
4117
|
-
width:
|
|
4118
|
-
"line-opacity":
|
|
5102
|
+
width: 2.8,
|
|
5103
|
+
"line-opacity": 0.92,
|
|
4119
5104
|
label: "data(label)",
|
|
4120
5105
|
"line-color": traceBorder,
|
|
4121
5106
|
"target-arrow-color": traceBorder,
|
|
4122
|
-
"line-style": "solid"
|
|
5107
|
+
"line-style": "solid",
|
|
5108
|
+
"line-outline-color": withAlpha(traceBorder, 0.16),
|
|
5109
|
+
"line-outline-width": 1,
|
|
5110
|
+
"underlay-color": withAlpha(traceBorder, 0.12),
|
|
5111
|
+
"underlay-opacity": 0
|
|
4123
5112
|
}
|
|
4124
5113
|
},
|
|
4125
5114
|
{
|
|
4126
5115
|
selector: "node.is-expanded-node",
|
|
4127
5116
|
style: {
|
|
4128
5117
|
opacity: 1,
|
|
4129
|
-
"border-color": mixColors(tokens.primary, tokens.warning, 0.
|
|
4130
|
-
"border-width":
|
|
4131
|
-
"background-opacity":
|
|
5118
|
+
"border-color": mixColors(tokens.primary, tokens.warning, 0.42),
|
|
5119
|
+
"border-width": 2.2,
|
|
5120
|
+
"background-opacity": 0.92,
|
|
5121
|
+
"underlay-opacity": 0.04,
|
|
5122
|
+
"underlay-padding": 10,
|
|
5123
|
+
"outline-opacity": 0.12
|
|
4132
5124
|
}
|
|
4133
5125
|
},
|
|
4134
5126
|
{
|
|
4135
5127
|
selector: "edge.is-expanded-edge",
|
|
4136
5128
|
style: {
|
|
4137
5129
|
opacity: 1,
|
|
4138
|
-
width:
|
|
4139
|
-
"line-opacity": 0.
|
|
5130
|
+
width: 2,
|
|
5131
|
+
"line-opacity": 0.76,
|
|
5132
|
+
"line-outline-width": 0.9,
|
|
5133
|
+
"underlay-opacity": 0,
|
|
4140
5134
|
label: "data(label)"
|
|
4141
5135
|
}
|
|
4142
5136
|
}
|
|
4143
5137
|
];
|
|
4144
5138
|
}
|
|
4145
|
-
|
|
5139
|
+
var GRAPH_SYNC_CLASS_NAMES = [
|
|
5140
|
+
"is-hidden",
|
|
5141
|
+
"is-faded",
|
|
5142
|
+
"is-context",
|
|
5143
|
+
"is-selected",
|
|
5144
|
+
"is-connected",
|
|
5145
|
+
"is-trace-node",
|
|
5146
|
+
"is-trace-edge",
|
|
5147
|
+
"is-trace-endpoint",
|
|
5148
|
+
"is-expanded-node",
|
|
5149
|
+
"is-expanded-edge"
|
|
5150
|
+
];
|
|
5151
|
+
function addGraphClassTarget(targets, elementId, className) {
|
|
5152
|
+
let classNames = targets.get(elementId);
|
|
5153
|
+
if (!classNames) {
|
|
5154
|
+
classNames = /* @__PURE__ */ new Set();
|
|
5155
|
+
targets.set(elementId, classNames);
|
|
5156
|
+
}
|
|
5157
|
+
classNames.add(className);
|
|
5158
|
+
}
|
|
5159
|
+
function removeGraphClassTarget(targets, elementId, className) {
|
|
5160
|
+
targets.get(elementId)?.delete(className);
|
|
5161
|
+
}
|
|
5162
|
+
function applyGraphClassTargets(cy, targets) {
|
|
5163
|
+
const previousTargets = cy.scratch("_elevasis_graphClassTargets") ?? /* @__PURE__ */ new Map();
|
|
5164
|
+
const nextTargets = /* @__PURE__ */ new Map();
|
|
5165
|
+
for (const [elementId, classNames] of targets) {
|
|
5166
|
+
const key = GRAPH_SYNC_CLASS_NAMES.filter((className) => classNames.has(className)).join(" ");
|
|
5167
|
+
if (key) {
|
|
5168
|
+
nextTargets.set(elementId, key);
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5171
|
+
const touchedIds = /* @__PURE__ */ new Set([...previousTargets.keys(), ...nextTargets.keys()]);
|
|
4146
5172
|
cy.batch(() => {
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
if (!node.empty()) {
|
|
4153
|
-
node.addClass("is-hidden");
|
|
5173
|
+
for (const elementId of touchedIds) {
|
|
5174
|
+
const previousKey = previousTargets.get(elementId) ?? "";
|
|
5175
|
+
const nextKey = nextTargets.get(elementId) ?? "";
|
|
5176
|
+
if (previousKey === nextKey) {
|
|
5177
|
+
continue;
|
|
4154
5178
|
}
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
if (!edge2.empty()) {
|
|
4159
|
-
edge2.addClass("is-hidden");
|
|
5179
|
+
const element = cy.getElementById(elementId);
|
|
5180
|
+
if (element.empty()) {
|
|
5181
|
+
continue;
|
|
4160
5182
|
}
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
node.addClass("is-expanded-node");
|
|
4170
|
-
}
|
|
5183
|
+
const previousClassNames = previousKey.length > 0 ? previousKey.split(" ") : [];
|
|
5184
|
+
const nextClassNames = nextKey.length > 0 ? nextKey.split(" ") : [];
|
|
5185
|
+
const nextClassSet = new Set(nextClassNames);
|
|
5186
|
+
const previousClassSet = new Set(previousClassNames);
|
|
5187
|
+
const classesToRemove = previousClassNames.filter((className) => !nextClassSet.has(className)).join(" ");
|
|
5188
|
+
const classesToAdd = nextClassNames.filter((className) => !previousClassSet.has(className)).join(" ");
|
|
5189
|
+
if (classesToRemove.length > 0) {
|
|
5190
|
+
element.removeClass(classesToRemove);
|
|
4171
5191
|
}
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
if (!edge2.empty()) {
|
|
4175
|
-
edge2.addClass("is-expanded-edge");
|
|
4176
|
-
}
|
|
5192
|
+
if (classesToAdd.length > 0) {
|
|
5193
|
+
element.addClass(classesToAdd);
|
|
4177
5194
|
}
|
|
4178
|
-
return;
|
|
4179
5195
|
}
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
5196
|
+
});
|
|
5197
|
+
cy.scratch("_elevasis_graphClassTargets", nextTargets);
|
|
5198
|
+
}
|
|
5199
|
+
function syncOverlayLabelPositions(cy, labels, labelElements) {
|
|
5200
|
+
if (labels.length === 0) return;
|
|
5201
|
+
const pan = cy.pan();
|
|
5202
|
+
const zoom = cy.zoom();
|
|
5203
|
+
for (const label of labels) {
|
|
5204
|
+
const element = labelElements.get(label.domain);
|
|
5205
|
+
if (!element) continue;
|
|
5206
|
+
const screenX = label.x * zoom + pan.x;
|
|
5207
|
+
const screenY = label.y * zoom + pan.y;
|
|
5208
|
+
element.style.transform = `translate(${screenX}px, ${screenY}px) translate(-50%, -50%)`;
|
|
5209
|
+
}
|
|
5210
|
+
}
|
|
5211
|
+
function isRenderedNodeWithinViewport(cy, node, padding = 96) {
|
|
5212
|
+
const container = cy.container();
|
|
5213
|
+
if (!container) return true;
|
|
5214
|
+
const rect = container.getBoundingClientRect();
|
|
5215
|
+
const position = node.renderedPosition();
|
|
5216
|
+
return position.x >= padding && position.y >= padding && position.x <= rect.width - padding && position.y <= rect.height - padding;
|
|
5217
|
+
}
|
|
5218
|
+
function syncGraphClasses(cy, selectedElement, traceResult, hiddenIds, hiddenEdgeIds, expandedNodeIds, expandedEdgeIds, visualizationMode, graph, graphIndex, exploreExpandedNodeIds) {
|
|
5219
|
+
const syncKey = JSON.stringify({
|
|
5220
|
+
sel: selectedElement?.id ?? null,
|
|
5221
|
+
expN: [...expandedNodeIds].sort().join(","),
|
|
5222
|
+
expExpl: [...exploreExpandedNodeIds].sort().join(","),
|
|
5223
|
+
expE: [...expandedEdgeIds].sort().join(","),
|
|
5224
|
+
hidN: [...hiddenIds].sort().join(","),
|
|
5225
|
+
hidE: [...hiddenEdgeIds].sort().join(","),
|
|
5226
|
+
trace: traceResult?.highlightNodeIds.join(">") ?? null,
|
|
5227
|
+
vmode: visualizationMode
|
|
5228
|
+
});
|
|
5229
|
+
const lastKey = cy.scratch("_elevasis_lastSyncKey");
|
|
5230
|
+
if (syncKey === lastKey) return;
|
|
5231
|
+
cy.scratch("_elevasis_lastSyncKey", syncKey);
|
|
5232
|
+
const targets = /* @__PURE__ */ new Map();
|
|
5233
|
+
const hasTrace = Boolean(
|
|
5234
|
+
traceResult && (traceResult.highlightNodeIds.length > 0 || traceResult.highlightEdgeIds.length > 0)
|
|
5235
|
+
);
|
|
5236
|
+
const selectedNode = selectedElement?.type === "node" ? cy.getElementById(selectedElement.id) : null;
|
|
5237
|
+
const selectedEdge = selectedElement?.type === "edge" ? cy.getElementById(selectedElement.id) : null;
|
|
5238
|
+
const hasRenderableSelection = Boolean(
|
|
5239
|
+
selectedElement && (selectedNode && !selectedNode.empty() || selectedEdge && !selectedEdge.empty())
|
|
5240
|
+
);
|
|
5241
|
+
const shouldFadeContext = hasTrace || hasRenderableSelection;
|
|
5242
|
+
for (const nodeId of hiddenIds) {
|
|
5243
|
+
addGraphClassTarget(targets, nodeId, "is-hidden");
|
|
5244
|
+
}
|
|
5245
|
+
for (const edgeId of hiddenEdgeIds) {
|
|
5246
|
+
addGraphClassTarget(targets, edgeId, "is-hidden");
|
|
5247
|
+
}
|
|
5248
|
+
if (shouldFadeContext) {
|
|
5249
|
+
cy.elements().forEach((element) => {
|
|
5250
|
+
addGraphClassTarget(targets, element.id(), "is-faded");
|
|
5251
|
+
});
|
|
5252
|
+
}
|
|
5253
|
+
for (const nodeId of expandedNodeIds) {
|
|
5254
|
+
removeGraphClassTarget(targets, nodeId, "is-faded");
|
|
5255
|
+
addGraphClassTarget(targets, nodeId, "is-expanded-node");
|
|
5256
|
+
if (shouldFadeContext) {
|
|
5257
|
+
addGraphClassTarget(targets, nodeId, "is-context");
|
|
4186
5258
|
}
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
5259
|
+
}
|
|
5260
|
+
for (const edgeId of expandedEdgeIds) {
|
|
5261
|
+
removeGraphClassTarget(targets, edgeId, "is-faded");
|
|
5262
|
+
addGraphClassTarget(targets, edgeId, "is-expanded-edge");
|
|
5263
|
+
if (shouldFadeContext) {
|
|
5264
|
+
addGraphClassTarget(targets, edgeId, "is-connected");
|
|
4192
5265
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
}
|
|
4200
|
-
for (const edgeId of traceResult.highlightEdgeIds) {
|
|
4201
|
-
const edge2 = cy.getElementById(edgeId);
|
|
4202
|
-
if (!edge2.empty()) {
|
|
4203
|
-
edge2.removeClass("is-faded").addClass("is-connected is-trace-edge");
|
|
4204
|
-
}
|
|
4205
|
-
}
|
|
4206
|
-
if (traceResult.source) {
|
|
4207
|
-
cy.getElementById(traceResult.source.id).removeClass("is-faded").addClass("is-trace-endpoint");
|
|
4208
|
-
}
|
|
4209
|
-
if (traceResult.target) {
|
|
4210
|
-
cy.getElementById(traceResult.target.id).removeClass("is-faded").addClass("is-trace-endpoint");
|
|
4211
|
-
}
|
|
5266
|
+
}
|
|
5267
|
+
if (traceResult) {
|
|
5268
|
+
for (const nodeId of traceResult.highlightNodeIds) {
|
|
5269
|
+
removeGraphClassTarget(targets, nodeId, "is-faded");
|
|
5270
|
+
addGraphClassTarget(targets, nodeId, "is-context");
|
|
5271
|
+
addGraphClassTarget(targets, nodeId, "is-trace-node");
|
|
4212
5272
|
}
|
|
4213
|
-
|
|
4214
|
-
|
|
5273
|
+
for (const edgeId of traceResult.highlightEdgeIds) {
|
|
5274
|
+
removeGraphClassTarget(targets, edgeId, "is-faded");
|
|
5275
|
+
addGraphClassTarget(targets, edgeId, "is-connected");
|
|
5276
|
+
addGraphClassTarget(targets, edgeId, "is-trace-edge");
|
|
4215
5277
|
}
|
|
4216
|
-
if (
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
cy.elements().removeClass("is-faded");
|
|
4220
|
-
return;
|
|
4221
|
-
}
|
|
4222
|
-
const neighborhood = node.closedNeighborhood();
|
|
4223
|
-
neighborhood.removeClass("is-faded").addClass("is-context");
|
|
4224
|
-
neighborhood.edges().addClass("is-connected");
|
|
4225
|
-
node.removeClass("is-faded").addClass("is-selected");
|
|
4226
|
-
return;
|
|
5278
|
+
if (traceResult.source) {
|
|
5279
|
+
removeGraphClassTarget(targets, traceResult.source.id, "is-faded");
|
|
5280
|
+
addGraphClassTarget(targets, traceResult.source.id, "is-trace-endpoint");
|
|
4227
5281
|
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
return;
|
|
5282
|
+
if (traceResult.target) {
|
|
5283
|
+
removeGraphClassTarget(targets, traceResult.target.id, "is-faded");
|
|
5284
|
+
addGraphClassTarget(targets, traceResult.target.id, "is-trace-endpoint");
|
|
4232
5285
|
}
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
5286
|
+
}
|
|
5287
|
+
if (selectedNode && !selectedNode.empty()) {
|
|
5288
|
+
if (visualizationMode === "explore") {
|
|
5289
|
+
const focus = getExploreFocusSet(graph, selectedNode.id(), exploreExpandedNodeIds, graphIndex);
|
|
5290
|
+
for (const nodeId of focus.nodeIds) {
|
|
5291
|
+
removeGraphClassTarget(targets, nodeId, "is-faded");
|
|
5292
|
+
addGraphClassTarget(targets, nodeId, "is-context");
|
|
5293
|
+
}
|
|
5294
|
+
for (const edgeId of focus.edgeIds) {
|
|
5295
|
+
removeGraphClassTarget(targets, edgeId, "is-faded");
|
|
5296
|
+
addGraphClassTarget(targets, edgeId, "is-connected");
|
|
5297
|
+
}
|
|
5298
|
+
} else {
|
|
5299
|
+
const neighborhood = selectedNode.closedNeighborhood();
|
|
5300
|
+
neighborhood.forEach((element) => {
|
|
5301
|
+
removeGraphClassTarget(targets, element.id(), "is-faded");
|
|
5302
|
+
addGraphClassTarget(targets, element.id(), "is-context");
|
|
5303
|
+
});
|
|
5304
|
+
neighborhood.edges().forEach((edge) => {
|
|
5305
|
+
addGraphClassTarget(targets, edge.id(), "is-connected");
|
|
5306
|
+
});
|
|
5307
|
+
}
|
|
5308
|
+
removeGraphClassTarget(targets, selectedNode.id(), "is-faded");
|
|
5309
|
+
addGraphClassTarget(targets, selectedNode.id(), "is-selected");
|
|
5310
|
+
} else if (selectedEdge && !selectedEdge.empty()) {
|
|
5311
|
+
selectedEdge.connectedNodes().union(selectedEdge).forEach((element) => {
|
|
5312
|
+
removeGraphClassTarget(targets, element.id(), "is-faded");
|
|
5313
|
+
addGraphClassTarget(targets, element.id(), "is-context");
|
|
5314
|
+
});
|
|
5315
|
+
removeGraphClassTarget(targets, selectedEdge.id(), "is-faded");
|
|
5316
|
+
addGraphClassTarget(targets, selectedEdge.id(), "is-selected");
|
|
5317
|
+
addGraphClassTarget(targets, selectedEdge.id(), "is-connected");
|
|
5318
|
+
selectedEdge.connectedNodes().forEach((node) => {
|
|
5319
|
+
addGraphClassTarget(targets, node.id(), "is-selected");
|
|
5320
|
+
});
|
|
5321
|
+
}
|
|
5322
|
+
applyGraphClassTargets(cy, targets);
|
|
4238
5323
|
}
|
|
4239
5324
|
function syncCytoscapeElements(cy, elements) {
|
|
4240
5325
|
const nextIds = new Set(elements.map((element) => element.data.id));
|
|
5326
|
+
let didMutateElements = false;
|
|
4241
5327
|
cy.batch(() => {
|
|
4242
5328
|
cy.elements().forEach((element) => {
|
|
4243
5329
|
if (!nextIds.has(element.id())) {
|
|
4244
5330
|
element.remove();
|
|
5331
|
+
didMutateElements = true;
|
|
4245
5332
|
}
|
|
4246
5333
|
});
|
|
4247
5334
|
for (const element of elements) {
|
|
@@ -4249,14 +5336,33 @@ function syncCytoscapeElements(cy, elements) {
|
|
|
4249
5336
|
const existing = cy.getElementById(id);
|
|
4250
5337
|
if (existing.empty()) {
|
|
4251
5338
|
cy.add(element);
|
|
5339
|
+
didMutateElements = true;
|
|
4252
5340
|
continue;
|
|
4253
5341
|
}
|
|
4254
|
-
existing.data(
|
|
5342
|
+
const currentData = existing.data();
|
|
5343
|
+
let dataChanged = false;
|
|
5344
|
+
for (const key of Object.keys(element.data)) {
|
|
5345
|
+
if (currentData[key] !== element.data[key]) {
|
|
5346
|
+
dataChanged = true;
|
|
5347
|
+
break;
|
|
5348
|
+
}
|
|
5349
|
+
}
|
|
5350
|
+
if (dataChanged) {
|
|
5351
|
+
existing.data(element.data);
|
|
5352
|
+
didMutateElements = true;
|
|
5353
|
+
}
|
|
4255
5354
|
if ("position" in element && element.position && existing.isNode()) {
|
|
4256
|
-
existing.position(
|
|
5355
|
+
const currentPos = existing.position();
|
|
5356
|
+
if (currentPos.x !== element.position.x || currentPos.y !== element.position.y) {
|
|
5357
|
+
existing.position(element.position);
|
|
5358
|
+
didMutateElements = true;
|
|
5359
|
+
}
|
|
4257
5360
|
}
|
|
4258
5361
|
}
|
|
4259
5362
|
});
|
|
5363
|
+
if (didMutateElements) {
|
|
5364
|
+
cy.scratch("_elevasis_lastSyncKey", null);
|
|
5365
|
+
}
|
|
4260
5366
|
}
|
|
4261
5367
|
function OrganizationGraphCanvas({
|
|
4262
5368
|
graph,
|
|
@@ -4268,32 +5374,104 @@ function OrganizationGraphCanvas({
|
|
|
4268
5374
|
hiddenEdgeIds,
|
|
4269
5375
|
expandedNodeIds,
|
|
4270
5376
|
expandedEdgeIds,
|
|
5377
|
+
expandedClusterDomains,
|
|
5378
|
+
exploreExpandedNodeIds,
|
|
4271
5379
|
themeTokens,
|
|
4272
5380
|
commandViewHealthByNodeId,
|
|
4273
5381
|
focusRequest,
|
|
4274
5382
|
toolbar,
|
|
4275
|
-
|
|
5383
|
+
parameters,
|
|
5384
|
+
runForceLayout,
|
|
5385
|
+
onSelectElement,
|
|
5386
|
+
onToggleClusterDomain,
|
|
5387
|
+
onToggleNodeExpansion
|
|
4276
5388
|
}) {
|
|
4277
5389
|
const containerRef = useRef(null);
|
|
4278
5390
|
const cytoscapeRef = useRef(null);
|
|
4279
5391
|
const previousModeRef = useRef(mode);
|
|
4280
5392
|
const onSelectElementRef = useRef(onSelectElement);
|
|
5393
|
+
const onToggleClusterDomainRef = useRef(onToggleClusterDomain);
|
|
5394
|
+
const onToggleNodeExpansionRef = useRef(onToggleNodeExpansion);
|
|
5395
|
+
const graphRef = useRef(graph);
|
|
5396
|
+
const visualizationModeRef = useRef(visualizationMode);
|
|
5397
|
+
const exploreExpandedNodeIdsRef = useRef(exploreExpandedNodeIds);
|
|
4281
5398
|
const lastSizeRef = useRef(null);
|
|
5399
|
+
const hasAnimatedInitialFitRef = useRef(false);
|
|
5400
|
+
const previousExploreExpandedNodeIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
5401
|
+
const lastSelectedRef = useRef(null);
|
|
5402
|
+
const hoveredElementIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
5403
|
+
const overlayLabelsRef = useRef([]);
|
|
5404
|
+
const overlayLabelElementsRef = useRef(/* @__PURE__ */ new Map());
|
|
4282
5405
|
const layoutSelectedElement = visualizationMode === "focus" ? selectedElement : null;
|
|
5406
|
+
const graphIndex = useMemo(() => buildCommandViewGraphIndex(graph), [graph]);
|
|
5407
|
+
const graphIndexRef = useRef(graphIndex);
|
|
4283
5408
|
const elements = useMemo(
|
|
4284
5409
|
() => toCytoscapeElementsWithHealth(
|
|
4285
5410
|
graph,
|
|
5411
|
+
graphIndex,
|
|
4286
5412
|
themeTokens,
|
|
4287
5413
|
commandViewHealthByNodeId,
|
|
4288
5414
|
visualizationMode,
|
|
4289
|
-
layoutSelectedElement
|
|
5415
|
+
layoutSelectedElement,
|
|
5416
|
+
expandedClusterDomains,
|
|
5417
|
+
parameters,
|
|
5418
|
+
exploreExpandedNodeIds
|
|
4290
5419
|
),
|
|
4291
|
-
[
|
|
5420
|
+
[
|
|
5421
|
+
commandViewHealthByNodeId,
|
|
5422
|
+
expandedClusterDomains,
|
|
5423
|
+
exploreExpandedNodeIds,
|
|
5424
|
+
graph,
|
|
5425
|
+
graphIndex,
|
|
5426
|
+
layoutSelectedElement,
|
|
5427
|
+
parameters,
|
|
5428
|
+
themeTokens,
|
|
5429
|
+
visualizationMode
|
|
5430
|
+
]
|
|
4292
5431
|
);
|
|
4293
|
-
const cytoscapeStyle = useMemo(
|
|
5432
|
+
const cytoscapeStyle = useMemo(
|
|
5433
|
+
() => createCytoscapeStyle(themeTokens, visualizationMode),
|
|
5434
|
+
[themeTokens, visualizationMode]
|
|
5435
|
+
);
|
|
5436
|
+
const expandedDomainsKey = expandedClusterDomains.join(",");
|
|
5437
|
+
const overlayLabels = useMemo(() => {
|
|
5438
|
+
if (visualizationMode === "cluster") {
|
|
5439
|
+
const expanded = new Set(expandedClusterDomains);
|
|
5440
|
+
return getCommandViewClusterZoneLabels().filter((entry) => !expanded.has(entry.domain));
|
|
5441
|
+
}
|
|
5442
|
+
if (visualizationMode === "swimlane") {
|
|
5443
|
+
return getCommandViewSwimlaneLaneLabels();
|
|
5444
|
+
}
|
|
5445
|
+
return [];
|
|
5446
|
+
}, [visualizationMode, expandedDomainsKey]);
|
|
5447
|
+
useEffect(() => {
|
|
5448
|
+
overlayLabelsRef.current = overlayLabels;
|
|
5449
|
+
const cy = cytoscapeRef.current;
|
|
5450
|
+
if (cy) {
|
|
5451
|
+
syncOverlayLabelPositions(cy, overlayLabels, overlayLabelElementsRef.current);
|
|
5452
|
+
}
|
|
5453
|
+
}, [overlayLabels]);
|
|
4294
5454
|
useEffect(() => {
|
|
4295
5455
|
onSelectElementRef.current = onSelectElement;
|
|
4296
5456
|
}, [onSelectElement]);
|
|
5457
|
+
useEffect(() => {
|
|
5458
|
+
onToggleClusterDomainRef.current = onToggleClusterDomain;
|
|
5459
|
+
}, [onToggleClusterDomain]);
|
|
5460
|
+
useEffect(() => {
|
|
5461
|
+
onToggleNodeExpansionRef.current = onToggleNodeExpansion;
|
|
5462
|
+
}, [onToggleNodeExpansion]);
|
|
5463
|
+
useEffect(() => {
|
|
5464
|
+
graphRef.current = graph;
|
|
5465
|
+
}, [graph]);
|
|
5466
|
+
useEffect(() => {
|
|
5467
|
+
graphIndexRef.current = graphIndex;
|
|
5468
|
+
}, [graphIndex]);
|
|
5469
|
+
useEffect(() => {
|
|
5470
|
+
visualizationModeRef.current = visualizationMode;
|
|
5471
|
+
}, [visualizationMode]);
|
|
5472
|
+
useEffect(() => {
|
|
5473
|
+
exploreExpandedNodeIdsRef.current = exploreExpandedNodeIds;
|
|
5474
|
+
}, [exploreExpandedNodeIds]);
|
|
4297
5475
|
useEffect(() => {
|
|
4298
5476
|
if (!containerRef.current) {
|
|
4299
5477
|
return;
|
|
@@ -4305,17 +5483,91 @@ function OrganizationGraphCanvas({
|
|
|
4305
5483
|
layout: getLayoutOptions(mode, null, traceResult),
|
|
4306
5484
|
minZoom: 0.22,
|
|
4307
5485
|
maxZoom: 1.6,
|
|
4308
|
-
wheelSensitivity: 1.35
|
|
5486
|
+
wheelSensitivity: 1.35,
|
|
5487
|
+
textureOnViewport: true,
|
|
5488
|
+
pixelRatio: getGraphPixelRatio()
|
|
4309
5489
|
});
|
|
4310
5490
|
cytoscapeRef.current = cy;
|
|
5491
|
+
window.__elevasis_cy = cy;
|
|
5492
|
+
const canvasElement = containerRef.current;
|
|
5493
|
+
const resetGraphHover = () => {
|
|
5494
|
+
const hoveredElementIds = hoveredElementIdsRef.current;
|
|
5495
|
+
if (hoveredElementIds.size > 0) {
|
|
5496
|
+
cy.batch(() => {
|
|
5497
|
+
for (const elementId of hoveredElementIds) {
|
|
5498
|
+
const element = cy.getElementById(elementId);
|
|
5499
|
+
if (!element.empty()) {
|
|
5500
|
+
element.removeClass("is-hovered is-hover-neighbor is-hover-connected");
|
|
5501
|
+
}
|
|
5502
|
+
}
|
|
5503
|
+
hoveredElementIds.clear();
|
|
5504
|
+
});
|
|
5505
|
+
}
|
|
5506
|
+
if (canvasElement) {
|
|
5507
|
+
canvasElement.style.cursor = "";
|
|
5508
|
+
}
|
|
5509
|
+
};
|
|
5510
|
+
cy.on("mouseover", "node", (event) => {
|
|
5511
|
+
const node = event.target;
|
|
5512
|
+
const connectedEdges = node.connectedEdges();
|
|
5513
|
+
const hoveredElementIds = hoveredElementIdsRef.current;
|
|
5514
|
+
node.addClass("is-hovered");
|
|
5515
|
+
hoveredElementIds.add(node.id());
|
|
5516
|
+
connectedEdges.addClass("is-hover-connected");
|
|
5517
|
+
connectedEdges.forEach((connectedEdge) => {
|
|
5518
|
+
hoveredElementIds.add(connectedEdge.id());
|
|
5519
|
+
});
|
|
5520
|
+
connectedEdges.connectedNodes().forEach((connectedNode) => {
|
|
5521
|
+
if (connectedNode.id() !== node.id()) {
|
|
5522
|
+
connectedNode.addClass("is-hover-neighbor");
|
|
5523
|
+
hoveredElementIds.add(connectedNode.id());
|
|
5524
|
+
}
|
|
5525
|
+
});
|
|
5526
|
+
if (canvasElement) {
|
|
5527
|
+
canvasElement.style.cursor = "pointer";
|
|
5528
|
+
}
|
|
5529
|
+
});
|
|
5530
|
+
cy.on("mouseout", "node", resetGraphHover);
|
|
5531
|
+
cy.on("mouseover", "edge", (event) => {
|
|
5532
|
+
const edge = event.target;
|
|
5533
|
+
const hoveredElementIds = hoveredElementIdsRef.current;
|
|
5534
|
+
edge.addClass("is-hover-connected");
|
|
5535
|
+
hoveredElementIds.add(edge.id());
|
|
5536
|
+
edge.connectedNodes().addClass("is-hover-neighbor");
|
|
5537
|
+
edge.connectedNodes().forEach((connectedNode) => {
|
|
5538
|
+
hoveredElementIds.add(connectedNode.id());
|
|
5539
|
+
});
|
|
5540
|
+
if (canvasElement) {
|
|
5541
|
+
canvasElement.style.cursor = "pointer";
|
|
5542
|
+
}
|
|
5543
|
+
});
|
|
5544
|
+
cy.on("mouseout", "edge", resetGraphHover);
|
|
4311
5545
|
cy.on("tap", "node", (event) => {
|
|
4312
|
-
|
|
5546
|
+
const node = event.target;
|
|
5547
|
+
if (node.data("kind") === "domain-card") {
|
|
5548
|
+
onToggleClusterDomainRef.current(node.data("domain"));
|
|
5549
|
+
return;
|
|
5550
|
+
}
|
|
5551
|
+
if (visualizationModeRef.current === "explore") {
|
|
5552
|
+
const nodeId = node.id();
|
|
5553
|
+
const expandedSet = exploreExpandedNodeIdsRef.current;
|
|
5554
|
+
const currentGraphIndex = graphIndexRef.current;
|
|
5555
|
+
if (nodeId !== EXPLORE_OM_ROOT_ID && !expandedSet.has(nodeId) && exploreNodeHasChildren(graphRef.current, nodeId, currentGraphIndex)) {
|
|
5556
|
+
const nextSet = getNextExpandedSetForToggle(graphRef.current, nodeId, expandedSet, currentGraphIndex);
|
|
5557
|
+
useCommandViewStore.setState({
|
|
5558
|
+
expandedNodeIdsArray: Array.from(nextSet),
|
|
5559
|
+
expandedNodeIds: nextSet
|
|
5560
|
+
});
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
onSelectElementRef.current({ type: "node", id: node.id() });
|
|
4313
5564
|
});
|
|
4314
5565
|
cy.on("tap", "edge", (event) => {
|
|
4315
5566
|
onSelectElementRef.current({ type: "edge", id: event.target.id() });
|
|
4316
5567
|
});
|
|
4317
5568
|
cy.on("tap", (event) => {
|
|
4318
5569
|
if (event.target === cy) {
|
|
5570
|
+
resetGraphHover();
|
|
4319
5571
|
onSelectElementRef.current(null);
|
|
4320
5572
|
}
|
|
4321
5573
|
});
|
|
@@ -4335,9 +5587,58 @@ function OrganizationGraphCanvas({
|
|
|
4335
5587
|
});
|
|
4336
5588
|
});
|
|
4337
5589
|
resizeObserver.observe(containerRef.current);
|
|
4338
|
-
syncGraphClasses(
|
|
5590
|
+
syncGraphClasses(
|
|
5591
|
+
cy,
|
|
5592
|
+
selectedElement,
|
|
5593
|
+
traceResult,
|
|
5594
|
+
hiddenIds,
|
|
5595
|
+
hiddenEdgeIds,
|
|
5596
|
+
expandedNodeIds,
|
|
5597
|
+
expandedEdgeIds,
|
|
5598
|
+
visualizationMode,
|
|
5599
|
+
graph,
|
|
5600
|
+
graphIndex,
|
|
5601
|
+
exploreExpandedNodeIds
|
|
5602
|
+
);
|
|
5603
|
+
if (!hasAnimatedInitialFitRef.current) {
|
|
5604
|
+
hasAnimatedInitialFitRef.current = true;
|
|
5605
|
+
const root = cy.nodes('[kind = "organization"]').first();
|
|
5606
|
+
if (root && !root.empty()) {
|
|
5607
|
+
if (shouldReduceGraphMotion()) {
|
|
5608
|
+
cy.fit(void 0, 44);
|
|
5609
|
+
} else {
|
|
5610
|
+
cy.animate(
|
|
5611
|
+
{ fit: { eles: root.closedNeighborhood(), padding: 80 }, duration: 280 },
|
|
5612
|
+
{
|
|
5613
|
+
easing: "ease-out-cubic",
|
|
5614
|
+
complete: () => {
|
|
5615
|
+
if (cy.destroyed()) return;
|
|
5616
|
+
cy.animate({ fit: { eles: cy.nodes(), padding: 44 }, duration: 700 }, { easing: "ease-out-cubic" });
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
);
|
|
5620
|
+
}
|
|
5621
|
+
} else {
|
|
5622
|
+
cy.fit(void 0, 44);
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
let frame = 0;
|
|
5626
|
+
const syncTransform = () => {
|
|
5627
|
+
if (overlayLabelsRef.current.length === 0) return;
|
|
5628
|
+
if (frame) return;
|
|
5629
|
+
frame = window.requestAnimationFrame(() => {
|
|
5630
|
+
frame = 0;
|
|
5631
|
+
if (cy.destroyed()) return;
|
|
5632
|
+
syncOverlayLabelPositions(cy, overlayLabelsRef.current, overlayLabelElementsRef.current);
|
|
5633
|
+
});
|
|
5634
|
+
};
|
|
5635
|
+
cy.on("pan zoom", syncTransform);
|
|
5636
|
+
syncTransform();
|
|
4339
5637
|
return () => {
|
|
5638
|
+
if (frame) window.cancelAnimationFrame(frame);
|
|
5639
|
+
cy.off("pan zoom", syncTransform);
|
|
4340
5640
|
resizeObserver.disconnect();
|
|
5641
|
+
hoveredElementIdsRef.current.clear();
|
|
4341
5642
|
cy.destroy();
|
|
4342
5643
|
cytoscapeRef.current = null;
|
|
4343
5644
|
};
|
|
@@ -4348,9 +5649,86 @@ function OrganizationGraphCanvas({
|
|
|
4348
5649
|
return;
|
|
4349
5650
|
}
|
|
4350
5651
|
syncCytoscapeElements(cy, elements);
|
|
4351
|
-
|
|
4352
|
-
|
|
5652
|
+
if (visualizationMode === "force") {
|
|
5653
|
+
runForceLayout(cy);
|
|
5654
|
+
} else if (visualizationMode === "explore") ; else {
|
|
5655
|
+
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
5656
|
+
}
|
|
5657
|
+
syncGraphClasses(
|
|
5658
|
+
cy,
|
|
5659
|
+
selectedElement,
|
|
5660
|
+
traceResult,
|
|
5661
|
+
hiddenIds,
|
|
5662
|
+
hiddenEdgeIds,
|
|
5663
|
+
expandedNodeIds,
|
|
5664
|
+
expandedEdgeIds,
|
|
5665
|
+
visualizationMode,
|
|
5666
|
+
graph,
|
|
5667
|
+
graphIndex,
|
|
5668
|
+
exploreExpandedNodeIds
|
|
5669
|
+
);
|
|
5670
|
+
if (visualizationMode === "cluster") {
|
|
5671
|
+
window.requestAnimationFrame(() => {
|
|
5672
|
+
if (cy.destroyed()) return;
|
|
5673
|
+
cy.fit(void 0, 44);
|
|
5674
|
+
cy.zoom(cy.zoom() * 1.3);
|
|
5675
|
+
cy.center();
|
|
5676
|
+
});
|
|
5677
|
+
}
|
|
4353
5678
|
}, [elements]);
|
|
5679
|
+
useEffect(() => {
|
|
5680
|
+
const cy = cytoscapeRef.current;
|
|
5681
|
+
if (!cy || visualizationMode !== "explore") {
|
|
5682
|
+
previousExploreExpandedNodeIdsRef.current = new Set(exploreExpandedNodeIds);
|
|
5683
|
+
return;
|
|
5684
|
+
}
|
|
5685
|
+
const previous = previousExploreExpandedNodeIdsRef.current;
|
|
5686
|
+
previousExploreExpandedNodeIdsRef.current = new Set(exploreExpandedNodeIds);
|
|
5687
|
+
const newlyAddedNodeIds = [];
|
|
5688
|
+
for (const nodeId of exploreExpandedNodeIds) {
|
|
5689
|
+
if (!previous.has(nodeId)) {
|
|
5690
|
+
newlyAddedNodeIds.push(nodeId);
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
if (newlyAddedNodeIds.length === 0) {
|
|
5694
|
+
return;
|
|
5695
|
+
}
|
|
5696
|
+
if (shouldReduceGraphMotion()) {
|
|
5697
|
+
return;
|
|
5698
|
+
}
|
|
5699
|
+
const { positions: explorePositions } = getExploreProjection();
|
|
5700
|
+
cy.batch(() => {
|
|
5701
|
+
for (const nodeId of newlyAddedNodeIds) {
|
|
5702
|
+
const anchorPos = explorePositions.get(nodeId) ?? cy.getElementById(nodeId).position();
|
|
5703
|
+
if (!anchorPos) continue;
|
|
5704
|
+
const level = nodeId.startsWith("centroid:") ? 1 : 2;
|
|
5705
|
+
const childPositions = getRadialFromAnchorProjection(graph, nodeId, anchorPos, level, graphIndex);
|
|
5706
|
+
if (childPositions.size > EXPLORE_EXPANSION_ANIMATION_LIMIT) {
|
|
5707
|
+
continue;
|
|
5708
|
+
}
|
|
5709
|
+
for (const [childId, targetPos] of childPositions) {
|
|
5710
|
+
const node = cy.getElementById(childId);
|
|
5711
|
+
if (node.empty()) continue;
|
|
5712
|
+
node.position({ x: anchorPos.x, y: anchorPos.y });
|
|
5713
|
+
node.animate({ position: { x: targetPos.x, y: targetPos.y } }, { duration: 320, easing: "ease-out-cubic" });
|
|
5714
|
+
const edge = cy.getElementById(`expand:${nodeId}:${childId}`);
|
|
5715
|
+
if (!edge.empty()) {
|
|
5716
|
+
edge.style({ width: 0.4, "line-opacity": 0, "underlay-opacity": 0 });
|
|
5717
|
+
edge.animate(
|
|
5718
|
+
{ style: { width: 1.55, "line-opacity": 0.56, "underlay-opacity": 0 } },
|
|
5719
|
+
{
|
|
5720
|
+
duration: 280,
|
|
5721
|
+
easing: "ease-out-cubic",
|
|
5722
|
+
complete: () => {
|
|
5723
|
+
if (!edge.removed()) edge.removeStyle("width line-opacity underlay-opacity");
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
);
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
5730
|
+
});
|
|
5731
|
+
}, [exploreExpandedNodeIds, graph, graphIndex, visualizationMode]);
|
|
4354
5732
|
useEffect(() => {
|
|
4355
5733
|
const cy = cytoscapeRef.current;
|
|
4356
5734
|
if (!cy) {
|
|
@@ -4361,34 +5739,98 @@ function OrganizationGraphCanvas({
|
|
|
4361
5739
|
if (!modeChanged && mode === "map") {
|
|
4362
5740
|
return;
|
|
4363
5741
|
}
|
|
4364
|
-
|
|
5742
|
+
if (visualizationMode === "force") {
|
|
5743
|
+
runForceLayout(cy);
|
|
5744
|
+
} else {
|
|
5745
|
+
cy.layout(getLayoutOptions(mode, selectedElement, traceResult)).run();
|
|
5746
|
+
}
|
|
4365
5747
|
}, [mode, selectedElement, traceResult]);
|
|
4366
5748
|
useEffect(() => {
|
|
4367
5749
|
const cy = cytoscapeRef.current;
|
|
4368
5750
|
if (!cy) {
|
|
4369
5751
|
return;
|
|
4370
5752
|
}
|
|
4371
|
-
syncGraphClasses(
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
5753
|
+
syncGraphClasses(
|
|
5754
|
+
cy,
|
|
5755
|
+
selectedElement,
|
|
5756
|
+
traceResult,
|
|
5757
|
+
hiddenIds,
|
|
5758
|
+
hiddenEdgeIds,
|
|
5759
|
+
expandedNodeIds,
|
|
5760
|
+
expandedEdgeIds,
|
|
5761
|
+
visualizationMode,
|
|
5762
|
+
graph,
|
|
5763
|
+
graphIndex,
|
|
5764
|
+
exploreExpandedNodeIds
|
|
5765
|
+
);
|
|
5766
|
+
}, [
|
|
5767
|
+
expandedEdgeIds,
|
|
5768
|
+
expandedNodeIds,
|
|
5769
|
+
exploreExpandedNodeIds,
|
|
5770
|
+
graph,
|
|
5771
|
+
graphIndex,
|
|
5772
|
+
hiddenEdgeIds,
|
|
5773
|
+
hiddenIds,
|
|
5774
|
+
mode,
|
|
5775
|
+
selectedElement,
|
|
5776
|
+
traceResult,
|
|
5777
|
+
visualizationMode
|
|
5778
|
+
]);
|
|
5779
|
+
useEffect(() => {
|
|
5780
|
+
const cy = cytoscapeRef.current;
|
|
5781
|
+
if (!cy) {
|
|
5782
|
+
return;
|
|
5783
|
+
}
|
|
5784
|
+
const currentSelectionId = selectedElement?.type === "node" ? selectedElement.id : null;
|
|
5785
|
+
if (currentSelectionId === null) {
|
|
5786
|
+
lastSelectedRef.current = null;
|
|
5787
|
+
return;
|
|
5788
|
+
}
|
|
5789
|
+
if (currentSelectionId === lastSelectedRef.current) {
|
|
5790
|
+
return;
|
|
5791
|
+
}
|
|
5792
|
+
lastSelectedRef.current = currentSelectionId;
|
|
5793
|
+
const node = cy.getElementById(currentSelectionId);
|
|
5794
|
+
if (node.empty()) {
|
|
5795
|
+
return;
|
|
5796
|
+
}
|
|
5797
|
+
if (visualizationMode === "explore") {
|
|
5798
|
+
if (isRenderedNodeWithinViewport(cy, node)) {
|
|
5799
|
+
return;
|
|
5800
|
+
}
|
|
5801
|
+
cy.stop();
|
|
5802
|
+
if (shouldReduceGraphMotion()) {
|
|
5803
|
+
cy.center(node);
|
|
5804
|
+
return;
|
|
5805
|
+
}
|
|
5806
|
+
cy.animate(
|
|
5807
|
+
{
|
|
5808
|
+
center: { eles: node },
|
|
5809
|
+
duration: 160
|
|
5810
|
+
},
|
|
5811
|
+
{ easing: "ease-out-cubic" }
|
|
5812
|
+
);
|
|
5813
|
+
} else if (mode === "map") {
|
|
5814
|
+
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
5815
|
+
cy.stop();
|
|
5816
|
+
if (shouldReduceGraphMotion()) {
|
|
5817
|
+
cy.fit(visibleNeighborhood.empty() ? node : visibleNeighborhood, 72);
|
|
5818
|
+
return;
|
|
4389
5819
|
}
|
|
5820
|
+
cy.animate(
|
|
5821
|
+
{
|
|
5822
|
+
fit: {
|
|
5823
|
+
eles: visibleNeighborhood.empty() ? node : visibleNeighborhood,
|
|
5824
|
+
padding: 72
|
|
5825
|
+
},
|
|
5826
|
+
duration: 220
|
|
5827
|
+
},
|
|
5828
|
+
{
|
|
5829
|
+
easing: "ease-out-cubic"
|
|
5830
|
+
}
|
|
5831
|
+
);
|
|
4390
5832
|
}
|
|
4391
|
-
}, [
|
|
5833
|
+
}, [selectedElement, visualizationMode]);
|
|
4392
5834
|
useEffect(() => {
|
|
4393
5835
|
const cy = cytoscapeRef.current;
|
|
4394
5836
|
if (!cy || !focusRequest) {
|
|
@@ -4400,6 +5842,10 @@ function OrganizationGraphCanvas({
|
|
|
4400
5842
|
}
|
|
4401
5843
|
const visibleNeighborhood = node.closedNeighborhood().not(".is-hidden");
|
|
4402
5844
|
cy.stop();
|
|
5845
|
+
if (shouldReduceGraphMotion()) {
|
|
5846
|
+
cy.fit(visibleNeighborhood.empty() ? node : visibleNeighborhood, 72);
|
|
5847
|
+
return;
|
|
5848
|
+
}
|
|
4403
5849
|
cy.animate(
|
|
4404
5850
|
{
|
|
4405
5851
|
fit: {
|
|
@@ -4427,17 +5873,71 @@ function OrganizationGraphCanvas({
|
|
|
4427
5873
|
},
|
|
4428
5874
|
children: [
|
|
4429
5875
|
/* @__PURE__ */ jsx(Box, { ref: containerRef, style: { width: "100%", height: "100%" } }),
|
|
5876
|
+
overlayLabels.length > 0 && /* @__PURE__ */ jsx(
|
|
5877
|
+
Box,
|
|
5878
|
+
{
|
|
5879
|
+
"aria-hidden": true,
|
|
5880
|
+
style: {
|
|
5881
|
+
position: "absolute",
|
|
5882
|
+
inset: 0,
|
|
5883
|
+
pointerEvents: "none",
|
|
5884
|
+
overflow: "hidden",
|
|
5885
|
+
zIndex: 1
|
|
5886
|
+
},
|
|
5887
|
+
children: overlayLabels.map((label) => {
|
|
5888
|
+
const tint = DOMAIN_ZONE_TINT_COLOR[label.domain] ?? "#868e96";
|
|
5889
|
+
return /* @__PURE__ */ jsx(
|
|
5890
|
+
"div",
|
|
5891
|
+
{
|
|
5892
|
+
ref: (element) => {
|
|
5893
|
+
if (element) {
|
|
5894
|
+
overlayLabelElementsRef.current.set(label.domain, element);
|
|
5895
|
+
const cy = cytoscapeRef.current;
|
|
5896
|
+
if (cy) {
|
|
5897
|
+
syncOverlayLabelPositions(cy, overlayLabelsRef.current, overlayLabelElementsRef.current);
|
|
5898
|
+
}
|
|
5899
|
+
} else {
|
|
5900
|
+
overlayLabelElementsRef.current.delete(label.domain);
|
|
5901
|
+
}
|
|
5902
|
+
},
|
|
5903
|
+
style: {
|
|
5904
|
+
position: "absolute",
|
|
5905
|
+
left: 0,
|
|
5906
|
+
top: 0,
|
|
5907
|
+
transform: "translate(-9999px, -9999px)",
|
|
5908
|
+
willChange: "transform",
|
|
5909
|
+
fontSize: 11,
|
|
5910
|
+
fontWeight: 600,
|
|
5911
|
+
letterSpacing: "0.06em",
|
|
5912
|
+
textTransform: "uppercase",
|
|
5913
|
+
color: tint,
|
|
5914
|
+
opacity: 0.55,
|
|
5915
|
+
whiteSpace: "nowrap",
|
|
5916
|
+
textShadow: "0 1px 2px var(--color-background, rgba(0,0,0,0.4))"
|
|
5917
|
+
},
|
|
5918
|
+
children: label.text
|
|
5919
|
+
},
|
|
5920
|
+
label.domain
|
|
5921
|
+
);
|
|
5922
|
+
})
|
|
5923
|
+
}
|
|
5924
|
+
),
|
|
4430
5925
|
/* @__PURE__ */ jsxs(
|
|
4431
5926
|
Group,
|
|
4432
5927
|
{
|
|
4433
|
-
gap:
|
|
5928
|
+
gap: 4,
|
|
4434
5929
|
wrap: "nowrap",
|
|
4435
5930
|
style: {
|
|
4436
5931
|
position: "absolute",
|
|
4437
5932
|
top: 12,
|
|
4438
5933
|
right: 12,
|
|
4439
5934
|
zIndex: 2,
|
|
4440
|
-
maxWidth: "calc(100% - 24px)"
|
|
5935
|
+
maxWidth: "calc(100% - 24px)",
|
|
5936
|
+
background: "var(--glass-background, rgba(11,16,21,0.88))",
|
|
5937
|
+
backdropFilter: "var(--glass-blur, blur(8px))",
|
|
5938
|
+
border: "1px solid var(--color-border)",
|
|
5939
|
+
borderRadius: "var(--mantine-radius-md)",
|
|
5940
|
+
padding: 4
|
|
4441
5941
|
},
|
|
4442
5942
|
children: [
|
|
4443
5943
|
toolbar,
|
|
@@ -4515,7 +6015,7 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4515
6015
|
const setSelectedNodeId = useCommandViewStore((state) => state.setSelectedNodeId);
|
|
4516
6016
|
const visualizationMode = useCommandViewStore((state) => state.visualizationMode);
|
|
4517
6017
|
const setVisualizationMode = useCommandViewStore((state) => state.setVisualizationMode);
|
|
4518
|
-
const effectiveVisualizationMode = visualizationMode
|
|
6018
|
+
const effectiveVisualizationMode = visualizationMode;
|
|
4519
6019
|
const resourcesHidden = useCommandViewStore((state) => state.resourcesHidden);
|
|
4520
6020
|
const setResourcesHidden = useCommandViewStore((state) => state.setResourcesHidden);
|
|
4521
6021
|
const diagnosticsHidden = useCommandViewStore((state) => state.diagnosticsHidden);
|
|
@@ -4525,9 +6025,17 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4525
6025
|
const setRevealedIds = useCommandViewStore((state) => state.setRevealedIds);
|
|
4526
6026
|
const clearRevealedIds = useCommandViewStore((state) => state.clearRevealedIds);
|
|
4527
6027
|
const markVisibilityInteraction = useCommandViewStore((state) => state.markVisibilityInteraction);
|
|
6028
|
+
const lastOpenBottomTab = useCommandViewStore((state) => state.lastOpenBottomTab);
|
|
6029
|
+
const setLastOpenBottomTab = useCommandViewStore((state) => state.setLastOpenBottomTab);
|
|
6030
|
+
const expandedClusterDomains = useCommandViewStore((state) => state.expandedClusterDomains);
|
|
6031
|
+
const toggleClusterDomain = useCommandViewStore((state) => state.toggleClusterDomain);
|
|
6032
|
+
const exploreExpandedNodeIds = useCommandViewStore((state) => state.expandedNodeIds);
|
|
6033
|
+
const toggleNodeExpansion = useCommandViewStore((state) => state.toggleNodeExpansion);
|
|
4528
6034
|
const lensConfig = useMemo(() => getOrganizationGraphLensConfig(lens), [lens]);
|
|
4529
6035
|
const [mode, setMode] = useState(lensConfig.initialMode);
|
|
4530
|
-
const [activePanelTab, setActivePanelTab] = useState(
|
|
6036
|
+
const [activePanelTab, setActivePanelTab] = useState(
|
|
6037
|
+
lens === "command-view" ? lastOpenBottomTab : "controls"
|
|
6038
|
+
);
|
|
4531
6039
|
const [selectedElement, setSelectedElement] = useState(null);
|
|
4532
6040
|
const [focusRequest, setFocusRequest] = useState(null);
|
|
4533
6041
|
const [pathTraceSelection, setPathTraceSelection] = useState(EMPTY_TRACE_SELECTION);
|
|
@@ -4535,6 +6043,15 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4535
6043
|
const [expandAroundPreview, setExpandAroundPreview] = useState(null);
|
|
4536
6044
|
const [appliedExpandAroundNodeIds, setAppliedExpandAroundNodeIds] = useState(EMPTY_EXPANDED_NODE_IDS);
|
|
4537
6045
|
const [appliedExpandAroundEdgeIds, setAppliedExpandAroundEdgeIds] = useState(EMPTY_EXPANDED_EDGE_IDS);
|
|
6046
|
+
const [visualizationParameters, setVisualizationParameters] = useState(
|
|
6047
|
+
() => getDefaultParameters(visualizationMode)
|
|
6048
|
+
);
|
|
6049
|
+
const forceParams = visualizationParameters.mode === "force" ? visualizationParameters : null;
|
|
6050
|
+
const { runLayout: runForceLayout } = useForceLayoutController(
|
|
6051
|
+
effectiveVisualizationMode === "force" ? forceParams : null
|
|
6052
|
+
);
|
|
6053
|
+
const canvasCytoscapeRef = useRef(null);
|
|
6054
|
+
const [legendDismissed, setLegendDismissed] = useState(false);
|
|
4538
6055
|
const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
|
|
4539
6056
|
const toolbarResetValue = useMemo(
|
|
4540
6057
|
() => createOrganizationGraphFilters(lensConfig.initialFilters),
|
|
@@ -4545,10 +6062,9 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4545
6062
|
const themeSignature = Object.values(rawThemeTokens).join("|");
|
|
4546
6063
|
const themeTokens = useMemo(() => rawThemeTokens, [themeSignature]);
|
|
4547
6064
|
useEffect(() => {
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
}, [setVisualizationMode, visualizationMode]);
|
|
6065
|
+
setVisualizationParameters(getDefaultParameters(visualizationMode));
|
|
6066
|
+
setLegendDismissed(false);
|
|
6067
|
+
}, [visualizationMode]);
|
|
4552
6068
|
const baseGraph = useMemo(() => {
|
|
4553
6069
|
if (!organizationModel) {
|
|
4554
6070
|
return null;
|
|
@@ -4790,6 +6306,9 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4790
6306
|
if (!graph || !selectedElement) {
|
|
4791
6307
|
return;
|
|
4792
6308
|
}
|
|
6309
|
+
if (selectedElement.type === "node" && (selectedElement.id === EXPLORE_OM_ROOT_ID || selectedElement.id.startsWith("centroid:"))) {
|
|
6310
|
+
return;
|
|
6311
|
+
}
|
|
4793
6312
|
const elementExists = selectedElement.type === "node" ? Boolean(visibleGraph?.nodes.some((node) => node.id === selectedElement.id)) : Boolean(visibleGraph?.edges.some((edge) => edge.id === selectedElement.id));
|
|
4794
6313
|
if (!elementExists) {
|
|
4795
6314
|
setSelectedElement(null);
|
|
@@ -4858,7 +6377,14 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4858
6377
|
) })
|
|
4859
6378
|
] });
|
|
4860
6379
|
}
|
|
4861
|
-
|
|
6380
|
+
const handleBottomTabChange = (tab) => {
|
|
6381
|
+
const next = tab === activePanelTab ? null : tab;
|
|
6382
|
+
setActivePanelTab(next);
|
|
6383
|
+
if (lens === "command-view") {
|
|
6384
|
+
setLastOpenBottomTab(next);
|
|
6385
|
+
}
|
|
6386
|
+
};
|
|
6387
|
+
return /* @__PURE__ */ jsx(Stack, { gap: "lg", style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsx(Tabs, { value: activePanelTab, onChange: handleBottomTabChange, keepMounted: false, children: /* @__PURE__ */ jsxs(
|
|
4862
6388
|
Paper,
|
|
4863
6389
|
{
|
|
4864
6390
|
withBorder: true,
|
|
@@ -4890,64 +6416,118 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4890
6416
|
}
|
|
4891
6417
|
}
|
|
4892
6418
|
) : null,
|
|
4893
|
-
/* @__PURE__ */
|
|
6419
|
+
/* @__PURE__ */ jsxs(
|
|
4894
6420
|
Box,
|
|
4895
6421
|
{
|
|
4896
6422
|
style: {
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
6423
|
+
// When the bottom panel is collapsed (activePanelTab === null) for command-view,
|
|
6424
|
+
// expand the canvas to ~94% viewport height to reclaim the freed space.
|
|
6425
|
+
height: lens === "command-view" ? activePanelTab === null ? "94vh" : "78vh" : "62vh",
|
|
6426
|
+
minHeight: lens === "command-view" ? 560 : 520,
|
|
6427
|
+
maxHeight: lens === "command-view" ? activePanelTab === null ? "96vh" : 860 : void 0,
|
|
4900
6428
|
position: "relative"
|
|
4901
6429
|
},
|
|
4902
|
-
children:
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
lens === "command-view" ?
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
6430
|
+
children: [
|
|
6431
|
+
renderGraph && renderGraph.nodes.length > 0 ? /* @__PURE__ */ jsx(
|
|
6432
|
+
OrganizationGraphCanvas,
|
|
6433
|
+
{
|
|
6434
|
+
graph: renderGraph,
|
|
6435
|
+
mode,
|
|
6436
|
+
visualizationMode: lens === "command-view" ? effectiveVisualizationMode : "network",
|
|
6437
|
+
selectedElement,
|
|
6438
|
+
traceResult: activeTraceResult,
|
|
6439
|
+
hiddenIds: EMPTY_GRAPH_HIDDEN_IDS,
|
|
6440
|
+
hiddenEdgeIds: EMPTY_GRAPH_HIDDEN_EDGE_IDS,
|
|
6441
|
+
expandedNodeIds: lens === "command-view" ? appliedExpandAroundNodeIds : EMPTY_EXPANDED_NODE_IDS,
|
|
6442
|
+
expandedEdgeIds: lens === "command-view" ? appliedExpandAroundEdgeIds : EMPTY_EXPANDED_EDGE_IDS,
|
|
6443
|
+
themeTokens,
|
|
6444
|
+
commandViewHealthByNodeId,
|
|
6445
|
+
focusRequest,
|
|
6446
|
+
parameters: lens === "command-view" ? visualizationParameters : void 0,
|
|
6447
|
+
runForceLayout,
|
|
6448
|
+
toolbar: /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
|
|
6449
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
6450
|
+
SegmentedControl,
|
|
6451
|
+
{
|
|
6452
|
+
value: effectiveVisualizationMode,
|
|
6453
|
+
onChange: (value) => setVisualizationMode(value),
|
|
6454
|
+
size: "xs",
|
|
6455
|
+
data: COMMAND_VIEW_VISUALIZATION_MODES
|
|
6456
|
+
}
|
|
6457
|
+
) : null,
|
|
6458
|
+
/* @__PURE__ */ jsx(
|
|
6459
|
+
SegmentedControl,
|
|
6460
|
+
{
|
|
6461
|
+
value: mode,
|
|
6462
|
+
onChange: (value) => setMode(value),
|
|
6463
|
+
size: "xs",
|
|
6464
|
+
data: [
|
|
6465
|
+
{ label: "Map", value: "map" },
|
|
6466
|
+
{ label: "Trace", value: "trace" },
|
|
6467
|
+
{ label: "Impact", value: "impact" }
|
|
6468
|
+
]
|
|
6469
|
+
}
|
|
6470
|
+
),
|
|
6471
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(
|
|
6472
|
+
VisualizationModeControls,
|
|
6473
|
+
{
|
|
6474
|
+
visualizationMode: effectiveVisualizationMode,
|
|
6475
|
+
parameters: visualizationParameters,
|
|
6476
|
+
onChangeParameters: setVisualizationParameters,
|
|
6477
|
+
onRerunForceLayout: () => {
|
|
6478
|
+
if (canvasCytoscapeRef.current) runForceLayout(canvasCytoscapeRef.current);
|
|
6479
|
+
}
|
|
6480
|
+
}
|
|
6481
|
+
) : null
|
|
6482
|
+
] }),
|
|
6483
|
+
expandedClusterDomains: lens === "command-view" ? expandedClusterDomains : [],
|
|
6484
|
+
exploreExpandedNodeIds: lens === "command-view" ? exploreExpandedNodeIds : /* @__PURE__ */ new Set(),
|
|
6485
|
+
onToggleClusterDomain: toggleClusterDomain,
|
|
6486
|
+
onToggleNodeExpansion: toggleNodeExpansion,
|
|
6487
|
+
onSelectElement: handleSelectElement
|
|
6488
|
+
}
|
|
6489
|
+
) : null,
|
|
6490
|
+
renderGraph && renderGraph.nodes.length > 0 && lens === "command-view" && !legendDismissed ? /* @__PURE__ */ jsx(
|
|
6491
|
+
Box,
|
|
6492
|
+
{
|
|
6493
|
+
style: {
|
|
6494
|
+
position: "absolute",
|
|
6495
|
+
bottom: 12,
|
|
6496
|
+
left: 12,
|
|
6497
|
+
zIndex: 2,
|
|
6498
|
+
pointerEvents: "auto"
|
|
6499
|
+
},
|
|
6500
|
+
children: /* @__PURE__ */ jsx(Legend, { visualizationMode: effectiveVisualizationMode, onDismiss: () => setLegendDismissed(true) })
|
|
6501
|
+
}
|
|
6502
|
+
) : null,
|
|
6503
|
+
renderGraph && renderGraph.nodes.length > 0 && lens === "command-view" && effectiveVisualizationMode === "explore" ? /* @__PURE__ */ jsx(
|
|
6504
|
+
Box,
|
|
6505
|
+
{
|
|
6506
|
+
style: {
|
|
6507
|
+
position: "absolute",
|
|
6508
|
+
top: 12,
|
|
6509
|
+
left: 12,
|
|
6510
|
+
zIndex: 2,
|
|
6511
|
+
maxWidth: "calc(100% - 24px)",
|
|
6512
|
+
background: "var(--glass-background, rgba(11,16,21,0.88))",
|
|
6513
|
+
backdropFilter: "var(--glass-blur, blur(8px))",
|
|
6514
|
+
border: "1px solid var(--color-border)",
|
|
6515
|
+
borderRadius: "var(--mantine-radius-md)",
|
|
6516
|
+
padding: "6px 10px",
|
|
6517
|
+
pointerEvents: "auto"
|
|
6518
|
+
},
|
|
6519
|
+
children: /* @__PURE__ */ jsx(ExploreBreadcrumb, {})
|
|
6520
|
+
}
|
|
6521
|
+
) : null,
|
|
6522
|
+
!renderGraph || renderGraph.nodes.length === 0 ? /* @__PURE__ */ jsx(
|
|
6523
|
+
EmptyState,
|
|
6524
|
+
{
|
|
6525
|
+
icon: IconTopologyStar3,
|
|
6526
|
+
title: "No graph elements match the current filters",
|
|
6527
|
+
description: lens === "command-view" && visibilityProjection.hiddenResourceCount > 0 ? "Reveal resources or adjust filters to bring graph elements back into view." : "Adjust the graph controls to bring semantic nodes, topology nodes, or relationship matches back into view."
|
|
6528
|
+
}
|
|
6529
|
+
) : null
|
|
6530
|
+
]
|
|
4951
6531
|
}
|
|
4952
6532
|
),
|
|
4953
6533
|
/* @__PURE__ */ jsx(Box, { p: "xs", children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "wrap", children: [
|
|
@@ -4957,7 +6537,8 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
4957
6537
|
lens === "command-view" ? null : /* @__PURE__ */ jsx(Tabs.Tab, { value: "controls", children: "Controls" }),
|
|
4958
6538
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "trace", children: "Trace" }),
|
|
4959
6539
|
/* @__PURE__ */ jsx(Tabs.Tab, { value: "details", children: "Details" }),
|
|
4960
|
-
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" })
|
|
6540
|
+
/* @__PURE__ */ jsx(Tabs.Tab, { value: "runtime", children: "Runtime" }),
|
|
6541
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(Tabs.Tab, { value: "filters", children: "Filters" }) : null
|
|
4961
6542
|
] })
|
|
4962
6543
|
] }),
|
|
4963
6544
|
/* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
|
|
@@ -5167,10 +6748,16 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
5167
6748
|
onClear: clearExpandAroundState
|
|
5168
6749
|
}
|
|
5169
6750
|
) : null,
|
|
6751
|
+
commandViewData,
|
|
5170
6752
|
onClearSelection: () => {
|
|
5171
6753
|
setSelectedElement(null);
|
|
5172
6754
|
clearRevealedIds();
|
|
5173
6755
|
clearExpandAroundState();
|
|
6756
|
+
},
|
|
6757
|
+
onSelectNode: (nodeId) => {
|
|
6758
|
+
setMode("map");
|
|
6759
|
+
setSelectedElement({ type: "node", id: nodeId });
|
|
6760
|
+
focusGraphNode(nodeId);
|
|
5174
6761
|
}
|
|
5175
6762
|
}
|
|
5176
6763
|
) }),
|
|
@@ -5218,7 +6805,28 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
|
|
|
5218
6805
|
"Topology bridge error: ",
|
|
5219
6806
|
error.message
|
|
5220
6807
|
] }) : null
|
|
5221
|
-
] }) })
|
|
6808
|
+
] }) }),
|
|
6809
|
+
lens === "command-view" ? /* @__PURE__ */ jsx(Tabs.Panel, { value: "filters", pt: 0, children: /* @__PURE__ */ jsx(
|
|
6810
|
+
FilterPanel,
|
|
6811
|
+
{
|
|
6812
|
+
filters,
|
|
6813
|
+
onChangeFilters: updateFilters,
|
|
6814
|
+
resetValue: toolbarResetValue,
|
|
6815
|
+
disabled: !baseGraph,
|
|
6816
|
+
commandViewData,
|
|
6817
|
+
lens: "command-view",
|
|
6818
|
+
resourcesHidden,
|
|
6819
|
+
diagnosticsHidden,
|
|
6820
|
+
onResourcesHiddenChange: handleResourcesHiddenChange,
|
|
6821
|
+
onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
|
|
6822
|
+
onRevealResources: revealAllResources,
|
|
6823
|
+
onResetFilters: handleResetFilters,
|
|
6824
|
+
visibilityCounts: visibilityProjection,
|
|
6825
|
+
graph: visibleGraph,
|
|
6826
|
+
baseGraph,
|
|
6827
|
+
layout: "stack"
|
|
6828
|
+
}
|
|
6829
|
+
) }) : null
|
|
5222
6830
|
]
|
|
5223
6831
|
}
|
|
5224
6832
|
)
|
|
@@ -6351,37 +7959,9 @@ function AgentListItem({ agent, isSelected, onAgentClick }) {
|
|
|
6351
7959
|
}
|
|
6352
7960
|
);
|
|
6353
7961
|
}
|
|
7962
|
+
|
|
7963
|
+
// src/features/operations/sidebar/OperationsSidebarTop.tsx
|
|
6354
7964
|
var OperationsSidebarTop = () => {
|
|
6355
|
-
const { currentPath, navigate } = useRouterContext();
|
|
6356
|
-
const theme = useMantineTheme();
|
|
6357
|
-
const isResourcesSection = currentPath.startsWith("/operations/resources");
|
|
6358
|
-
const isSessionsSection = currentPath.startsWith("/operations/sessions");
|
|
6359
|
-
const isCommandViewSection = currentPath.startsWith("/operations/command-view");
|
|
6360
|
-
if (isSessionsSection || isCommandViewSection) {
|
|
6361
|
-
return null;
|
|
6362
|
-
}
|
|
6363
|
-
if (isResourcesSection) {
|
|
6364
|
-
const isActive = currentPath === "/operations/resources";
|
|
6365
|
-
return /* @__PURE__ */ jsx(
|
|
6366
|
-
Box,
|
|
6367
|
-
{
|
|
6368
|
-
style: {
|
|
6369
|
-
padding: theme.spacing.sm,
|
|
6370
|
-
borderBottom: "1px solid var(--color-border)"
|
|
6371
|
-
},
|
|
6372
|
-
children: /* @__PURE__ */ jsx(
|
|
6373
|
-
NavigationButton,
|
|
6374
|
-
{
|
|
6375
|
-
icon: IconApps,
|
|
6376
|
-
label: "Resource Overview",
|
|
6377
|
-
isActive,
|
|
6378
|
-
hasActiveBackground: isActive,
|
|
6379
|
-
onClick: () => navigate("/operations/resources")
|
|
6380
|
-
}
|
|
6381
|
-
)
|
|
6382
|
-
}
|
|
6383
|
-
);
|
|
6384
|
-
}
|
|
6385
7965
|
return null;
|
|
6386
7966
|
};
|
|
6387
7967
|
|
|
@@ -6610,15 +8190,23 @@ var OperationsSidebar = () => {
|
|
|
6610
8190
|
function CommandQueueShell({ children }) {
|
|
6611
8191
|
return /* @__PURE__ */ jsx(SubshellContentContainer, { children });
|
|
6612
8192
|
}
|
|
6613
|
-
|
|
8193
|
+
function OperationsSidebarRouter() {
|
|
8194
|
+
const { currentPath } = useRouterContext();
|
|
8195
|
+
if (currentPath.startsWith("/knowledge/command-view")) {
|
|
8196
|
+
return null;
|
|
8197
|
+
}
|
|
8198
|
+
return /* @__PURE__ */ jsx(OperationsSidebar, {});
|
|
8199
|
+
}
|
|
8200
|
+
|
|
8201
|
+
// src/features/operations/manifest.ts
|
|
6614
8202
|
var defaultOperationsSidebarWidth = 250;
|
|
6615
8203
|
var operationsManifest = {
|
|
6616
8204
|
key: "operations",
|
|
6617
8205
|
featureId: "operations",
|
|
6618
8206
|
capabilityIds: ["knowledge.command-view"],
|
|
6619
8207
|
icon: IconCode,
|
|
6620
|
-
sidebar:
|
|
6621
|
-
sidebarWidth: ({ currentPath }) => currentPath.startsWith("/knowledge/command-view") ?
|
|
8208
|
+
sidebar: OperationsSidebarRouter,
|
|
8209
|
+
sidebarWidth: ({ currentPath }) => currentPath.startsWith("/knowledge/command-view") ? 0 : defaultOperationsSidebarWidth
|
|
6622
8210
|
};
|
|
6623
8211
|
|
|
6624
8212
|
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 };
|