@likec4/diagram 1.18.0 → 1.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/LICENSE +1 -1
  2. package/dist/LikeC4CustomColors.d.ts +7 -0
  3. package/dist/LikeC4CustomColors.js +30 -0
  4. package/dist/LikeC4Diagram.css.d.ts +5 -0
  5. package/dist/LikeC4Diagram.css.js +13 -0
  6. package/dist/LikeC4Diagram.d.ts +6 -0
  7. package/dist/LikeC4Diagram.js +194 -0
  8. package/dist/LikeC4Diagram.props.d.ts +166 -0
  9. package/dist/LikeC4ModelProvider.d.ts +9 -0
  10. package/dist/LikeC4ModelProvider.js +12 -0
  11. package/dist/LikeC4Search.css.d.ts +1 -0
  12. package/dist/LikeC4Search.css.js +5 -0
  13. package/dist/LikeC4Search.d.ts +2 -0
  14. package/dist/LikeC4Search.js +96 -0
  15. package/dist/StaticLikeC4Diagram.d.ts +3 -0
  16. package/dist/StaticLikeC4Diagram.js +41 -0
  17. package/dist/_virtual/_commonjsHelpers.js +6 -0
  18. package/dist/controls/Text.d.ts +2 -0
  19. package/dist/controls/Text.js +7 -0
  20. package/dist/controls/action-button-bar/ActionButtonBar.css.d.ts +1 -0
  21. package/dist/controls/action-button-bar/ActionButtonBar.css.js +5 -0
  22. package/dist/controls/action-button-bar/ActionButtonBar.d.ts +9 -0
  23. package/dist/controls/action-button-bar/ActionButtonBar.js +100 -0
  24. package/dist/controls/action-button-bar/useActionButtonBarCtx.d.ts +10 -0
  25. package/dist/controls/action-button-bar/useActionButtonBarCtx.js +9 -0
  26. package/dist/controls/action-buttons/ActionButton.css.d.ts +1 -0
  27. package/dist/controls/action-buttons/ActionButton.css.js +5 -0
  28. package/dist/controls/action-buttons/ActionButton.d.ts +9 -0
  29. package/dist/controls/action-buttons/ActionButton.js +66 -0
  30. package/dist/controls/action-buttons/ActionButtons.d.ts +12 -0
  31. package/dist/controls/action-buttons/ActionButtons.js +99 -0
  32. package/dist/globals.css.d.ts +1 -0
  33. package/dist/globals.css.js +92 -0
  34. package/dist/hooks/index.d.ts +5 -0
  35. package/dist/hooks/useDiagramState.d.ts +6 -0
  36. package/dist/hooks/useDiagramState.js +27 -0
  37. package/dist/hooks/useMantinePortalProps.d.ts +9 -0
  38. package/dist/hooks/useMantinePortalProps.js +9 -0
  39. package/dist/hooks/useSetState.d.ts +2 -0
  40. package/dist/hooks/useSetState.js +19 -0
  41. package/dist/hooks/useUpdateEffect.d.ts +4 -0
  42. package/dist/hooks/useUpdateEffect.js +32 -0
  43. package/dist/hooks/useXYFlow.d.ts +270 -0
  44. package/dist/hooks/useXYFlow.js +20 -0
  45. package/dist/index.d.ts +11 -0
  46. package/dist/index.js +25 -0
  47. package/dist/likec4model/LikeC4ModelContext.d.ts +3 -0
  48. package/dist/likec4model/LikeC4ModelContext.js +5 -0
  49. package/dist/likec4model/index.d.ts +2 -0
  50. package/dist/likec4model/useLikeC4ElementsTree.d.ts +12 -0
  51. package/dist/likec4model/useLikeC4ElementsTree.js +25 -0
  52. package/dist/likec4model/useLikeC4Model.d.ts +20 -0
  53. package/dist/likec4model/useLikeC4Model.js +55 -0
  54. package/dist/overlays/OverlayContext.d.ts +10 -0
  55. package/dist/overlays/OverlayContext.js +9 -0
  56. package/dist/overlays/Overlays.css.d.ts +3 -0
  57. package/dist/overlays/Overlays.css.js +7 -0
  58. package/dist/overlays/Overlays.d.ts +2 -0
  59. package/dist/overlays/Overlays.js +137 -0
  60. package/dist/overlays/edge-details/EdgeDetailsXYFlow.d.ts +5 -0
  61. package/dist/overlays/edge-details/EdgeDetailsXYFlow.js +185 -0
  62. package/dist/overlays/edge-details/SelectEdge.css.d.ts +7 -0
  63. package/dist/overlays/edge-details/SelectEdge.css.js +17 -0
  64. package/dist/overlays/edge-details/SelectEdge.d.ts +5 -0
  65. package/dist/overlays/edge-details/SelectEdge.js +129 -0
  66. package/dist/overlays/edge-details/_types.d.ts +14 -0
  67. package/dist/overlays/edge-details/use-layouted-edge-details.d.ts +21 -0
  68. package/dist/overlays/edge-details/use-layouted-edge-details.js +270 -0
  69. package/dist/overlays/edge-details/xyflow/CompoundNode.d.ts +5 -0
  70. package/dist/overlays/edge-details/xyflow/CompoundNode.js +76 -0
  71. package/dist/overlays/edge-details/xyflow/ElementNode.d.ts +5 -0
  72. package/dist/overlays/edge-details/xyflow/ElementNode.js +159 -0
  73. package/dist/overlays/edge-details/xyflow/RelationshipEdge.d.ts +3 -0
  74. package/dist/overlays/edge-details/xyflow/RelationshipEdge.js +84 -0
  75. package/dist/overlays/edge-details/xyflow/styles.css.d.ts +9 -0
  76. package/dist/overlays/edge-details/xyflow/styles.css.js +21 -0
  77. package/dist/overlays/element-details/ElementDetailsCard.css.d.ts +16 -0
  78. package/dist/overlays/element-details/ElementDetailsCard.css.js +33 -0
  79. package/dist/overlays/element-details/ElementDetailsCard.d.ts +7 -0
  80. package/dist/overlays/element-details/ElementDetailsCard.js +484 -0
  81. package/dist/overlays/element-details/TabPanelDeployments.css.d.ts +4 -0
  82. package/dist/overlays/element-details/TabPanelDeployments.css.js +11 -0
  83. package/dist/overlays/element-details/TabPanelDeployments.d.ts +7 -0
  84. package/dist/overlays/element-details/TabPanelDeployments.js +173 -0
  85. package/dist/overlays/element-details/TabPanelRelationships.css.d.ts +5 -0
  86. package/dist/overlays/element-details/TabPanelRelationships.css.js +11 -0
  87. package/dist/overlays/element-details/TabPanelRelationships.d.ts +8 -0
  88. package/dist/overlays/element-details/TabPanelRelationships.js +157 -0
  89. package/dist/overlays/element-details/TabPanelStructure.css.d.ts +2 -0
  90. package/dist/overlays/element-details/TabPanelStructure.css.js +7 -0
  91. package/dist/overlays/element-details/TabPanelStructure.d.ts +25 -0
  92. package/dist/overlays/element-details/TabPanelStructure.js +91 -0
  93. package/dist/overlays/index.d.ts +1 -0
  94. package/dist/overlays/relationships-of/RelationshipsOverlay.d.ts +5 -0
  95. package/dist/overlays/relationships-of/RelationshipsOverlay.js +193 -0
  96. package/dist/overlays/relationships-of/RelationshipsXYFlow.d.ts +19 -0
  97. package/dist/overlays/relationships-of/RelationshipsXYFlow.js +290 -0
  98. package/dist/overlays/relationships-of/SelectElement.css.d.ts +2 -0
  99. package/dist/overlays/relationships-of/SelectElement.css.js +7 -0
  100. package/dist/overlays/relationships-of/SelectElement.d.ts +7 -0
  101. package/dist/overlays/relationships-of/SelectElement.js +126 -0
  102. package/dist/overlays/relationships-of/_types.d.ts +28 -0
  103. package/dist/overlays/relationships-of/use-layouted-relationships.d.ts +22 -0
  104. package/dist/overlays/relationships-of/use-layouted-relationships.js +496 -0
  105. package/dist/overlays/relationships-of/xyflow/CompoundNode.d.ts +6 -0
  106. package/dist/overlays/relationships-of/xyflow/CompoundNode.js +120 -0
  107. package/dist/overlays/relationships-of/xyflow/ElementNode.d.ts +6 -0
  108. package/dist/overlays/relationships-of/xyflow/ElementNode.js +194 -0
  109. package/dist/overlays/relationships-of/xyflow/EmptyNode.d.ts +5 -0
  110. package/dist/overlays/relationships-of/xyflow/EmptyNode.js +18 -0
  111. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.d.ts +3 -0
  112. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.js +123 -0
  113. package/dist/overlays/relationships-of/xyflow/styles.css.d.ts +14 -0
  114. package/dist/overlays/relationships-of/xyflow/styles.css.js +24 -0
  115. package/dist/overlays/shared/xyflow/RelationshipEdge.css.d.ts +4 -0
  116. package/dist/overlays/shared/xyflow/RelationshipEdge.css.js +12 -0
  117. package/dist/overlays/shared/xyflow/_types.d.ts +77 -0
  118. package/dist/state/DiagramContext.d.ts +1609 -0
  119. package/dist/state/DiagramContext.js +101 -0
  120. package/dist/state/aligners.d.ts +42 -0
  121. package/dist/state/aligners.js +349 -0
  122. package/dist/state/diagram-to-xyflow.d.ts +11 -0
  123. package/dist/state/diagram-to-xyflow.js +113 -0
  124. package/dist/state/diagramStore.d.ts +1705 -0
  125. package/dist/state/diagramStore.js +808 -0
  126. package/dist/state/diagramStore.layout.d.ts +4 -0
  127. package/dist/state/diagramStore.layout.js +56 -0
  128. package/dist/style.css +1 -0
  129. package/dist/theme-vars.css.d.ts +72 -0
  130. package/dist/theme-vars.css.js +6 -0
  131. package/dist/theme-vars.css.ts.vanilla.css.js +1 -0
  132. package/dist/theme-vars.d.ts +3 -0
  133. package/dist/theme-vars.js +5 -0
  134. package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
  135. package/dist/ui/DiagramTitlePanel.css.js +11 -0
  136. package/dist/ui/DiagramTitlePanel.d.ts +1 -0
  137. package/dist/ui/DiagramTitlePanel.js +159 -0
  138. package/dist/ui/DynamicViewWalkthrough.css.d.ts +4 -0
  139. package/dist/ui/DynamicViewWalkthrough.css.js +11 -0
  140. package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
  141. package/dist/ui/DynamicViewWalkthrough.js +156 -0
  142. package/dist/ui/EnsureMantine.d.ts +7 -0
  143. package/dist/ui/EnsureMantine.js +14 -0
  144. package/dist/ui/FramerMotionConfig.d.ts +2 -0
  145. package/dist/ui/FramerMotionConfig.js +14 -0
  146. package/dist/ui/Link.d.ts +4 -0
  147. package/dist/ui/Link.js +36 -0
  148. package/dist/ui/notation/NotationPanel.css.d.ts +6 -0
  149. package/dist/ui/notation/NotationPanel.css.js +16 -0
  150. package/dist/ui/notation/NotationPanel.d.ts +1 -0
  151. package/dist/ui/notation/NotationPanel.js +250 -0
  152. package/dist/ui/notation/index.d.ts +1 -0
  153. package/dist/ui/top-left/ChangeAutoLayoutButton.d.ts +2 -0
  154. package/dist/ui/top-left/ChangeAutoLayoutButton.js +159 -0
  155. package/dist/ui/top-left/ManualLayoutToolsButton.d.ts +2 -0
  156. package/dist/ui/top-left/ManualLayoutToolsButton.js +137 -0
  157. package/dist/ui/top-left/TopLeftPanel.d.ts +4 -0
  158. package/dist/ui/top-left/TopLeftPanel.js +211 -0
  159. package/dist/ui/top-left/_shared.d.ts +7 -0
  160. package/dist/ui/top-left/_shared.js +22 -0
  161. package/dist/ui/top-left/styles.css.d.ts +8 -0
  162. package/dist/ui/top-left/styles.css.js +17 -0
  163. package/dist/utils/types.d.ts +8 -0
  164. package/dist/utils/vector.d.ts +24 -0
  165. package/dist/utils/vector.js +55 -0
  166. package/dist/xyflow/EdgeMarkers.d.ts +12 -0
  167. package/dist/xyflow/EdgeMarkers.js +192 -0
  168. package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -0
  169. package/dist/xyflow/FitviewOnDiagramChange.js +72 -0
  170. package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
  171. package/dist/xyflow/SelectEdgesOnNodeFocus.js +96 -0
  172. package/dist/xyflow/XYFlow.d.ts +8 -0
  173. package/dist/xyflow/XYFlow.js +145 -0
  174. package/dist/xyflow/XYFlowBackground.d.ts +10 -0
  175. package/dist/xyflow/XYFlowBackground.js +25 -0
  176. package/dist/xyflow/XYFlowInner.d.ts +8 -0
  177. package/dist/xyflow/XYFlowInner.js +41 -0
  178. package/dist/xyflow/const.d.ts +7 -0
  179. package/dist/xyflow/const.js +12 -0
  180. package/dist/xyflow/edges/EdgeLabel.d.ts +7 -0
  181. package/dist/xyflow/edges/EdgeLabel.js +160 -0
  182. package/dist/xyflow/edges/RelationshipEdge.d.ts +6 -0
  183. package/dist/xyflow/edges/RelationshipEdge.js +443 -0
  184. package/dist/xyflow/edges/RelationshipsDropdownMenu.css.d.ts +4 -0
  185. package/dist/xyflow/edges/RelationshipsDropdownMenu.css.js +11 -0
  186. package/dist/xyflow/edges/RelationshipsDropdownMenu.d.ts +13 -0
  187. package/dist/xyflow/edges/RelationshipsDropdownMenu.js +211 -0
  188. package/dist/xyflow/edges/edges.css.d.ts +17 -0
  189. package/dist/xyflow/edges/edges.css.js +37 -0
  190. package/dist/xyflow/edges/utils.d.ts +16 -0
  191. package/dist/xyflow/edges/utils.js +24 -0
  192. package/dist/xyflow/nodes/AnimateVariants.d.ts +1313 -0
  193. package/dist/xyflow/nodes/AnimateVariants.js +123 -0
  194. package/dist/xyflow/nodes/Node.css.d.ts +3 -0
  195. package/dist/xyflow/nodes/Node.css.js +9 -0
  196. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +14 -0
  197. package/dist/xyflow/nodes/compound/CompoundNode.css.js +27 -0
  198. package/dist/xyflow/nodes/compound/CompoundNode.d.ts +6 -0
  199. package/dist/xyflow/nodes/compound/CompoundNode.js +216 -0
  200. package/dist/xyflow/nodes/compound/index.d.ts +1 -0
  201. package/dist/xyflow/nodes/element/ElementLink.css.d.ts +3 -0
  202. package/dist/xyflow/nodes/element/ElementLink.d.ts +6 -0
  203. package/dist/xyflow/nodes/element/ElementNode.d.ts +6 -0
  204. package/dist/xyflow/nodes/element/ElementNode.js +190 -0
  205. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +17 -0
  206. package/dist/xyflow/nodes/element/ElementShapeSvg.js +175 -0
  207. package/dist/xyflow/nodes/element/element.css.d.ts +18 -0
  208. package/dist/xyflow/nodes/element/element.css.js +31 -0
  209. package/dist/xyflow/nodes/element/index.d.ts +1 -0
  210. package/dist/xyflow/nodes/shared/ElementIcon.d.ts +8 -0
  211. package/dist/xyflow/nodes/shared/ElementIcon.js +38 -0
  212. package/dist/xyflow/nodes/shared/Toolbar.d.ts +9 -0
  213. package/dist/xyflow/nodes/shared/Toolbar.js +436 -0
  214. package/dist/xyflow/types.d.ts +36 -0
  215. package/dist/xyflow/useLayoutConstraints.d.ts +42 -0
  216. package/dist/xyflow/useLayoutConstraints.js +226 -0
  217. package/dist/xyflow/useXYFlowEvents.d.ts +160 -0
  218. package/dist/xyflow/useXYFlowEvents.js +275 -0
  219. package/dist/xyflow/utils.d.ts +22 -0
  220. package/dist/xyflow/utils.js +72 -0
  221. package/package.json +34 -27
  222. package/src/LikeC4Diagram.tsx +4 -4
  223. package/src/LikeC4Search.css.ts +12 -0
  224. package/src/LikeC4Search.tsx +39 -90
  225. package/src/controls/Text.ts +5 -0
  226. package/src/controls/action-button-bar/ActionButtonBar.css.ts +13 -0
  227. package/src/controls/action-button-bar/ActionButtonBar.tsx +138 -0
  228. package/src/controls/action-button-bar/useActionButtonBarCtx.ts +13 -0
  229. package/src/controls/action-buttons/ActionButton.css.ts +29 -0
  230. package/src/controls/action-buttons/ActionButton.tsx +66 -0
  231. package/src/controls/action-buttons/ActionButtons.tsx +138 -0
  232. package/src/hooks/useXYFlow.ts +8 -8
  233. package/src/index.ts +12 -6
  234. package/src/likec4model/index.ts +12 -2
  235. package/src/overlays/edge-details/EdgeDetailsXYFlow.tsx +18 -12
  236. package/src/overlays/edge-details/_types.ts +13 -37
  237. package/src/overlays/edge-details/use-layouted-edge-details.ts +16 -14
  238. package/src/overlays/edge-details/xyflow/CompoundNode.tsx +3 -11
  239. package/src/overlays/edge-details/xyflow/ElementNode.tsx +4 -11
  240. package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +3 -3
  241. package/src/overlays/edge-details/xyflow/styles.css.ts +1 -59
  242. package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +23 -23
  243. package/src/overlays/relationships-of/_types.ts +20 -58
  244. package/src/overlays/relationships-of/use-layouted-relationships.ts +36 -40
  245. package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +9 -13
  246. package/src/overlays/relationships-of/xyflow/ElementNode.tsx +12 -15
  247. package/src/overlays/relationships-of/xyflow/EmptyNode.tsx +4 -7
  248. package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +16 -14
  249. package/src/overlays/shared/xyflow/RelationshipEdge.css.ts +60 -0
  250. package/src/overlays/shared/xyflow/_types.ts +87 -0
  251. package/src/state/diagram-to-xyflow.ts +6 -7
  252. package/src/state/diagramStore.layout.ts +3 -4
  253. package/src/state/diagramStore.ts +35 -37
  254. package/src/theme-vars.css.ts +81 -0
  255. package/src/theme-vars.ts +8 -81
  256. package/src/ui/DiagramTitlePanel.tsx +6 -6
  257. package/src/utils/types.ts +6 -0
  258. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +3 -3
  259. package/src/xyflow/XYFlow.tsx +2 -2
  260. package/src/xyflow/edges/EdgeLabel.tsx +25 -18
  261. package/src/xyflow/edges/RelationshipEdge.tsx +5 -3
  262. package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +3 -3
  263. package/src/xyflow/edges/edges.css.ts +68 -74
  264. package/src/xyflow/edges/utils.ts +6 -6
  265. package/src/xyflow/nodes/AnimateVariants.ts +143 -0
  266. package/src/xyflow/nodes/Node.css.ts +44 -0
  267. package/src/xyflow/nodes/compound/CompoundNode.css.ts +1 -64
  268. package/src/xyflow/nodes/compound/CompoundNode.tsx +69 -182
  269. package/src/xyflow/nodes/element/ElementLink.tsx +2 -3
  270. package/src/xyflow/nodes/element/ElementNode.tsx +64 -266
  271. package/src/xyflow/nodes/element/element.css.ts +0 -57
  272. package/src/xyflow/nodes/shared/Toolbar.tsx +30 -30
  273. package/src/xyflow/types.ts +48 -51
  274. package/src/xyflow/useLayoutConstraints.ts +9 -9
  275. package/src/xyflow/useXYFlowEvents.ts +13 -30
  276. package/src/xyflow/utils.ts +2 -2
  277. package/src/xyflow/nodes/use-animate-variants.tsx +0 -64
