@likec4/diagram 1.40.0 → 1.41.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/bundle/{chunk-CDr-4Ymp.js → chunk-FGcODVxo.js} +232 -229
- package/bundle/custom.js +59 -59
- package/bundle/index.js +140 -100
- package/dist/base/primitives/MarkdownBlock.js +2 -0
- package/dist/components/Link.js +28 -20
- package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +1 -1
- package/dist/navigationpanel/controls/ViewDetailsCard.js +22 -10
- package/dist/overlays/element-details/ElementDetailsCard.css.js +7 -1
- package/dist/overlays/element-details/ElementDetailsCard.js +17 -19
- package/dist/overlays/relationship-details/layout.d.ts +3 -2
- package/dist/overlays/relationship-details/layout.js +1 -2
- package/dist/overlays/relationships-browser/RelationshipsBrowser.js +2 -1
- package/dist/overlays/relationships-browser/layout.js +1 -1
- package/dist/search/components/ElementsColumn.js +1 -1
- package/dist/state/DiagramActorProvider.js +23 -32
- package/dist/styles-min.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css2.js +1 -1
- package/package.json +4 -4
- package/panda.buildinfo.json +15 -15
- package/src/base/primitives/MarkdownBlock.tsx +2 -0
- package/src/components/Link.tsx +21 -18
- package/src/navigationpanel/controls/ViewDetailsCard.tsx +24 -10
- package/src/overlays/element-details/ElementDetailsCard.css.ts +7 -1
- package/src/overlays/element-details/ElementDetailsCard.tsx +24 -25
- package/src/overlays/relationship-details/layout.ts +4 -3
- package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +2 -1
- package/src/overlays/relationships-browser/layout.ts +1 -1
- package/src/search/components/ElementsColumn.tsx +1 -1
- package/src/state/DiagramActorProvider.tsx +29 -45
|
@@ -12,6 +12,7 @@ const MarkdownBlock = forwardRef(({
|
|
|
12
12
|
hideIfEmpty = false,
|
|
13
13
|
emptyText = "no content",
|
|
14
14
|
className,
|
|
15
|
+
style,
|
|
15
16
|
...props
|
|
16
17
|
}, ref) => {
|
|
17
18
|
if (value.isEmpty && hideIfEmpty) {
|
|
@@ -31,6 +32,7 @@ const MarkdownBlock = forwardRef(({
|
|
|
31
32
|
className
|
|
32
33
|
),
|
|
33
34
|
style: {
|
|
35
|
+
...style,
|
|
34
36
|
...props.fontSize && {
|
|
35
37
|
"--text-fz": `var(--font-sizes-${props.fontSize}, var(--font-sizes-md))`
|
|
36
38
|
},
|
package/dist/components/Link.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { css, cx } from '@likec4/styles/css';
|
|
3
|
+
import { styled } from '@likec4/styles/jsx';
|
|
3
4
|
import { Badge, CopyButton, ActionIcon } from '@mantine/core';
|
|
4
5
|
import { forwardRef } from 'react';
|
|
5
6
|
import { GithubIcon } from './GithubIcon.js';
|
|
@@ -66,15 +67,22 @@ const Link = forwardRef(
|
|
|
66
67
|
userSelect: "none",
|
|
67
68
|
pointerEvents: "none",
|
|
68
69
|
_groupHover: {
|
|
69
|
-
color: "[
|
|
70
|
+
color: "[var(--badge-color)]",
|
|
70
71
|
opacity: 0.7
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
})
|
|
75
|
+
},
|
|
76
|
+
children: /* @__PURE__ */ jsxs(
|
|
77
|
+
styled.a,
|
|
78
|
+
{
|
|
79
|
+
href: url,
|
|
80
|
+
target: "_blank",
|
|
81
|
+
style: {
|
|
82
|
+
color: "var(--badge-color)",
|
|
83
|
+
cursor: "pointer"
|
|
84
|
+
},
|
|
85
|
+
css: {
|
|
78
86
|
transition: "fast",
|
|
79
87
|
opacity: {
|
|
80
88
|
base: 0.7,
|
|
@@ -84,20 +92,20 @@ const Link = forwardRef(
|
|
|
84
92
|
base: "none",
|
|
85
93
|
_hover: "underline"
|
|
86
94
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
},
|
|
96
|
+
children: [
|
|
97
|
+
isGithub && /* @__PURE__ */ jsx(
|
|
98
|
+
GithubIcon,
|
|
99
|
+
{
|
|
100
|
+
height: "12",
|
|
101
|
+
width: "12",
|
|
102
|
+
style: { verticalAlign: "middle", marginRight: "4px" }
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
isGithub ? url.replace(GITHUB_PREFIX, "") : url
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
)
|
|
101
109
|
}
|
|
102
110
|
);
|
|
103
111
|
}
|
|
@@ -38,7 +38,7 @@ export declare const RelationshipEdge: FunctionComponent<{
|
|
|
38
38
|
points: NonEmptyArray<Point>;
|
|
39
39
|
color: Color | undefined;
|
|
40
40
|
dir: "forward" | "back" | "both" | undefined;
|
|
41
|
-
technology: string | undefined;
|
|
41
|
+
technology: string | null | undefined;
|
|
42
42
|
labelBBox: BBox | null | undefined;
|
|
43
43
|
line: RelationshipLineType | undefined;
|
|
44
44
|
head: RelationshipArrowType | undefined;
|
|
@@ -4,8 +4,9 @@ import { HStack, Box, styled } from '@likec4/styles/jsx';
|
|
|
4
4
|
import { hstack, vstack } from '@likec4/styles/patterns';
|
|
5
5
|
import { Popover, UnstyledButton, Text, Badge } from '@mantine/core';
|
|
6
6
|
import * as m from 'motion/react-m';
|
|
7
|
+
import { useState } from 'react';
|
|
7
8
|
import { Link } from '../../components/Link.js';
|
|
8
|
-
import { useDiagram } from '../../hooks/useDiagram.js';
|
|
9
|
+
import { useDiagram, useOnDiagramEvent } from '../../hooks/useDiagram.js';
|
|
9
10
|
import { useMantinePortalProps } from '../../hooks/useMantinePortalProps.js';
|
|
10
11
|
import { useNavigationActorSnapshot } from '../hooks.js';
|
|
11
12
|
import IconId from '../../node_modules/.pnpm/@tabler_icons-react@3.34.1_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconId.js';
|
|
@@ -25,6 +26,7 @@ const selector = ({ context }) => {
|
|
|
25
26
|
};
|
|
26
27
|
};
|
|
27
28
|
const ViewDetailsCard = (props) => {
|
|
29
|
+
const [opened, setOpened] = useState(false);
|
|
28
30
|
const data = useNavigationActorSnapshot(selector);
|
|
29
31
|
const portalProps = useMantinePortalProps();
|
|
30
32
|
return /* @__PURE__ */ jsxs(
|
|
@@ -33,20 +35,21 @@ const ViewDetailsCard = (props) => {
|
|
|
33
35
|
position: "bottom-end",
|
|
34
36
|
shadow: "xl",
|
|
35
37
|
clickOutsideEvents: ["pointerdown", "mousedown", "click"],
|
|
36
|
-
trapFocus: true,
|
|
37
38
|
offset: {
|
|
38
39
|
mainAxis: 4
|
|
39
40
|
},
|
|
41
|
+
opened,
|
|
42
|
+
onChange: setOpened,
|
|
40
43
|
...portalProps,
|
|
41
44
|
...props,
|
|
42
45
|
children: [
|
|
43
|
-
/* @__PURE__ */ jsx(ViewDetailsCardTrigger, { linksCount: data.links.length }),
|
|
44
|
-
/* @__PURE__ */ jsx(ViewDetailsCardDropdown, { data })
|
|
46
|
+
/* @__PURE__ */ jsx(ViewDetailsCardTrigger, { linksCount: data.links.length, onOpen: () => setOpened(true) }),
|
|
47
|
+
opened && /* @__PURE__ */ jsx(ViewDetailsCardDropdown, { data, onClose: () => setOpened(false) })
|
|
45
48
|
]
|
|
46
49
|
}
|
|
47
50
|
);
|
|
48
51
|
};
|
|
49
|
-
const ViewDetailsCardTrigger = ({ linksCount }) => /* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsxs(
|
|
52
|
+
const ViewDetailsCardTrigger = ({ linksCount, onOpen }) => /* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsxs(
|
|
50
53
|
UnstyledButton,
|
|
51
54
|
{
|
|
52
55
|
component: m.button,
|
|
@@ -55,6 +58,10 @@ const ViewDetailsCardTrigger = ({ linksCount }) => /* @__PURE__ */ jsx(Popover.T
|
|
|
55
58
|
scale: 0.95,
|
|
56
59
|
translateY: 1
|
|
57
60
|
},
|
|
61
|
+
onClick: (e) => {
|
|
62
|
+
e.stopPropagation();
|
|
63
|
+
onOpen();
|
|
64
|
+
},
|
|
58
65
|
className: cx(
|
|
59
66
|
"group",
|
|
60
67
|
hstack({
|
|
@@ -115,9 +122,12 @@ const ViewDetailsCardDropdown = ({
|
|
|
115
122
|
tags,
|
|
116
123
|
links,
|
|
117
124
|
relativePath
|
|
118
|
-
}
|
|
125
|
+
},
|
|
126
|
+
onClose
|
|
119
127
|
}) => {
|
|
120
128
|
const diagram = useDiagram();
|
|
129
|
+
useOnDiagramEvent("paneClick", onClose);
|
|
130
|
+
useOnDiagramEvent("nodeClick", onClose);
|
|
121
131
|
return /* @__PURE__ */ jsxs(
|
|
122
132
|
Popover.Dropdown,
|
|
123
133
|
{
|
|
@@ -128,9 +138,10 @@ const ViewDetailsCardDropdown = ({
|
|
|
128
138
|
layerStyle: "likec4.dropdown",
|
|
129
139
|
gap: "md",
|
|
130
140
|
padding: "md",
|
|
141
|
+
paddingBottom: "lg",
|
|
131
142
|
pointerEvents: "all",
|
|
132
|
-
maxWidth: "calc(100cqw -
|
|
133
|
-
minWidth: "
|
|
143
|
+
maxWidth: "calc(100cqw - 52px)",
|
|
144
|
+
minWidth: "200px",
|
|
134
145
|
maxHeight: "calc(100cqh - 100px)",
|
|
135
146
|
width: "max-content",
|
|
136
147
|
cursor: "default",
|
|
@@ -147,7 +158,7 @@ const ViewDetailsCardDropdown = ({
|
|
|
147
158
|
),
|
|
148
159
|
children: [
|
|
149
160
|
/* @__PURE__ */ jsxs("section", { children: [
|
|
150
|
-
/* @__PURE__ */ jsx(Text, { component: "div", fw: 500, size: "xl", children: title }),
|
|
161
|
+
/* @__PURE__ */ jsx(Text, { component: "div", fw: 500, size: "xl", lh: "sm", children: title }),
|
|
151
162
|
/* @__PURE__ */ jsxs(HStack, { alignItems: "flex-start", mt: "1", children: [
|
|
152
163
|
/* @__PURE__ */ jsx(ViewBadge, { label: "id", value: id }),
|
|
153
164
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", flexWrap: "wrap", children: tags.map((tag, i) => /* @__PURE__ */ jsx(
|
|
@@ -168,7 +179,7 @@ const ViewDetailsCardDropdown = ({
|
|
|
168
179
|
/* @__PURE__ */ jsx(SectionHeader, { children: "Links" }),
|
|
169
180
|
/* @__PURE__ */ jsx(HStack, { gap: "xs", flexWrap: "wrap", children: links.map((link, i) => /* @__PURE__ */ jsx(Link, { value: link }, `${i}-${link.url}`)) })
|
|
170
181
|
] }),
|
|
171
|
-
description.isEmpty && /* @__PURE__ */ jsx(Text, { component: "div", fw: 500, size: "xs", c: "dimmed",
|
|
182
|
+
description.isEmpty && /* @__PURE__ */ jsx(Text, { component: "div", fw: 500, size: "xs", c: "dimmed", style: { userSelect: "none" }, children: "No description" }),
|
|
172
183
|
description.nonEmpty && /* @__PURE__ */ jsxs("section", { children: [
|
|
173
184
|
/* @__PURE__ */ jsx(SectionHeader, { children: "Description" }),
|
|
174
185
|
/* @__PURE__ */ jsx(
|
|
@@ -208,6 +219,7 @@ const ViewBadge = ({
|
|
|
208
219
|
overflow: "visible",
|
|
209
220
|
px: "1",
|
|
210
221
|
color: {
|
|
222
|
+
_dark: "mantine.colors.gray[4]",
|
|
211
223
|
_light: "mantine.colors.gray[8]"
|
|
212
224
|
}
|
|
213
225
|
}),
|
|
@@ -24,13 +24,19 @@ const dialog = css({
|
|
|
24
24
|
const card = css({
|
|
25
25
|
position: "absolute",
|
|
26
26
|
pointerEvents: "all",
|
|
27
|
+
display: "flex",
|
|
28
|
+
flexDirection: "column",
|
|
29
|
+
padding: "4",
|
|
27
30
|
gap: "lg",
|
|
28
31
|
justifyContent: "stretch",
|
|
32
|
+
color: "mantine.colors.text",
|
|
29
33
|
backgroundColor: {
|
|
30
34
|
base: "mantine.colors.body",
|
|
31
35
|
_dark: "mantine.colors.dark[6]"
|
|
32
36
|
},
|
|
33
|
-
|
|
37
|
+
boxShadow: "md",
|
|
38
|
+
overflow: "hidden",
|
|
39
|
+
border: "none",
|
|
34
40
|
backgroundImage: `
|
|
35
41
|
linear-gradient(180deg,
|
|
36
42
|
color-mix(in srgb, var(--likec4-palette-fill) 60%, transparent),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { cx, css } from '@likec4/styles/css';
|
|
3
3
|
import { HStack } from '@likec4/styles/jsx';
|
|
4
|
-
import { RemoveScroll,
|
|
4
|
+
import { RemoveScroll, Text, CloseButton, Badge, Flex, ActionIconGroup, ActionIcon, Tooltip as Tooltip$1, Tabs, TabsList, TabsTab, TabsPanel, ScrollArea, Box, Stack, Divider as Divider$1, ScrollAreaAutosize, UnstyledButton, Group, ThemeIcon } from '@mantine/core';
|
|
5
5
|
import { useViewportSize, useSessionStorage } from '@mantine/hooks';
|
|
6
6
|
import { useSyncedRef, useDebouncedCallback, useTimeoutEffect } from '@react-hookz/web';
|
|
7
7
|
import { useDragControls, useMotionValue, m } from 'motion/react';
|
|
@@ -14,7 +14,7 @@ import { elementIcon, card, cardHeader, title, tabsPanel, tabsTab, tabsList, tab
|
|
|
14
14
|
import { TabPanelDeployments } from './TabPanelDeployments.js';
|
|
15
15
|
import { TabPanelRelationships } from './TabPanelRelationships.js';
|
|
16
16
|
import { TabPanelStructure } from './TabPanelStructure.js';
|
|
17
|
-
import {
|
|
17
|
+
import { useCurrentViewModel } from '../../likec4model/useCurrentViewModel.js';
|
|
18
18
|
import { useUpdateEffect } from '../../hooks/useUpdateEffect.js';
|
|
19
19
|
import { IconRenderer } from '../../context/IconRenderer.js';
|
|
20
20
|
import { stopPropagation } from '../../utils/xyflow.js';
|
|
@@ -69,8 +69,7 @@ function ElementDetailsCard({
|
|
|
69
69
|
defaultValue: "Properties"
|
|
70
70
|
});
|
|
71
71
|
const diagram = useDiagram();
|
|
72
|
-
const
|
|
73
|
-
const viewModel = likec4model.view(viewId);
|
|
72
|
+
const viewModel = useCurrentViewModel();
|
|
74
73
|
const nodeModel = fromNode ? viewModel.findNode(fromNode) : viewModel.findNodeWithElement(fqn);
|
|
75
74
|
const elementModel = viewModel.$model.element(fqn);
|
|
76
75
|
const [viewsOf, otherViews] = pipe(
|
|
@@ -150,7 +149,7 @@ function ElementDetailsCard({
|
|
|
150
149
|
}, 20);
|
|
151
150
|
useTimeoutEffect(() => {
|
|
152
151
|
setOpened(true);
|
|
153
|
-
},
|
|
152
|
+
}, 220);
|
|
154
153
|
return /* @__PURE__ */ jsx(
|
|
155
154
|
m.dialog,
|
|
156
155
|
{
|
|
@@ -185,10 +184,8 @@ function ElementDetailsCard({
|
|
|
185
184
|
close();
|
|
186
185
|
},
|
|
187
186
|
children: /* @__PURE__ */ jsx(RemoveScroll, { forwardProps: true, removeScrollBar: false, children: /* @__PURE__ */ jsxs(
|
|
188
|
-
|
|
187
|
+
m.div,
|
|
189
188
|
{
|
|
190
|
-
shadow: "md",
|
|
191
|
-
component: m.div,
|
|
192
189
|
layout: true,
|
|
193
190
|
layoutRoot: true,
|
|
194
191
|
drag: true,
|
|
@@ -221,14 +218,13 @@ function ElementDetailsCard({
|
|
|
221
218
|
}
|
|
222
219
|
},
|
|
223
220
|
style: {
|
|
224
|
-
// `style` prop in Mantine doesn't accept motion values
|
|
225
221
|
width,
|
|
226
222
|
height
|
|
227
223
|
},
|
|
228
224
|
children: [
|
|
229
225
|
/* @__PURE__ */ jsxs("div", { className: cardHeader, onPointerDown: (e) => controls.start(e), children: [
|
|
230
|
-
/* @__PURE__ */ jsxs(
|
|
231
|
-
/* @__PURE__ */ jsxs(
|
|
226
|
+
/* @__PURE__ */ jsxs(HStack, { alignItems: "start", justify: "space-between", gap: "sm", mb: "sm", flexWrap: "nowrap", children: [
|
|
227
|
+
/* @__PURE__ */ jsxs(HStack, { alignItems: "start", gap: "sm", style: { cursor: "default" }, flexWrap: "nowrap", children: [
|
|
232
228
|
elementIcon$1,
|
|
233
229
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
234
230
|
/* @__PURE__ */ jsx(
|
|
@@ -253,7 +249,7 @@ function ElementDetailsCard({
|
|
|
253
249
|
}
|
|
254
250
|
)
|
|
255
251
|
] }),
|
|
256
|
-
/* @__PURE__ */ jsxs(
|
|
252
|
+
/* @__PURE__ */ jsxs(HStack, { alignItems: "baseline", gap: "sm", flexWrap: "nowrap", children: [
|
|
257
253
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
258
254
|
/* @__PURE__ */ jsx(SmallLabel, { children: "kind" }),
|
|
259
255
|
/* @__PURE__ */ jsx(
|
|
@@ -359,6 +355,10 @@ function ElementDetailsCard({
|
|
|
359
355
|
children: [
|
|
360
356
|
/* @__PURE__ */ jsx(TabsList, { children: TABS.map((tab) => /* @__PURE__ */ jsx(TabsTab, { value: tab, children: tab }, tab)) }),
|
|
361
357
|
/* @__PURE__ */ jsx(TabsPanel, { value: "Properties", children: /* @__PURE__ */ jsx(ScrollArea, { scrollbars: "y", type: "scroll", offsetScrollbars: true, children: /* @__PURE__ */ jsxs(Box, { className: propertiesGrid, pt: "xs", children: [
|
|
358
|
+
elementModel.hasSummary && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
359
|
+
/* @__PURE__ */ jsx(PropertyLabel, { children: "summary" }),
|
|
360
|
+
/* @__PURE__ */ jsx(MarkdownBlock, { value: elementModel.summary })
|
|
361
|
+
] }),
|
|
362
362
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
363
363
|
/* @__PURE__ */ jsx(PropertyLabel, { children: "description" }),
|
|
364
364
|
/* @__PURE__ */ jsx(
|
|
@@ -494,12 +494,10 @@ function ElementMetata({
|
|
|
494
494
|
children: entries(metadata).map(([key, value]) => /* @__PURE__ */ jsxs(
|
|
495
495
|
"div",
|
|
496
496
|
{
|
|
497
|
-
|
|
498
|
-
"
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
})
|
|
502
|
-
),
|
|
497
|
+
style: {
|
|
498
|
+
display: "contents"
|
|
499
|
+
},
|
|
500
|
+
className: "group",
|
|
503
501
|
children: [
|
|
504
502
|
/* @__PURE__ */ jsxs(
|
|
505
503
|
"div",
|
|
@@ -548,7 +546,7 @@ function ElementMetata({
|
|
|
548
546
|
fontSize: "sm",
|
|
549
547
|
padding: "xxs",
|
|
550
548
|
whiteSpace: "pre",
|
|
551
|
-
fontFamily: "
|
|
549
|
+
fontFamily: "mono",
|
|
552
550
|
userSelect: "all"
|
|
553
551
|
}),
|
|
554
552
|
children: value
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DiagramEdge, DiagramNode, DiagramView, Fqn, RelationId, RichTextOrEmpty } from '@likec4/core/types';
|
|
2
2
|
import { AnyAux, LikeC4ViewModel } from '@likec4/core/model';
|
|
3
|
+
import { Except } from 'type-fest';
|
|
3
4
|
import { RelationshipDetailsTypes } from './_types';
|
|
4
5
|
import { RelationshipDetailsViewData } from './compute';
|
|
5
6
|
export type LayoutResult = {
|
|
@@ -8,13 +9,13 @@ export type LayoutResult = {
|
|
|
8
9
|
bounds: DiagramView['bounds'];
|
|
9
10
|
};
|
|
10
11
|
export declare namespace LayoutResult {
|
|
11
|
-
type Node =
|
|
12
|
+
type Node = Except<DiagramNode, 'modelRef' | 'description' | 'deploymentRef' | 'inEdges' | 'outEdges'> & {
|
|
12
13
|
description: RichTextOrEmpty;
|
|
13
14
|
modelRef: Fqn;
|
|
14
15
|
column: RelationshipDetailsTypes.Column;
|
|
15
16
|
ports: RelationshipDetailsTypes.Ports;
|
|
16
17
|
};
|
|
17
|
-
type Edge =
|
|
18
|
+
type Edge = Except<DiagramEdge, 'relations' | 'description'> & {
|
|
18
19
|
relationId: RelationId;
|
|
19
20
|
sourceHandle: string;
|
|
20
21
|
targetHandle: string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { treeFromElements } from '@likec4/core/compute-view/relationships';
|
|
2
2
|
import dagre from '@dagrejs/dagre';
|
|
3
|
-
import { RichText } from '@likec4/core';
|
|
4
3
|
import { ifind, DefaultMap, invariant } from '@likec4/core/utils';
|
|
5
4
|
import { pipe, filter, mapToObj, find, map, tap, reduce, sortBy, prop } from 'remeda';
|
|
6
5
|
|
|
@@ -240,7 +239,7 @@ function layoutRelationshipDetails(data, scope) {
|
|
|
240
239
|
y: position.y,
|
|
241
240
|
position: [position.x, position.y],
|
|
242
241
|
title: element.title,
|
|
243
|
-
description:
|
|
242
|
+
description: element.summary,
|
|
244
243
|
technology: element.technology,
|
|
245
244
|
tags: [...element.tags],
|
|
246
245
|
links: null,
|
|
@@ -2,6 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { cx } from '@likec4/styles/css';
|
|
3
3
|
import { ActionIcon, Group } from '@mantine/core';
|
|
4
4
|
import { useCallbackRef, useStateHistory } from '@mantine/hooks';
|
|
5
|
+
import { useRafEffect } from '@react-hookz/web';
|
|
5
6
|
import { ReactFlowProvider, useStoreApi, useReactFlow, Panel } from '@xyflow/react';
|
|
6
7
|
import { shallowEqual } from 'fast-equals';
|
|
7
8
|
import { LayoutGroup, AnimatePresence, m } from 'motion/react';
|
|
@@ -137,7 +138,7 @@ const RelationshipsBrowserInner = memo(() => {
|
|
|
137
138
|
browser.navigateTo(historySubjectId);
|
|
138
139
|
}
|
|
139
140
|
}, [historySubjectId, browser]);
|
|
140
|
-
|
|
141
|
+
useRafEffect(() => {
|
|
141
142
|
browser.updateView(layouted);
|
|
142
143
|
}, [layouted, browser]);
|
|
143
144
|
const hasStepBack = current > 0;
|
|
@@ -374,7 +374,7 @@ function layoutRelationshipsView(data, scope) {
|
|
|
374
374
|
y: position.y,
|
|
375
375
|
position: [position.x, position.y],
|
|
376
376
|
title: element.title,
|
|
377
|
-
description:
|
|
377
|
+
description: element.summary,
|
|
378
378
|
technology: element.technology,
|
|
379
379
|
tags: [...element.tags],
|
|
380
380
|
links: null,
|
|
@@ -224,7 +224,7 @@ function ElementTreeNode({ node, elementProps, hasChildren, expanded }) {
|
|
|
224
224
|
}
|
|
225
225
|
) })
|
|
226
226
|
] }),
|
|
227
|
-
/* @__PURE__ */ jsx(Highlight, { component: "div", highlight: searchTerms, className: btn.description, lineClamp: 1, children: element.
|
|
227
|
+
/* @__PURE__ */ jsx(Highlight, { component: "div", highlight: searchTerms, className: btn.description, lineClamp: 1, children: element.summary.text || "No description" })
|
|
228
228
|
] }),
|
|
229
229
|
/* @__PURE__ */ jsx(Text, { component: "div", className: cx(elementViewsCount, btn.descriptionColor), fz: "xs", children: views.length === 0 ? "No views" : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
230
230
|
views.length,
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { useCustomCompareEffect } from '@react-hookz/web';
|
|
2
|
+
import { useCustomCompareEffect, useRafEffect } from '@react-hookz/web';
|
|
3
3
|
import { useActorRef, useSelector } from '@xstate/react';
|
|
4
4
|
import { useStoreApi } from '@xyflow/react';
|
|
5
5
|
import { shallowEqual, deepEqual } from 'fast-equals';
|
|
6
|
-
import { useRef, useMemo
|
|
6
|
+
import { useRef, useMemo } from 'react';
|
|
7
7
|
import { ErrorBoundary } from '../components/ErrorFallback.js';
|
|
8
8
|
import { useDiagramEventHandlers } from '../context/DiagramEventHandlers.js';
|
|
9
9
|
import { useEnabledFeatures, DiagramFeatures } from '../context/DiagramFeatures.js';
|
|
10
10
|
import { DiagramActorContextProvider } from '../hooks/safeContext.js';
|
|
11
|
-
import { useCurrentViewId } from '../hooks/useCurrentViewId.js';
|
|
12
11
|
import { convertToXYFlow } from '../likec4diagram/convert-to-xyflow.js';
|
|
13
12
|
import { CurrentViewModelContext } from '../likec4model/LikeC4ModelContext.js';
|
|
14
13
|
import { useLikeC4Model } from '../likec4model/useLikeC4Model.js';
|
|
@@ -16,15 +15,6 @@ import { diagramMachine } from './diagram-machine.js';
|
|
|
16
15
|
import { syncManualLayoutActorLogic } from './syncManualLayoutActor.js';
|
|
17
16
|
import { useOnDiagramEvent } from '../hooks/useDiagram.js';
|
|
18
17
|
|
|
19
|
-
const selectToggledFeatures = (state) => {
|
|
20
|
-
if (state.context.features.enableReadOnly || state.context.activeWalkthrough) {
|
|
21
|
-
return {
|
|
22
|
-
...state.context.toggledFeatures,
|
|
23
|
-
enableReadOnly: true
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return state.context.toggledFeatures;
|
|
27
|
-
};
|
|
28
18
|
const selectDynamicViewVariant = (state) => {
|
|
29
19
|
return state.context.dynamicViewVariant;
|
|
30
20
|
};
|
|
@@ -91,23 +81,37 @@ function DiagramActorProvider({
|
|
|
91
81
|
() => convertToXYFlow({ view, where, nodesSelectable, dynamicViewVariant }),
|
|
92
82
|
[view, where, nodesSelectable, dynamicViewVariant]
|
|
93
83
|
);
|
|
94
|
-
|
|
84
|
+
useRafEffect(() => {
|
|
95
85
|
actorRef.send({
|
|
96
86
|
type: "update.view",
|
|
97
87
|
...update
|
|
98
88
|
});
|
|
99
89
|
}, [actorRef, update]);
|
|
100
|
-
const toggledFeatures = useSelector(actorRef, selectToggledFeatures, shallowEqual);
|
|
101
90
|
return /* @__PURE__ */ jsxs(DiagramActorContextProvider, { value: actorRef, children: [
|
|
102
|
-
/* @__PURE__ */ jsx(
|
|
91
|
+
/* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(CurrentViewModelProvider, { actorRef, children }) }),
|
|
103
92
|
/* @__PURE__ */ jsx(DiagramActorEventListener, { actorRef })
|
|
104
93
|
] });
|
|
105
94
|
}
|
|
106
|
-
|
|
107
|
-
|
|
95
|
+
const selectViewIdAndToggledFeatures = (state) => {
|
|
96
|
+
if (state.context.features.enableReadOnly || state.context.activeWalkthrough) {
|
|
97
|
+
return {
|
|
98
|
+
viewId: state.context.view.id,
|
|
99
|
+
toggledFeatures: {
|
|
100
|
+
...state.context.toggledFeatures,
|
|
101
|
+
enableReadOnly: true
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
viewId: state.context.view.id,
|
|
107
|
+
toggledFeatures: state.context.toggledFeatures
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
function CurrentViewModelProvider({ children, actorRef }) {
|
|
111
|
+
const { viewId, toggledFeatures } = useSelector(actorRef, selectViewIdAndToggledFeatures, deepEqual);
|
|
108
112
|
const likec4model = useLikeC4Model();
|
|
109
113
|
const viewmodel = likec4model.findView(viewId);
|
|
110
|
-
return /* @__PURE__ */ jsx(CurrentViewModelContext.Provider, { value: viewmodel, children });
|
|
114
|
+
return /* @__PURE__ */ jsx(CurrentViewModelContext.Provider, { value: viewmodel, children: /* @__PURE__ */ jsx(DiagramFeatures, { overrides: toggledFeatures, children }) });
|
|
111
115
|
}
|
|
112
116
|
function DiagramActorEventListener({ actorRef }) {
|
|
113
117
|
const {
|
|
@@ -115,20 +119,7 @@ function DiagramActorEventListener({ actorRef }) {
|
|
|
115
119
|
onOpenSource
|
|
116
120
|
} = useDiagramEventHandlers();
|
|
117
121
|
useOnDiagramEvent("openSource", ({ params }) => onOpenSource?.(params));
|
|
118
|
-
|
|
119
|
-
if (!onNavigateTo) return;
|
|
120
|
-
let frame;
|
|
121
|
-
const subscription = actorRef.on("navigateTo", ({ viewId }) => {
|
|
122
|
-
cancelAnimationFrame(frame);
|
|
123
|
-
frame = requestAnimationFrame(() => {
|
|
124
|
-
onNavigateTo(viewId);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
return () => {
|
|
128
|
-
cancelAnimationFrame(frame);
|
|
129
|
-
subscription.unsubscribe();
|
|
130
|
-
};
|
|
131
|
-
}, [actorRef, onNavigateTo]);
|
|
122
|
+
useOnDiagramEvent("navigateTo", ({ viewId }) => onNavigateTo?.(viewId));
|
|
132
123
|
return null;
|
|
133
124
|
}
|
|
134
125
|
|