@tldiagram/core-ui 1.95.0 → 2.0.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/api/client.d.ts +184 -3
- package/dist/components/ConnectorPanel.d.ts +5 -1
- package/dist/components/CrossBranchControls.d.ts +4 -3
- package/dist/components/ElementNode.d.ts +5 -0
- package/dist/components/ElementPanel.d.ts +6 -1
- package/dist/components/LayoutSection.d.ts +2 -1
- package/dist/components/MergeDialog.d.ts +16 -0
- package/dist/components/MiniZoomOnboarding.d.ts +2 -1
- package/dist/components/NodeContainer.d.ts +2 -0
- package/dist/components/ProxyConnectorPanel.d.ts +4 -1
- package/dist/components/ViewExplorer/index.d.ts +1 -1
- package/dist/components/ViewFloatingMenu-vscode.d.ts +5 -0
- package/dist/components/ViewFloatingMenu.d.ts +8 -1
- package/dist/components/ViewGridNode.d.ts +3 -0
- package/dist/components/ViewPanel.d.ts +2 -1
- package/dist/components/WorkspacePanel.d.ts +2 -0
- package/dist/components/ZUI/ZUICanvas.d.ts +5 -0
- package/dist/components/ZUI/focus.d.ts +32 -0
- package/dist/components/ZUI/focus.test.d.ts +1 -0
- package/dist/components/ZUI/layout.d.ts +2 -2
- package/dist/components/ZUI/proxy.d.ts +20 -4
- package/dist/components/ZUI/renderer.d.ts +35 -1
- package/dist/components/ZUI/types.d.ts +6 -0
- package/dist/components/ZUI/useZUIInteraction.d.ts +1 -0
- package/dist/context/WorkspaceVersionContext.d.ts +49 -0
- package/dist/crossBranch/resolve.d.ts +39 -2
- package/dist/crossBranch/resolve.test.d.ts +1 -0
- package/dist/crossBranch/settings.d.ts +6 -1
- package/dist/crossBranch/types.d.ts +8 -0
- package/dist/hooks/useElementSearch.d.ts +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14597 -12083
- package/dist/pages/InfiniteZoom.d.ts +1 -0
- package/dist/pages/ViewEditor/hooks/useCanvasInteractions.d.ts +6 -1
- package/dist/pages/ViewEditor/hooks/useViewContextNeighbours.d.ts +2 -0
- package/dist/pages/ViewEditor/hooks/useViewData.d.ts +4 -2
- package/dist/pages/ViewEditor/hooks/useViewEditHistory.d.ts +13 -0
- package/dist/pages/viewsJumpSearch.d.ts +22 -0
- package/dist/pages/viewsJumpSearch.test.d.ts +1 -0
- package/dist/store/useStore.d.ts +3 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/utils/elementIcon.d.ts +2 -0
- package/dist/utils/elementIcon.test.d.ts +1 -0
- package/dist/utils/sourceEditor.d.ts +7 -0
- package/dist/utils/watchDiffSummary.d.ts +34 -0
- package/package.json +2 -2
- package/src/App.tsx +12 -8
- package/src/api/client.ts +488 -26
- package/src/components/CodePreviewPanel.tsx +90 -16
- package/src/components/ConnectorPanel.tsx +34 -3
- package/src/components/ContextNeighborElement.tsx +2 -5
- package/src/components/CrossBranchControls.tsx +46 -17
- package/src/components/ElementNode.tsx +98 -47
- package/src/components/ElementPanel.tsx +62 -25
- package/src/components/InlineElementAdder.tsx +8 -3
- package/src/components/LayoutSection.tsx +4 -1
- package/src/components/MergeDialog.tsx +269 -0
- package/src/components/MiniZoomOnboarding.tsx +29 -22
- package/src/components/NodeContainer.tsx +55 -17
- package/src/components/ProxyConnectorPanel.tsx +58 -16
- package/src/components/ViewBezierConnector.tsx +116 -21
- package/src/components/ViewExplorer/index.tsx +1 -1
- package/src/components/ViewFloatingMenu-vscode.tsx +5 -0
- package/src/components/ViewFloatingMenu.tsx +110 -1
- package/src/components/ViewGridNode.tsx +59 -8
- package/src/components/ViewPanel.tsx +3 -2
- package/src/components/WorkspacePanel.tsx +938 -0
- package/src/components/ZUI/ZUICanvas.tsx +226 -127
- package/src/components/ZUI/focus.test.ts +534 -0
- package/src/components/ZUI/focus.ts +293 -0
- package/src/components/ZUI/layout.ts +7 -11
- package/src/components/ZUI/proxy.ts +470 -114
- package/src/components/ZUI/renderer.ts +510 -134
- package/src/components/ZUI/types.ts +6 -0
- package/src/components/ZUI/useZUIInteraction.ts +66 -29
- package/src/context/WorkspaceVersionContext.tsx +126 -0
- package/src/crossBranch/resolve.test.ts +342 -0
- package/src/crossBranch/resolve.ts +368 -68
- package/src/crossBranch/settings.ts +49 -3
- package/src/crossBranch/types.ts +9 -0
- package/src/hooks/useElementSearch.ts +45 -0
- package/src/index.css +11 -0
- package/src/index.ts +7 -0
- package/src/pages/AppearanceSettings.tsx +24 -1
- package/src/pages/Dependencies.tsx +231 -65
- package/src/pages/InfiniteZoom.tsx +76 -27
- package/src/pages/Settings.tsx +1 -1
- package/src/pages/ViewEditor/hooks/useCanvasInteractions.ts +103 -24
- package/src/pages/ViewEditor/hooks/useViewContextNeighbours.ts +102 -6
- package/src/pages/ViewEditor/hooks/useViewData.ts +42 -26
- package/src/pages/ViewEditor/hooks/useViewEditHistory.ts +62 -0
- package/src/pages/ViewEditor/index.tsx +549 -59
- package/src/pages/Views.tsx +112 -41
- package/src/pages/ViewsGrid.tsx +332 -113
- package/src/pages/viewsJumpSearch.test.ts +193 -0
- package/src/pages/viewsJumpSearch.ts +111 -0
- package/src/store/useStore.ts +58 -0
- package/src/types/index.ts +10 -0
- package/src/utils/elementIcon.test.ts +28 -0
- package/src/utils/elementIcon.ts +20 -0
- package/src/utils/sourceEditor.ts +46 -0
- package/src/utils/watchDiffSummary.ts +159 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import type { DiagramGroupLayout, LayoutNode, ZUIViewState } from './types'
|
|
2
|
+
import { getExpandThresholds } from './renderer'
|
|
3
|
+
|
|
4
|
+
interface Rect {
|
|
5
|
+
x: number
|
|
6
|
+
y: number
|
|
7
|
+
w: number
|
|
8
|
+
h: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ZUIFocusTarget {
|
|
12
|
+
id: string
|
|
13
|
+
label: string
|
|
14
|
+
type: 'group' | 'node'
|
|
15
|
+
isCircular?: boolean
|
|
16
|
+
absX: number
|
|
17
|
+
absY: number
|
|
18
|
+
absW: number
|
|
19
|
+
absH: number
|
|
20
|
+
absScale: number
|
|
21
|
+
node?: LayoutNode
|
|
22
|
+
contentRect?: Rect
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ZUIFocusViewportOptions {
|
|
26
|
+
preferContent?: boolean
|
|
27
|
+
minTargetScreenW?: number
|
|
28
|
+
minChildScreenW?: number
|
|
29
|
+
keepParentVisible?: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function boundsForRects(rects: Rect[]): Rect | null {
|
|
33
|
+
if (rects.length === 0) return null
|
|
34
|
+
|
|
35
|
+
let minX = Infinity
|
|
36
|
+
let minY = Infinity
|
|
37
|
+
let maxX = -Infinity
|
|
38
|
+
let maxY = -Infinity
|
|
39
|
+
|
|
40
|
+
for (const rect of rects) {
|
|
41
|
+
minX = Math.min(minX, rect.x)
|
|
42
|
+
minY = Math.min(minY, rect.y)
|
|
43
|
+
maxX = Math.max(maxX, rect.x + rect.w)
|
|
44
|
+
maxY = Math.max(maxY, rect.y + rect.h)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {
|
|
48
|
+
return null
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { x: minX, y: minY, w: positiveSize(maxX - minX), h: positiveSize(maxY - minY) }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function positiveSize(value: number): number {
|
|
55
|
+
return Number.isFinite(value) && value > 0 ? value : 0.0001
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function childContentRect(node: LayoutNode, absX: number, absY: number, absScale: number): Rect | null {
|
|
59
|
+
if (node.children.length === 0) return null
|
|
60
|
+
|
|
61
|
+
const childAbsScale = absScale * node.childScale
|
|
62
|
+
return boundsForRects(node.children.map((child) => ({
|
|
63
|
+
x: absX + (child.worldX - node.childOffsetX) * childAbsScale,
|
|
64
|
+
y: absY + (child.worldY - node.childOffsetY) * childAbsScale,
|
|
65
|
+
w: child.worldW * childAbsScale,
|
|
66
|
+
h: child.worldH * childAbsScale,
|
|
67
|
+
})))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function nodeTarget(
|
|
71
|
+
node: LayoutNode,
|
|
72
|
+
parentAbsX: number,
|
|
73
|
+
parentAbsY: number,
|
|
74
|
+
parentAbsScale: number,
|
|
75
|
+
parentChildOffsetX: number,
|
|
76
|
+
parentChildOffsetY: number,
|
|
77
|
+
): ZUIFocusTarget {
|
|
78
|
+
const absX = parentAbsX + (node.worldX - parentChildOffsetX) * parentAbsScale
|
|
79
|
+
const absY = parentAbsY + (node.worldY - parentChildOffsetY) * parentAbsScale
|
|
80
|
+
const absW = node.worldW * parentAbsScale
|
|
81
|
+
const absH = node.worldH * parentAbsScale
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
id: node.id,
|
|
85
|
+
label: node.linkedDiagramLabel || node.label,
|
|
86
|
+
type: 'node',
|
|
87
|
+
isCircular: node.isCircular,
|
|
88
|
+
absX,
|
|
89
|
+
absY,
|
|
90
|
+
absW,
|
|
91
|
+
absH,
|
|
92
|
+
absScale: parentAbsScale,
|
|
93
|
+
node,
|
|
94
|
+
contentRect: childContentRect(node, absX, absY, parentAbsScale) ?? undefined,
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function findLinkedDiagramInNodes(
|
|
99
|
+
viewId: number,
|
|
100
|
+
nodes: DiagramGroupLayout['nodes'],
|
|
101
|
+
parentAbsX: number,
|
|
102
|
+
parentAbsY: number,
|
|
103
|
+
parentAbsScale: number,
|
|
104
|
+
parentChildOffsetX: number,
|
|
105
|
+
parentChildOffsetY: number,
|
|
106
|
+
): ZUIFocusTarget | null {
|
|
107
|
+
for (const node of nodes) {
|
|
108
|
+
const target = nodeTarget(node, parentAbsX, parentAbsY, parentAbsScale, parentChildOffsetX, parentChildOffsetY)
|
|
109
|
+
|
|
110
|
+
if (node.linkedDiagramId === viewId) {
|
|
111
|
+
return target
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (node.children.length > 0) {
|
|
115
|
+
const found = findLinkedDiagramInNodes(
|
|
116
|
+
viewId,
|
|
117
|
+
node.children,
|
|
118
|
+
target.absX,
|
|
119
|
+
target.absY,
|
|
120
|
+
parentAbsScale * node.childScale,
|
|
121
|
+
node.childOffsetX,
|
|
122
|
+
node.childOffsetY,
|
|
123
|
+
)
|
|
124
|
+
if (found) return found
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function findElementInNodes(
|
|
132
|
+
viewId: number,
|
|
133
|
+
elementId: number,
|
|
134
|
+
nodes: DiagramGroupLayout['nodes'],
|
|
135
|
+
parentAbsX: number,
|
|
136
|
+
parentAbsY: number,
|
|
137
|
+
parentAbsScale: number,
|
|
138
|
+
parentChildOffsetX: number,
|
|
139
|
+
parentChildOffsetY: number,
|
|
140
|
+
): ZUIFocusTarget | null {
|
|
141
|
+
for (const node of nodes) {
|
|
142
|
+
const target = nodeTarget(node, parentAbsX, parentAbsY, parentAbsScale, parentChildOffsetX, parentChildOffsetY)
|
|
143
|
+
|
|
144
|
+
if (node.diagramId === viewId && node.elementId === elementId) {
|
|
145
|
+
return target
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (node.children.length > 0) {
|
|
149
|
+
const found = findElementInNodes(
|
|
150
|
+
viewId,
|
|
151
|
+
elementId,
|
|
152
|
+
node.children,
|
|
153
|
+
target.absX,
|
|
154
|
+
target.absY,
|
|
155
|
+
parentAbsScale * node.childScale,
|
|
156
|
+
node.childOffsetX,
|
|
157
|
+
node.childOffsetY,
|
|
158
|
+
)
|
|
159
|
+
if (found) return found
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return null
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function findDiagramFocusTarget(groups: DiagramGroupLayout[], viewId: number): ZUIFocusTarget | null {
|
|
167
|
+
for (const group of groups) {
|
|
168
|
+
if (group.diagramId === viewId) {
|
|
169
|
+
return {
|
|
170
|
+
id: `g-${group.diagramId}`,
|
|
171
|
+
label: group.label,
|
|
172
|
+
type: 'group',
|
|
173
|
+
absX: group.worldX,
|
|
174
|
+
absY: group.worldY,
|
|
175
|
+
absW: group.worldW,
|
|
176
|
+
absH: group.worldH,
|
|
177
|
+
absScale: 1,
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const found = findLinkedDiagramInNodes(viewId, group.nodes, 0, 0, 1, 0, 0)
|
|
182
|
+
if (found) return found
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function findElementFocusTarget(groups: DiagramGroupLayout[], viewId: number, elementId: number): ZUIFocusTarget | null {
|
|
189
|
+
for (const group of groups) {
|
|
190
|
+
const found = findElementInNodes(viewId, elementId, group.nodes, 0, 0, 1, 0, 0)
|
|
191
|
+
if (found) return found
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return null
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function viewportForFocusTarget(
|
|
198
|
+
target: ZUIFocusTarget,
|
|
199
|
+
canvasW: number,
|
|
200
|
+
canvasH: number,
|
|
201
|
+
maxZoom: number,
|
|
202
|
+
padding: number,
|
|
203
|
+
options: ZUIFocusViewportOptions = {},
|
|
204
|
+
): ZUIViewState | null {
|
|
205
|
+
const rect = options.preferContent && target.contentRect ? target.contentRect : {
|
|
206
|
+
x: target.absX,
|
|
207
|
+
y: target.absY,
|
|
208
|
+
w: target.absW,
|
|
209
|
+
h: target.absH,
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const bboxW = positiveSize(rect.w)
|
|
213
|
+
const bboxH = positiveSize(rect.h)
|
|
214
|
+
const fitZoom = Math.min(
|
|
215
|
+
(canvasW * (1 - padding * 2)) / bboxW,
|
|
216
|
+
(canvasH * (1 - padding * 2)) / bboxH,
|
|
217
|
+
)
|
|
218
|
+
const minZooms: number[] = []
|
|
219
|
+
|
|
220
|
+
if (options.minTargetScreenW && target.absW > 0) {
|
|
221
|
+
minZooms.push(options.minTargetScreenW / target.absW)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (target.node?.children.length && options.minChildScreenW && target.node.childScale > 0) {
|
|
225
|
+
const childAbsW = target.node.worldW * target.absScale * target.node.childScale
|
|
226
|
+
if (childAbsW > 0) {
|
|
227
|
+
minZooms.push(options.minChildScreenW / childAbsW)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const finiteMinZooms = minZooms.filter((value) => Number.isFinite(value) && value > 0)
|
|
232
|
+
const zoomLimit = Math.max(maxZoom, ...finiteMinZooms)
|
|
233
|
+
let zoom = Math.min(fitZoom, zoomLimit)
|
|
234
|
+
|
|
235
|
+
for (const minZoom of finiteMinZooms) {
|
|
236
|
+
zoom = Math.max(zoom, Math.min(minZoom, zoomLimit))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (target.node?.children.length && options.keepParentVisible) {
|
|
240
|
+
const thresholds = getExpandThresholds(canvasW)
|
|
241
|
+
const maxParentScreenW = thresholds.start + (thresholds.end - thresholds.start) * 0.78
|
|
242
|
+
zoom = Math.min(zoom, maxParentScreenW / positiveSize(target.absW))
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!Number.isFinite(zoom) || zoom <= 0) return null
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
x: (canvasW - bboxW * zoom) / 2 - rect.x * zoom,
|
|
249
|
+
y: (canvasH - bboxH * zoom) / 2 - rect.y * zoom,
|
|
250
|
+
zoom,
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function viewportForDiagramFocusTarget(
|
|
255
|
+
target: ZUIFocusTarget,
|
|
256
|
+
canvasW: number,
|
|
257
|
+
canvasH: number,
|
|
258
|
+
maxZoom: number,
|
|
259
|
+
isMobileLayout: boolean,
|
|
260
|
+
): ZUIViewState | null {
|
|
261
|
+
return viewportForFocusTarget(
|
|
262
|
+
target,
|
|
263
|
+
canvasW,
|
|
264
|
+
canvasH,
|
|
265
|
+
maxZoom,
|
|
266
|
+
isMobileLayout ? 0.18 : 0.16,
|
|
267
|
+
{
|
|
268
|
+
preferContent: true,
|
|
269
|
+
minTargetScreenW: isMobileLayout ? 180 : 260,
|
|
270
|
+
minChildScreenW: isMobileLayout ? 76 : 104,
|
|
271
|
+
},
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export function viewportForElementFocusTarget(
|
|
276
|
+
target: ZUIFocusTarget,
|
|
277
|
+
canvasW: number,
|
|
278
|
+
canvasH: number,
|
|
279
|
+
maxZoom: number,
|
|
280
|
+
isMobileLayout: boolean,
|
|
281
|
+
): ZUIViewState | null {
|
|
282
|
+
return viewportForFocusTarget(
|
|
283
|
+
target,
|
|
284
|
+
canvasW,
|
|
285
|
+
canvasH,
|
|
286
|
+
maxZoom,
|
|
287
|
+
isMobileLayout ? 0.2 : 0.18,
|
|
288
|
+
{
|
|
289
|
+
minTargetScreenW: isMobileLayout ? 220 : 320,
|
|
290
|
+
keepParentVisible: true,
|
|
291
|
+
},
|
|
292
|
+
)
|
|
293
|
+
}
|
|
@@ -10,15 +10,15 @@ import type {
|
|
|
10
10
|
ExploreData,
|
|
11
11
|
ViewConnector,
|
|
12
12
|
} from '../../types'
|
|
13
|
-
import {
|
|
13
|
+
import { resolveElementIconUrl } from '../../utils/elementIcon'
|
|
14
14
|
|
|
15
15
|
// ── Constants ──────────────────────────────────────────────────────
|
|
16
16
|
|
|
17
|
-
export const NODE_W =
|
|
18
|
-
export const NODE_H =
|
|
17
|
+
export const NODE_W = 180
|
|
18
|
+
export const NODE_H = 85
|
|
19
19
|
const GROUP_PAD = 80 // padding inside a diagram group box
|
|
20
20
|
const GROUP_SPACING = 400 // horizontal gap between root diagrams
|
|
21
|
-
const CHILD_PAD =
|
|
21
|
+
const CHILD_PAD = 4 // padding inside a node when rendering children
|
|
22
22
|
|
|
23
23
|
// ── Helpers ────────────────────────────────────────────────────────
|
|
24
24
|
|
|
@@ -159,6 +159,7 @@ function buildNodes(
|
|
|
159
159
|
const edgesOut = (views[String(diagramId)]?.connectors ?? [])
|
|
160
160
|
.filter((e) => e.source_element_id === obj.element_id)
|
|
161
161
|
.map((e) => ({
|
|
162
|
+
id: e.id,
|
|
162
163
|
targetId: nodeId(diagramId, e.target_element_id),
|
|
163
164
|
label: e.label ?? '',
|
|
164
165
|
direction: e.direction ?? 'forward',
|
|
@@ -167,12 +168,6 @@ function buildNodes(
|
|
|
167
168
|
type: e.style || 'bezier',
|
|
168
169
|
}))
|
|
169
170
|
|
|
170
|
-
const derivedPrimaryIconPath = (() => {
|
|
171
|
-
const selected = obj.technology_connectors?.find((link) => link.type === 'catalog' && !!(link.is_primary_icon ?? (link as any).isPrimaryIcon) && !!link.slug)
|
|
172
|
-
if (!selected?.slug) return null
|
|
173
|
-
return resolveIconPath(`/icons/${selected.slug}.png`)
|
|
174
|
-
})()
|
|
175
|
-
|
|
176
171
|
return {
|
|
177
172
|
id: nodeId(diagramId, obj.element_id),
|
|
178
173
|
elementId: obj.element_id,
|
|
@@ -183,7 +178,7 @@ function buildNodes(
|
|
|
183
178
|
worldH: NODE_H,
|
|
184
179
|
label: obj.name,
|
|
185
180
|
type: obj.kind ?? 'system',
|
|
186
|
-
logoUrl: obj.logo_url
|
|
181
|
+
logoUrl: resolveElementIconUrl(obj.logo_url, obj.technology_connectors),
|
|
187
182
|
description: obj.description ?? null,
|
|
188
183
|
technology: obj.technology ?? null,
|
|
189
184
|
tags: obj.tags ?? [],
|
|
@@ -253,6 +248,7 @@ export function computeLayout(data: ExploreData): ZUILayout {
|
|
|
253
248
|
|
|
254
249
|
// Edges within the same diagram (world-level, not children)
|
|
255
250
|
const edges = (diagData.connectors ?? []).map((e) => ({
|
|
251
|
+
id: e.id,
|
|
256
252
|
sourceId: nodeId(diag.id, e.source_element_id),
|
|
257
253
|
targetId: nodeId(diag.id, e.target_element_id),
|
|
258
254
|
label: e.label ?? '',
|