@@ -0,0 +1,484 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { invariant, isScopedElementView, isDeploymentView } from "@likec4/core";
3
+ import { Divider as Divider$1, Tooltip as Tooltip$1, Text, RemoveScroll, Card, FocusTrap, FocusTrapInitialFocus, Box, Group, CloseButton, Badge, Flex, ActionIconGroup, ActionIcon, Tabs, TabsList, TabsTab, TabsPanel, ScrollArea, Stack, UnstyledButton, ThemeIcon, CopyButton, Anchor, Code } from "@mantine/core";
4
+ import { useViewportSize, useSessionStorage } from "@mantine/hooks";
5
+ import { IconExternalLink, IconFileSymlink, IconZoomScan, IconStack2, IconCheck, IconCopy } from "@tabler/icons-react";
6
+ import clsx from "clsx";
7
+ import { useDragControls, useMotionValue, m } from "framer-motion";
8
+ import { memo, useCallback, useRef, useEffect } from "react";
9
+ import { pick, pipe, map, partition, find, only, clamp, isNullish } from "remeda";
10
+ import { useOverlayDialog } from "../OverlayContext.js";
11
+ import { propertyLabel, dialog, card, cardHeader, title, tabsRoot, tabsList, tabsTab, tabsPanel, propertiesGrid, resizeHandle, elementIcon, viewButton, viewButtonTitle, elementLink } from "./ElementDetailsCard.css.js";
12
+ import { TabPanelDeployments } from "./TabPanelDeployments.js";
13
+ import { TabPanelRelationships } from "./TabPanelRelationships.js";
14
+ import { TabPanelStructure } from "./TabPanelStructure.js";
15
+ import { useXYFlow, useXYInternalNode } from "../../hooks/useXYFlow.js";
16
+ import { useLikeC4CurrentViewModel } from "../../likec4model/useLikeC4Model.js";
17
+ import { useDiagramStoreApi, useDiagramState } from "../../hooks/useDiagramState.js";
18
+ const Divider = Divider$1.withProps({
19
+ mb: 8,
20
+ labelPosition: "left",
21
+ variant: "dashed"
22
+ });
23
+ const Tooltip = Tooltip$1.withProps({
24
+ color: "dark",
25
+ fz: "xs",
26
+ openDelay: 400,
27
+ closeDelay: 150,
28
+ label: "",
29
+ children: null,
30
+ offset: 4
31
+ });
32
+ const SmallLabel = Text.withProps({
33
+ component: "div",
34
+ fz: 11,
35
+ fw: 500,
36
+ c: "dimmed",
37
+ lh: 1
38
+ });
39
+ const PropertyLabel = Text.withProps({
40
+ component: "div",
41
+ fz: "xs",
42
+ c: "dimmed",
43
+ className: propertyLabel
44
+ });
45
+ const MIN_PADDING = 24;
46
+ const TABS = ["Properties", "Relationships", "Views", "Structure", "Deployments"];
47
+ const ElementDetailsCard = memo(({ fqn }) => {
48
+ var _a;
49
+ const windowSize = useViewportSize();
50
+ const windowWidth = windowSize.width || window.innerWidth || 1200, windowHeight = windowSize.height || window.innerHeight || 800;
51
+ const xyflow = useXYFlow();
52
+ const xynode = useXYInternalNode(fqn);
53
+ invariant(xynode, `XYNode with id ${fqn} not found`);
54
+ const overlay = useOverlayDialog();
55
+ const [activeTab, setActiveTab] = useSessionStorage({
56
+ key: `likec4:element-details:active-tab`,
57
+ defaultValue: "Properties"
58
+ });
59
+ const diagramApi = useDiagramStoreApi();
60
+ const viewModel = useLikeC4CurrentViewModel();
61
+ const {
62
+ view: currentView,
63
+ renderIcon,
64
+ onOpenSource
65
+ } = useDiagramState(pick(["view", "renderIcon", "onNavigateTo", "onOpenSource"]));
66
+ const diagramNode = currentView.nodes.find((n) => n.id === fqn);
67
+ invariant(diagramNode, `DiagramNode with fqn ${fqn} not found`);
68
+ const nodeModel = viewModel.findNode(fqn);
69
+ invariant(nodeModel && nodeModel.hasElement(), `NodeModel with fqn ${fqn} not found`);
70
+ const elementModel = nodeModel.element;
71
+ const viewId = viewModel.id;
72
+ const elementIcon2 = ElementIcon({
73
+ element: nodeModel.$node,
74
+ viewId,
75
+ renderIcon
76
+ });
77
+ const [viewsOf, otherViews] = pipe(
78
+ [...elementModel.views()],
79
+ map((v) => v.$view),
80
+ partition((view) => {
81
+ const v = view;
82
+ return isScopedElementView(v) && v.viewOf === fqn;
83
+ })
84
+ );
85
+ const defaultView = ((_a = nodeModel.navigateTo) == null ? void 0 : _a.$view) ?? find(viewsOf, (v) => v.id !== viewModel.id) ?? null;
86
+ const defaultLink = only(nodeModel.links);
87
+ const onNavigateToCb = useCallback((toView, e) => {
88
+ e == null ? void 0 : e.stopPropagation();
89
+ const { onNavigateTo } = diagramApi.getState();
90
+ if (!onNavigateTo) {
91
+ return;
92
+ }
93
+ overlay.close(() => {
94
+ diagramApi.setState({
95
+ lastOnNavigate: {
96
+ fromView: viewModel.id,
97
+ toView,
98
+ fromNode: fqn
99
+ }
100
+ });
101
+ onNavigateTo(toView);
102
+ });
103
+ }, [fqn, viewModel.id]);
104
+ const controls = useDragControls();
105
+ const isCompound = nodeModel.children.length > 0;
106
+ const fromPositon = xyflow.flowToScreenPosition({
107
+ x: xynode.internals.positionAbsolute.x + diagramNode.width / 2,
108
+ y: xynode.internals.positionAbsolute.y + (isCompound ? 0 : diagramNode.height / 2)
109
+ });
110
+ const _width = Math.min(700, windowWidth - MIN_PADDING * 2);
111
+ const _height = Math.min(650, windowHeight - MIN_PADDING * 2);
112
+ const left = Math.round(
113
+ clamp(fromPositon.x - _width / 2, {
114
+ min: MIN_PADDING,
115
+ max: windowWidth - _width - MIN_PADDING
116
+ })
117
+ );
118
+ const top = Math.round(
119
+ clamp(fromPositon.y - (isCompound ? 0 : 60), {
120
+ min: MIN_PADDING,
121
+ max: windowHeight - _height - MIN_PADDING
122
+ })
123
+ );
124
+ const width = useMotionValue(_width);
125
+ const height = useMotionValue(_height);
126
+ const handleDrag = useCallback((_, info) => {
127
+ width.set(Math.max(width.get() + info.delta.x, 320));
128
+ height.set(Math.max(height.get() + info.delta.y, 300));
129
+ }, []);
130
+ const ref = useRef(null);
131
+ useEffect(() => {
132
+ var _a2;
133
+ (_a2 = ref.current) == null ? void 0 : _a2.showModal();
134
+ }, []);
135
+ return /* @__PURE__ */ jsx(
136
+ m.dialog,
137
+ {
138
+ ref,
139
+ className: dialog,
140
+ initial: {
141
+ "--backdrop-blur": "0px",
142
+ "--backdrop-opacity": "0%"
143
+ },
144
+ animate: {
145
+ "--backdrop-blur": "1px",
146
+ "--backdrop-opacity": "50%"
147
+ },
148
+ exit: {
149
+ "--backdrop-blur": "0px",
150
+ "--backdrop-opacity": "0%"
151
+ },
152
+ onClick: (e) => {
153
+ var _a2, _b;
154
+ if (((_b = (_a2 = e.target) == null ? void 0 : _a2.nodeName) == null ? void 0 : _b.toUpperCase()) === "DIALOG") {
155
+ e.stopPropagation();
156
+ overlay.close();
157
+ }
158
+ },
159
+ onClose: (e) => {
160
+ e.stopPropagation();
161
+ overlay.close();
162
+ },
163
+ children: /* @__PURE__ */ jsx(RemoveScroll, { forwardProps: true, children: /* @__PURE__ */ jsx(
164
+ Card,
165
+ {
166
+ drag: true,
167
+ dragElastic: 0,
168
+ dragMomentum: false,
169
+ dragListener: false,
170
+ dragControls: controls,
171
+ withBorder: true,
172
+ shadow: "md",
173
+ component: m.div,
174
+ className: card,
175
+ layoutId: `${viewId}:element:${fqn}`,
176
+ initial: {
177
+ top,
178
+ left,
179
+ width: _width,
180
+ height: _height,
181
+ opacity: 0
182
+ },
183
+ animate: {
184
+ opacity: 1
185
+ },
186
+ exit: {
187
+ opacity: 0
188
+ },
189
+ style: {
190
+ // `style` prop in Mantine doesn't accept motion values
191
+ width,
192
+ height
193
+ },
194
+ onKeyDown: (e) => {
195
+ if (e.key === "Escape") {
196
+ e.preventDefault();
197
+ e.stopPropagation();
198
+ overlay.close();
199
+ }
200
+ },
201
+ "data-likec4-color": nodeModel.color,
202
+ children: /* @__PURE__ */ jsxs(FocusTrap, { children: [
203
+ /* @__PURE__ */ jsx(FocusTrapInitialFocus, {}),
204
+ /* @__PURE__ */ jsxs(
205
+ Box,
206
+ {
207
+ className: cardHeader,
208
+ onPointerDown: (e) => controls.start(e),
209
+ children: [
210
+ /* @__PURE__ */ jsxs(Group, { align: "start", justify: "space-between", gap: "sm", mb: "sm", wrap: "nowrap", children: [
211
+ /* @__PURE__ */ jsxs(Group, { align: "start", gap: "sm", style: { cursor: "default" }, wrap: "nowrap", children: [
212
+ elementIcon2,
213
+ /* @__PURE__ */ jsxs(Box, { children: [
214
+ /* @__PURE__ */ jsx(
215
+ Text,
216
+ {
217
+ component: m.div,
218
+ layout: "position",
219
+ layoutId: `${viewId}:element:title:${fqn}`,
220
+ className: title,
221
+ children: elementModel.title
222
+ }
223
+ ),
224
+ nodeModel.$node.notation && /* @__PURE__ */ jsx(Text, { component: "div", c: "dimmed", fz: "sm", fw: 500, lh: 1.3, lineClamp: 1, children: nodeModel.$node.notation })
225
+ ] })
226
+ ] }),
227
+ /* @__PURE__ */ jsx(
228
+ CloseButton,
229
+ {
230
+ size: "lg",
231
+ onClick: (e) => {
232
+ e.stopPropagation();
233
+ overlay.close();
234
+ }
235
+ }
236
+ )
237
+ ] }),
238
+ /* @__PURE__ */ jsxs(Group, { align: "baseline", gap: "sm", wrap: "nowrap", children: [
239
+ /* @__PURE__ */ jsxs(Box, { children: [
240
+ /* @__PURE__ */ jsx(SmallLabel, { children: "kind" }),
241
+ /* @__PURE__ */ jsx(Badge, { radius: "sm", size: "sm", fw: 600, color: "gray", children: elementModel.kind })
242
+ ] }),
243
+ /* @__PURE__ */ jsxs(Box, { flex: 1, children: [
244
+ /* @__PURE__ */ jsx(SmallLabel, { children: "tags" }),
245
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, flex: 1, mt: 6, children: [
246
+ elementModel.tags.map((tag) => /* @__PURE__ */ jsxs(Badge, { radius: "sm", size: "sm", fw: 600, variant: "gradient", children: [
247
+ "#",
248
+ tag
249
+ ] }, tag)),
250
+ elementModel.tags.length === 0 && /* @__PURE__ */ jsx(Badge, { radius: "sm", size: "sm", fw: 600, color: "gray", children: "—" })
251
+ ] })
252
+ ] }),
253
+ /* @__PURE__ */ jsxs(
254
+ ActionIconGroup,
255
+ {
256
+ style: {
257
+ alignSelf: "flex-end"
258
+ },
259
+ children: [
260
+ defaultLink && /* @__PURE__ */ jsx(
261
+ ActionIcon,
262
+ {
263
+ component: "a",
264
+ href: defaultLink.url,
265
+ target: "_blank",
266
+ size: "lg",
267
+ variant: "default",
268
+ radius: "sm",
269
+ children: /* @__PURE__ */ jsx(IconExternalLink, { stroke: 1.6, style: { width: "65%" } })
270
+ }
271
+ ),
272
+ onOpenSource && /* @__PURE__ */ jsx(Tooltip, { label: "Open source", children: /* @__PURE__ */ jsx(
273
+ ActionIcon,
274
+ {
275
+ size: "lg",
276
+ variant: "default",
277
+ radius: "sm",
278
+ onClick: (e) => {
279
+ var _a2, _b;
280
+ e.stopPropagation();
281
+ (_b = (_a2 = diagramApi.getState()).onOpenSource) == null ? void 0 : _b.call(_a2, {
282
+ element: elementModel.id
283
+ });
284
+ },
285
+ children: /* @__PURE__ */ jsx(IconFileSymlink, { stroke: 1.8, style: { width: "62%" } })
286
+ }
287
+ ) }),
288
+ defaultView && /* @__PURE__ */ jsx(Tooltip, { label: "Open default view", children: /* @__PURE__ */ jsx(
289
+ ActionIcon,
290
+ {
291
+ size: "lg",
292
+ variant: "default",
293
+ radius: "sm",
294
+ onClick: (e) => {
295
+ onNavigateToCb(defaultView.id, e);
296
+ },
297
+ children: /* @__PURE__ */ jsx(IconZoomScan, { style: { width: "70%" } })
298
+ }
299
+ ) })
300
+ ]
301
+ }
302
+ )
303
+ ] })
304
+ ]
305
+ }
306
+ ),
307
+ /* @__PURE__ */ jsxs(
308
+ Tabs,
309
+ {
310
+ value: activeTab,
311
+ onChange: (v) => setActiveTab(v),
312
+ variant: "none",
313
+ classNames: {
314
+ root: tabsRoot,
315
+ list: tabsList,
316
+ tab: tabsTab,
317
+ panel: tabsPanel
318
+ },
319
+ children: [
320
+ /* @__PURE__ */ jsx(TabsList, { children: TABS.map((tab) => /* @__PURE__ */ jsx(TabsTab, { value: tab, children: tab }, tab)) }),
321
+ /* @__PURE__ */ jsx(TabsPanel, { value: "Properties", children: /* @__PURE__ */ jsx(ScrollArea, { scrollbars: "y", type: "auto", children: /* @__PURE__ */ jsxs(Box, { className: propertiesGrid, pt: "xs", children: [
322
+ /* @__PURE__ */ jsx(ElementProperty, { title: "description", emptyValue: "no description", children: elementModel.description }),
323
+ elementModel.technology && /* @__PURE__ */ jsx(ElementProperty, { title: "technology", children: elementModel.technology }),
324
+ elementModel.links.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
325
+ /* @__PURE__ */ jsx(PropertyLabel, { children: "links" }),
326
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", align: "flex-start", children: elementModel.links.map((link, i) => /* @__PURE__ */ jsx(ElementLink, { value: link }, i)) })
327
+ ] }),
328
+ elementModel.$element.metadata && /* @__PURE__ */ jsx(ElementMetata, { value: elementModel.$element.metadata })
329
+ ] }) }) }),
330
+ /* @__PURE__ */ jsx(TabsPanel, { value: "Relationships", children: activeTab === "Relationships" && /* @__PURE__ */ jsx(
331
+ TabPanelRelationships,
332
+ {
333
+ element: elementModel,
334
+ node: nodeModel,
335
+ currentView
336
+ }
337
+ ) }),
338
+ /* @__PURE__ */ jsx(TabsPanel, { value: "Views", children: /* @__PURE__ */ jsx(ScrollArea, { scrollbars: "y", type: "auto", children: /* @__PURE__ */ jsxs(Stack, { gap: "lg", children: [
339
+ viewsOf.length > 0 && /* @__PURE__ */ jsxs(Box, { children: [
340
+ /* @__PURE__ */ jsx(Divider, { label: "views of the element (scoped)" }),
341
+ /* @__PURE__ */ jsx(Stack, { gap: "sm", children: viewsOf.map((view) => /* @__PURE__ */ jsx(
342
+ ViewButton,
343
+ {
344
+ view,
345
+ onNavigateTo: onNavigateToCb
346
+ },
347
+ view.id
348
+ )) })
349
+ ] }),
350
+ otherViews.length > 0 && /* @__PURE__ */ jsxs(Box, { children: [
351
+ /* @__PURE__ */ jsx(Divider, { label: "views including this element" }),
352
+ /* @__PURE__ */ jsx(Stack, { gap: "sm", children: otherViews.map((view) => /* @__PURE__ */ jsx(
353
+ ViewButton,
354
+ {
355
+ view,
356
+ onNavigateTo: onNavigateToCb
357
+ },
358
+ view.id
359
+ )) })
360
+ ] })
361
+ ] }) }) }),
362
+ /* @__PURE__ */ jsx(TabsPanel, { value: "Structure", children: /* @__PURE__ */ jsx(ScrollArea, { scrollbars: "y", type: "auto", children: /* @__PURE__ */ jsx(TabPanelStructure, { element: elementModel }) }) }),
363
+ /* @__PURE__ */ jsx(TabsPanel, { value: "Deployments", children: /* @__PURE__ */ jsx(ScrollArea, { scrollbars: "y", type: "auto", children: /* @__PURE__ */ jsx(TabPanelDeployments, { elementFqn: elementModel.id }) }) })
364
+ ]
365
+ }
366
+ ),
367
+ /* @__PURE__ */ jsx(
368
+ m.div,
369
+ {
370
+ className: resizeHandle,
371
+ drag: true,
372
+ dragElastic: 0,
373
+ dragMomentum: false,
374
+ onDrag: handleDrag,
375
+ dragConstraints: { top: 0, left: 0, right: 0, bottom: 0 }
376
+ }
377
+ )
378
+ ] })
379
+ }
380
+ ) })
381
+ }
382
+ );
383
+ });
384
+ ElementDetailsCard.displayName = "ElementDetailsCard";
385
+ const ElementIcon = ({ element, viewId, renderIcon: RenderIcon }) => {
386
+ if (!element.icon || element.icon === "none") {
387
+ return null;
388
+ }
389
+ let icon = null;
390
+ if (element.icon.startsWith("http://") || element.icon.startsWith("https://")) {
391
+ icon = /* @__PURE__ */ jsx("img", { src: element.icon, alt: element.title });
392
+ } else if (RenderIcon) {
393
+ icon = /* @__PURE__ */ jsx(RenderIcon, { node: element });
394
+ }
395
+ if (!icon) {
396
+ return null;
397
+ }
398
+ return /* @__PURE__ */ jsx(
399
+ m.div,
400
+ {
401
+ layoutId: `${viewId}:element:icon:${element.id}`,
402
+ className: clsx(
403
+ elementIcon,
404
+ "likec4-element-icon"
405
+ ),
406
+ "data-likec4-icon": element.icon,
407
+ children: icon
408
+ }
409
+ );
410
+ };
411
+ const ViewButton = ({
412
+ view,
413
+ onNavigateTo
414
+ }) => {
415
+ return /* @__PURE__ */ jsx(UnstyledButton, { className: viewButton, onClick: (e) => onNavigateTo(view.id, e), children: /* @__PURE__ */ jsxs(Group, { gap: 6, align: "start", wrap: "nowrap", children: [
416
+ /* @__PURE__ */ jsx(ThemeIcon, { size: "sm", variant: "transparent", children: isDeploymentView(view) ? /* @__PURE__ */ jsx(IconStack2, { stroke: 1.8 }) : /* @__PURE__ */ jsx(IconZoomScan, { stroke: 1.8 }) }),
417
+ /* @__PURE__ */ jsxs(Box, { children: [
418
+ /* @__PURE__ */ jsx(Text, { component: "div", className: viewButtonTitle, lineClamp: 1, children: view.title || "untitled" }),
419
+ view.description && /* @__PURE__ */ jsx(Text, { component: "div", mt: 2, fz: "xs", c: "dimmed", lh: 1.4, lineClamp: 1, children: view.description })
420
+ ] })
421
+ ] }) });
422
+ };
423
+ function ElementProperty({
424
+ title: title2,
425
+ emptyValue = `undefined`,
426
+ children,
427
+ style,
428
+ ...props
429
+ }) {
430
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
431
+ /* @__PURE__ */ jsx(PropertyLabel, { children: title2 }),
432
+ /* @__PURE__ */ jsx(
433
+ Text,
434
+ {
435
+ component: "div",
436
+ ...isNullish(children) && { c: "dimmed" },
437
+ fz: "md",
438
+ style: {
439
+ whiteSpace: "preserve-breaks",
440
+ ...style
441
+ },
442
+ ...props,
443
+ children: children || emptyValue
444
+ }
445
+ )
446
+ ] });
447
+ }
448
+ function ElementLink({
449
+ value
450
+ }) {
451
+ const url = new URL(value.url, window.location.href).toString();
452
+ return /* @__PURE__ */ jsx(CopyButton, { value: url, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Anchor, { href: url, target: "_blank", underline: "never", className: elementLink, children: /* @__PURE__ */ jsxs(Group, { gap: 4, align: "center", wrap: "nowrap", children: [
453
+ /* @__PURE__ */ jsx(
454
+ ActionIcon,
455
+ {
456
+ tabIndex: -1,
457
+ size: 24,
458
+ variant: copied ? "light" : "subtle",
459
+ color: copied ? "teal" : "gray",
460
+ onClick: (e) => {
461
+ e.stopPropagation();
462
+ e.preventDefault();
463
+ copy();
464
+ },
465
+ children: copied ? /* @__PURE__ */ jsx(IconCheck, {}) : /* @__PURE__ */ jsx(IconCopy, { style: { width: "65%", opacity: 0.8 } })
466
+ }
467
+ ),
468
+ /* @__PURE__ */ jsxs(Box, { flex: 1, children: [
469
+ /* @__PURE__ */ jsx(Text, { fz: "sm", truncate: true, lh: 1.3, fw: value.title ? 500 : 400, children: value.title || url }),
470
+ value.title && /* @__PURE__ */ jsx(Text, { component: "div", fz: 10, c: "dimmed", lh: 1.2, truncate: true, children: url })
471
+ ] })
472
+ ] }) }) });
473
+ }
474
+ function ElementMetata({
475
+ value
476
+ }) {
477
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
478
+ /* @__PURE__ */ jsx(PropertyLabel, { children: "metadata" }),
479
+ /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Code, { block: true, children: JSON.stringify(value, null, 2) }) })
480
+ ] });
481
+ }
482
+ export {
483
+ ElementDetailsCard
484
+ };
@@ -0,0 +1,4 @@
1
+ export declare const treeNode: string;
2
+ export declare const treeNodeLabel: string;
3
+ export declare const nodeLabel: string;
4
+ export declare const instanceLabel: string;
@@ -0,0 +1,11 @@
1
+ /* empty css */
2
+ var treeNode = "_6nb9wd0";
3
+ var treeNodeLabel = "_6nb9wd1";
4
+ var nodeLabel = "_6nb9wd3 _6nb9wd2";
5
+ var instanceLabel = "_6nb9wd4 _6nb9wd2";
6
+ export {
7
+ instanceLabel,
8
+ nodeLabel,
9
+ treeNode,
10
+ treeNodeLabel
11
+ };
@@ -0,0 +1,7 @@
1
+ import { Fqn } from '@likec4/core';
2
+ import { NamedExoticComponent } from 'react';
3
+ type TabPanelDeploymentsProps = {
4
+ elementFqn: Fqn;
5
+ };
6
+ export declare const TabPanelDeployments: NamedExoticComponent<TabPanelDeploymentsProps>;
7
+ export {};
@@ -0,0 +1,173 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useTree, Alert, Tree, Box, rem, Button, Group, Text, ThemeIcon, Menu } from "@mantine/core";
3
+ import { IconInfoCircle, IconTarget, IconZoomScan } from "@tabler/icons-react";
4
+ import { memo, useMemo, useEffect } from "react";
5
+ import { useLikeC4ElementModel } from "../../likec4model/useLikeC4Model.js";
6
+ import { stopPropagation } from "../../xyflow/utils.js";
7
+ import { treeNode, treeNodeLabel, nodeLabel, instanceLabel } from "./TabPanelDeployments.css.js";
8
+ import { useCurrentViewId, useDiagramStoreApi } from "../../hooks/useDiagramState.js";
9
+ const DeploymentNodeRenderer = ({
10
+ node
11
+ }) => /* @__PURE__ */ jsxs(Group, { className: nodeLabel, gap: 6, align: "baseline", wrap: "nowrap", children: [
12
+ /* @__PURE__ */ jsxs(Text, { component: "div", fz: 11, c: "dimmed", children: [
13
+ node.kind,
14
+ ":"
15
+ ] }),
16
+ /* @__PURE__ */ jsx(Text, { component: "div", fz: "sm", fw: "500", children: node.title })
17
+ ] });
18
+ const DeployedInstanceRenderer = ({
19
+ instance
20
+ }) => {
21
+ const currentViewId = useCurrentViewId();
22
+ const diagramApi = useDiagramStoreApi();
23
+ const views = [...instance.views()];
24
+ return /* @__PURE__ */ jsxs(Group, { className: instanceLabel, gap: 4, children: [
25
+ /* @__PURE__ */ jsx(ThemeIcon, { color: "gray", variant: "transparent", size: "xs", flex: 0, children: /* @__PURE__ */ jsx(IconTarget, { stroke: 1.2 }) }),
26
+ /* @__PURE__ */ jsx(Text, { component: "div", fz: "sm", fw: "500", flex: "1 1 100%", children: instance.title }),
27
+ /* @__PURE__ */ jsxs(Box, { onClick: stopPropagation, pos: "relative", "data-no-transform": true, flex: 0, children: [
28
+ views.length === 0 && /* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "transparent", color: "gray", disabled: true, children: "no views" }),
29
+ views.length > 0 && /* @__PURE__ */ jsxs(
30
+ Menu,
31
+ {
32
+ shadow: "md",
33
+ withinPortal: false,
34
+ position: "bottom-start",
35
+ offset: 0,
36
+ closeOnClickOutside: true,
37
+ clickOutsideEvents: ["pointerdown", "mousedown", "click"],
38
+ closeOnEscape: true,
39
+ trapFocus: true,
40
+ children: [
41
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsxs(Button, { size: "compact-xs", variant: "subtle", color: "gray", children: [
42
+ views.length,
43
+ " view",
44
+ views.length > 1 ? "s" : ""
45
+ ] }) }),
46
+ /* @__PURE__ */ jsx(Menu.Dropdown, { children: views.map((view) => /* @__PURE__ */ jsx(
47
+ Menu.Item,
48
+ {
49
+ px: "xs",
50
+ py: 4,
51
+ disabled: view.id === currentViewId,
52
+ leftSection: /* @__PURE__ */ jsx(ThemeIcon, { size: "sm", variant: "transparent", color: "gray", children: /* @__PURE__ */ jsx(IconZoomScan, { stroke: 1.8, opacity: 0.65 }) }),
53
+ styles: {
54
+ itemSection: {
55
+ marginInlineEnd: rem(8)
56
+ }
57
+ },
58
+ onClick: (e) => {
59
+ var _a, _b;
60
+ e.stopPropagation();
61
+ (_b = (_a = diagramApi.getState()).onNavigateTo) == null ? void 0 : _b.call(_a, view.id);
62
+ },
63
+ children: view.title
64
+ },
65
+ view.id
66
+ )) })
67
+ ]
68
+ }
69
+ )
70
+ ] })
71
+ ] });
72
+ };
73
+ const TabPanelDeployments = memo(({ elementFqn }) => {
74
+ const element = useLikeC4ElementModel(elementFqn);
75
+ const deployments = [...element.deployments()];
76
+ const tree = useTree({
77
+ multiple: false
78
+ });
79
+ const data = useMemo(() => {
80
+ let roots = [];
81
+ let treeItems = /* @__PURE__ */ new Map();
82
+ for (const instance of element.deployments()) {
83
+ let instanceNode = {
84
+ label: /* @__PURE__ */ jsx(DeployedInstanceRenderer, { instance }),
85
+ value: instance.id,
86
+ type: "instance",
87
+ children: []
88
+ };
89
+ treeItems.set(instance.id, instanceNode);
90
+ let ancestor = instance.parent;
91
+ while (ancestor) {
92
+ let ancestorNode = treeItems.get(ancestor.id);
93
+ if (ancestorNode) {
94
+ ancestorNode.children.push(instanceNode);
95
+ break;
96
+ }
97
+ ancestorNode = {
98
+ label: /* @__PURE__ */ jsx(DeploymentNodeRenderer, { node: ancestor }),
99
+ value: ancestor.id,
100
+ type: "node",
101
+ children: [instanceNode]
102
+ };
103
+ treeItems.set(ancestor.id, ancestorNode);
104
+ instanceNode = ancestorNode;
105
+ ancestor = ancestor.parent;
106
+ }
107
+ if (!ancestor && !roots.includes(instanceNode)) {
108
+ roots.push(instanceNode);
109
+ }
110
+ }
111
+ return roots;
112
+ }, [element]);
113
+ useEffect(() => {
114
+ tree.expandAllNodes();
115
+ }, [data]);
116
+ if (deployments.length === 0) {
117
+ return /* @__PURE__ */ jsx(Alert, { variant: "light", color: "gray", icon: /* @__PURE__ */ jsx(IconInfoCircle, {}), children: "This element does not have any deployments" });
118
+ }
119
+ return (
120
+ // <Box></Box>
121
+ /* @__PURE__ */ jsx(
122
+ Tree,
123
+ {
124
+ levelOffset: "sm",
125
+ allowRangeSelection: false,
126
+ classNames: {
127
+ node: treeNode,
128
+ label: treeNodeLabel
129
+ },
130
+ styles: {
131
+ root: {
132
+ position: "relative",
133
+ width: "min-content",
134
+ minWidth: 300
135
+ }
136
+ },
137
+ data,
138
+ tree,
139
+ renderNode: ({ node, selected, elementProps, hasChildren }) => /* @__PURE__ */ jsx(
140
+ Box,
141
+ {
142
+ ...elementProps,
143
+ style: {
144
+ ...!hasChildren && {
145
+ marginBottom: rem(4)
146
+ }
147
+ },
148
+ children: hasChildren ? /* @__PURE__ */ jsx(
149
+ Button,
150
+ {
151
+ fullWidth: true,
152
+ color: "gray",
153
+ variant: selected ? "transparent" : "subtle",
154
+ size: "xs",
155
+ justify: "flex-start",
156
+ styles: {
157
+ root: {
158
+ position: "unset",
159
+ paddingInlineStart: rem(16)
160
+ }
161
+ },
162
+ children: node.label
163
+ }
164
+ ) : node.label
165
+ }
166
+ )
167
+ }
168
+ )
169
+ );
170
+ });
171
+ export {
172
+ TabPanelDeployments
173
+ };
@@ -0,0 +1,5 @@
1
+ export declare const fqn: string;
2
+ export declare const relationshipStat: string;
3
+ export declare const xyflow: string;
4
+ export declare const panelScope: string;
5
+ export declare const edgeNum: string;