@likec4/diagram 1.44.0 → 1.45.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/index.js +18160 -17671
- package/dist/LikeC4Diagram.js +7 -5
- package/dist/LikeC4Diagram.props.d.ts +9 -8
- package/dist/LikeC4Styles.js +0 -3
- package/dist/LikeC4View.d.ts +3 -3
- package/dist/LikeC4View.js +7 -3
- package/dist/ReactLikeC4.d.ts +2 -2
- package/dist/base/Base.d.ts +1 -1
- package/dist/base/updateEdges.js +25 -15
- package/dist/base/updateNodes.d.ts +14 -0
- package/dist/base/updateNodes.js +51 -18
- package/dist/base-primitives/Markdown.d.ts +30 -4
- package/dist/base-primitives/Markdown.js +3 -2
- package/dist/base-primitives/compound/CompoundActionButton.d.ts +3 -2
- package/dist/base-primitives/compound/CompoundDetailsButton.d.ts +3 -2
- package/dist/base-primitives/edge/EdgeActionButton.d.ts +3 -2
- package/dist/base-primitives/edge/EdgeContainer.d.ts +1 -1
- package/dist/base-primitives/edge/EdgeContainer.js +4 -1
- package/dist/base-primitives/edge/EdgeLabel.d.ts +2 -2
- package/dist/base-primitives/edge/EdgePath.js +24 -4
- package/dist/base-primitives/element/ElementActionButtons.d.ts +3 -2
- package/dist/base-primitives/element/ElementActionButtons.js +2 -2
- package/dist/base-primitives/element/ElementData.d.ts +3 -3
- package/dist/base-primitives/element/ElementData.js +13 -7
- package/dist/base-primitives/element/ElementDetailsButton.d.ts +3 -2
- package/dist/base-primitives/element/ElementDetailsButton.js +3 -0
- package/dist/base-primitives/element/ElementShape.js +5 -5
- package/dist/base-primitives/element/ElementTags.d.ts +6 -4
- package/dist/context/DiagramFeatures.d.ts +1 -0
- package/dist/context/TagStylesContext.js +1 -1
- package/dist/custom/hooks.d.ts +2 -2
- package/dist/custom/index.js +1 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/useDiagramCompareLayout.js +7 -2
- package/dist/hooks/useLikeC4Project.d.ts +6 -1
- package/dist/hooks/useLikeC4Project.js +14 -2
- package/dist/hooks/useMediaPrint.d.ts +6 -0
- package/dist/likec4diagram/DiagramXYFlow.js +11 -6
- package/dist/likec4diagram/custom/edges/EdgeDrifts.d.ts +6 -0
- package/dist/likec4diagram/custom/edges/EdgeDrifts.js +38 -0
- package/dist/likec4diagram/custom/edges/RelationshipEdge.js +24 -14
- package/dist/likec4diagram/custom/edges/SequenceStepEdge.js +3 -1
- package/dist/likec4diagram/custom/edges/useControlPoints.js +3 -3
- package/dist/likec4diagram/custom/edges/useRelationshipEdgePath.js +5 -5
- package/dist/likec4diagram/custom/nodes/NodeDrifts.d.ts +6 -0
- package/dist/likec4diagram/custom/nodes/{ElementNodeDrifts.js → NodeDrifts.js} +8 -4
- package/dist/likec4diagram/custom/nodes/SequenceActorNode.js +4 -2
- package/dist/likec4diagram/custom/nodes/index.d.ts +1 -0
- package/dist/likec4diagram/custom/nodes/nodes.js +64 -23
- package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +3 -3
- package/dist/likec4diagram/relationship-popover/actor.d.ts +1 -1
- package/dist/likec4diagram/state/DiagramActorProvider.d.ts +2 -2
- package/dist/likec4diagram/state/DiagramActorProvider.js +0 -1
- package/dist/likec4diagram/state/assign.d.ts +10 -6
- package/dist/likec4diagram/state/assign.js +17 -192
- package/dist/likec4diagram/state/createViewChange.js +15 -26
- package/dist/likec4diagram/state/diagram-api.d.ts +2 -6
- package/dist/likec4diagram/state/diagram-api.js +2 -10
- package/dist/likec4diagram/state/hotkeyActor.d.ts +0 -7
- package/dist/likec4diagram/state/hotkeyActor.js +1 -17
- package/dist/likec4diagram/state/machine.actions.d.ts +430 -746
- package/dist/likec4diagram/state/machine.actions.js +193 -284
- package/dist/likec4diagram/state/machine.actions.layout.d.ts +579 -0
- package/dist/likec4diagram/state/machine.actions.layout.js +129 -0
- package/dist/likec4diagram/state/machine.d.ts +17 -3712
- package/dist/likec4diagram/state/machine.js +59 -73
- package/dist/likec4diagram/state/machine.setup.d.ts +61 -18
- package/dist/likec4diagram/state/machine.setup.js +27 -5
- package/dist/likec4diagram/state/machine.state.initializing.d.ts +25 -0
- package/dist/likec4diagram/state/machine.state.initializing.js +5 -5
- package/dist/likec4diagram/state/machine.state.navigating.d.ts +5 -108
- package/dist/likec4diagram/state/machine.state.navigating.js +167 -34
- package/dist/likec4diagram/state/machine.state.ready.d.ts +2316 -2851
- package/dist/likec4diagram/state/machine.state.ready.focused.d.ts +386 -0
- package/dist/likec4diagram/state/machine.state.ready.focused.js +85 -0
- package/dist/likec4diagram/state/machine.state.ready.idle.d.ts +474 -0
- package/dist/likec4diagram/state/machine.state.ready.idle.js +96 -0
- package/dist/likec4diagram/state/machine.state.ready.js +144 -319
- package/dist/likec4diagram/state/machine.state.ready.printing.d.ts +128 -0
- package/dist/likec4diagram/state/machine.state.ready.printing.js +40 -0
- package/dist/likec4diagram/state/machine.state.ready.walkthrough.d.ts +511 -0
- package/dist/likec4diagram/state/machine.state.ready.walkthrough.js +177 -0
- package/dist/likec4diagram/state/mediaPrintActor.d.ts +12 -0
- package/dist/likec4diagram/state/mediaPrintActor.js +18 -0
- package/dist/likec4diagram/state/syncManualLayoutActor.d.ts +6 -240
- package/dist/likec4diagram/state/syncManualLayoutActor.js +150 -89
- package/dist/likec4diagram/state/types.d.ts +5 -7
- package/dist/likec4diagram/state/utils.d.ts +15 -2
- package/dist/likec4diagram/state/utils.js +43 -3
- package/dist/likec4diagram/types.d.ts +8 -13
- package/dist/likec4diagram/ui/notation/NotationPanel.css.js +5 -2
- package/dist/likec4diagram/useLayoutConstraints.js +107 -102
- package/dist/likec4diagram/xyflow-diagram/diagram-view.js +12 -15
- package/dist/likec4diagram/xyflow-sequence/sequence-layout.js +11 -8
- package/dist/navigationpanel/NavigationPanel.js +5 -1
- package/dist/navigationpanel/actor.d.ts +4 -204
- package/dist/navigationpanel/actor.js +1 -1
- package/dist/navigationpanel/controls/ToggleReadonly.js +8 -3
- package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +66 -66
- package/dist/navigationpanel/walkthrough/WalkthroughPanel.js +4 -3
- package/dist/overlays/element-details/ElementDetailsCard.css.js +3 -3
- package/dist/overlays/element-details/MetadataValue.d.ts +2 -1
- package/dist/overlays/element-details/actor.d.ts +8 -83
- package/dist/overlays/element-details/actor.js +0 -8
- package/dist/overlays/overlay/Overlay.js +10 -10
- package/dist/overlays/overlaysActor.d.ts +7 -392
- package/dist/overlays/overlaysActor.js +67 -46
- package/dist/overlays/relationship-details/_types.d.ts +3 -4
- package/dist/overlays/relationship-details/actor.d.ts +6 -562
- package/dist/overlays/relationship-details/actor.js +1 -0
- package/dist/overlays/relationship-details/layout-to-xyflow.js +3 -5
- package/dist/overlays/relationship-details/layout.d.ts +3 -3
- package/dist/overlays/relationship-details/layout.js +4 -4
- package/dist/overlays/relationships-browser/_types.d.ts +2 -3
- package/dist/overlays/relationships-browser/actor.d.ts +7 -739
- package/dist/overlays/relationships-browser/layout.d.ts +2 -2
- package/dist/overlays/relationships-browser/layout.js +3 -3
- package/dist/overlays/relationships-browser/useViewToNodesEdges.js +0 -3
- package/dist/overlays/types.d.ts +12 -13
- package/dist/search/components/_shared.css.d.ts +1 -1
- package/dist/search/searchActor.d.ts +3 -66
- package/dist/shadowroot/ShadowRoot.d.ts +5 -7
- package/dist/shadowroot/ShadowRoot.js +7 -5
- package/dist/styles.css2.js +1 -1
- package/dist/utils/vector.d.ts +5 -0
- package/dist/utils/vector.js +7 -0
- package/dist/utils/view-bounds.js +7 -6
- package/dist/utils/xyflow.d.ts +4 -2
- package/dist/utils/xyflow.js +18 -50
- package/package.json +19 -18
- package/panda.buildinfo.json +17 -5
- package/styles-min.css +1 -1
- package/styles.css +1 -1
- package/dist/likec4diagram/custom/nodes/ElementNodeDrifts.d.ts +0 -4
|
@@ -1,121 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getViewportForBounds } from '@xyflow/react';
|
|
1
|
+
import { nonNullable, nonexhaustive, invariant } from '@likec4/core';
|
|
3
2
|
import { nodeToRect } from '@xyflow/system';
|
|
4
|
-
import {
|
|
3
|
+
import { produce } from 'immer';
|
|
4
|
+
import { isTruthy, hasAtLeast } from 'remeda';
|
|
5
5
|
import { assertEvent } from 'xstate';
|
|
6
6
|
import { createLayoutConstraints } from '../useLayoutConstraints.js';
|
|
7
7
|
import { getAligner, toNodeRect } from './aligners.js';
|
|
8
|
-
import {
|
|
8
|
+
import { resetEdgeControlPoints, mergeXYNodesEdges, focusNodesEdges } from './assign.js';
|
|
9
9
|
import { createViewChange } from './createViewChange.js';
|
|
10
10
|
import { machine } from './machine.setup.js';
|
|
11
|
-
import { typedSystem,
|
|
12
|
-
import { MinZoom } from '../../base/const.js';
|
|
11
|
+
import { typedSystem, findDiagramEdge, findDiagramNode } from './utils.js';
|
|
13
12
|
import { Base } from '../../base/Base.js';
|
|
14
13
|
|
|
15
|
-
function nodeRef(node) {
|
|
16
|
-
switch (node.type) {
|
|
17
|
-
case "element":
|
|
18
|
-
case "compound-element":
|
|
19
|
-
case "seq-actor":
|
|
20
|
-
return node.data.modelFqn;
|
|
21
|
-
case "deployment":
|
|
22
|
-
case "compound-deployment":
|
|
23
|
-
return node.data.modelFqn ?? node.data.deploymentFqn;
|
|
24
|
-
case "seq-parallel":
|
|
25
|
-
case "view-group":
|
|
26
|
-
return null;
|
|
27
|
-
default:
|
|
28
|
-
nonexhaustive(node);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function findCorrespondingNode(context, event) {
|
|
32
|
-
const fromNodeId = context.lastOnNavigate?.fromNode;
|
|
33
|
-
const fromNode = fromNodeId && context.xynodes.find((n) => n.id === fromNodeId);
|
|
34
|
-
const fromRef = fromNode && nodeRef(fromNode);
|
|
35
|
-
const toNode = fromRef && event.xynodes.find((n) => nodeRef(n) === fromRef);
|
|
36
|
-
return { fromNode, toNode };
|
|
37
|
-
}
|
|
38
|
-
const trigger = {
|
|
39
|
-
navigateTo: () => machine.emit(({ context }) => ({
|
|
40
|
-
type: "navigateTo",
|
|
41
|
-
viewId: nonNullable(context.lastOnNavigate, "Invalid state, lastOnNavigate is null").toView
|
|
42
|
-
}))
|
|
43
|
-
};
|
|
44
|
-
const xyflow = {
|
|
45
|
-
fitDiagram: (params) => machine.createAction(({ context, event }) => {
|
|
46
|
-
params ??= event.type === "fitDiagram" ? event : {};
|
|
47
|
-
const {
|
|
48
|
-
bounds = context.view.bounds,
|
|
49
|
-
duration = 450
|
|
50
|
-
} = params;
|
|
51
|
-
const { width, height, panZoom, transform } = nonNullable(context.xystore).getState();
|
|
52
|
-
const maxZoom = Math.max(1, transform[2]);
|
|
53
|
-
const viewport = getViewportForBounds(
|
|
54
|
-
bounds,
|
|
55
|
-
width,
|
|
56
|
-
height,
|
|
57
|
-
MinZoom,
|
|
58
|
-
maxZoom,
|
|
59
|
-
context.fitViewPadding
|
|
60
|
-
);
|
|
61
|
-
viewport.x = Math.round(viewport.x);
|
|
62
|
-
viewport.y = Math.round(viewport.y);
|
|
63
|
-
panZoom?.setViewport(viewport, duration > 0 ? { duration, interpolate: "smooth" } : void 0).catch(
|
|
64
|
-
console.error
|
|
65
|
-
);
|
|
66
|
-
}),
|
|
67
|
-
fitFocusedBounds: () => machine.createAction(({ context }) => {
|
|
68
|
-
const isActiveSequenceWalkthrough = !!context.activeWalkthrough && context.dynamicViewVariant === "sequence";
|
|
69
|
-
const { bounds, duration = 450 } = isActiveSequenceWalkthrough ? activeSequenceBounds({ context }) : focusedBounds({ context });
|
|
70
|
-
const { width, height, panZoom, transform } = nonNullable(context.xystore).getState();
|
|
71
|
-
const maxZoom = Math.max(1, transform[2]);
|
|
72
|
-
const viewport = getViewportForBounds(
|
|
73
|
-
bounds,
|
|
74
|
-
width,
|
|
75
|
-
height,
|
|
76
|
-
MinZoom,
|
|
77
|
-
maxZoom,
|
|
78
|
-
context.fitViewPadding
|
|
79
|
-
);
|
|
80
|
-
viewport.x = Math.round(viewport.x);
|
|
81
|
-
viewport.y = Math.round(viewport.y);
|
|
82
|
-
panZoom?.setViewport(viewport, duration > 0 ? { duration, interpolate: "smooth" } : void 0);
|
|
83
|
-
}),
|
|
84
|
-
alignNodeFromToAfterNavigate: (params) => machine.createAction(({ context }) => {
|
|
85
|
-
const xyflow2 = nonNullable(context.xyflow, "xyflow is not initialized");
|
|
86
|
-
const elFrom = xyflow2.getInternalNode(params.fromNode);
|
|
87
|
-
if (!elFrom) return;
|
|
88
|
-
const fromPos = xyflow2.flowToScreenPosition({
|
|
89
|
-
x: elFrom.internals.positionAbsolute.x,
|
|
90
|
-
y: elFrom.internals.positionAbsolute.y
|
|
91
|
-
}), toPos = xyflow2.flowToScreenPosition(params.toPosition), diff = {
|
|
92
|
-
x: Math.round(fromPos.x - toPos.x),
|
|
93
|
-
y: Math.round(fromPos.y - toPos.y)
|
|
94
|
-
};
|
|
95
|
-
context.xystore.getState().panBy(diff);
|
|
96
|
-
}),
|
|
97
|
-
setViewportCenter: (params) => machine.createAction(({ context, event }) => {
|
|
98
|
-
let center;
|
|
99
|
-
if (params) {
|
|
100
|
-
center = params;
|
|
101
|
-
} else if (event.type === "update.view") {
|
|
102
|
-
center = BBox.center(event.view.bounds);
|
|
103
|
-
} else {
|
|
104
|
-
center = BBox.center(context.view.bounds);
|
|
105
|
-
}
|
|
106
|
-
invariant(context.xyflow, "xyflow is not initialized");
|
|
107
|
-
const zoom = context.xyflow.getZoom();
|
|
108
|
-
context.xyflow.setCenter(Math.round(center.x), Math.round(center.y), { zoom });
|
|
109
|
-
}),
|
|
110
|
-
setViewport: (params) => machine.createAction(({ context }) => {
|
|
111
|
-
const {
|
|
112
|
-
viewport,
|
|
113
|
-
duration = 350
|
|
114
|
-
} = params;
|
|
115
|
-
const panZoom = context.xystore?.getState().panZoom;
|
|
116
|
-
panZoom?.setViewport(viewport, duration > 0 ? { duration, interpolate: "smooth" } : void 0);
|
|
117
|
-
})
|
|
118
|
-
};
|
|
119
14
|
const disableCompareWithLatest = () => machine.assign(({ context }) => {
|
|
120
15
|
return {
|
|
121
16
|
toggledFeatures: {
|
|
@@ -143,7 +38,7 @@ const onEdgeDoubleClick = () => machine.assign(({ context, event }) => {
|
|
|
143
38
|
...e.data,
|
|
144
39
|
controlPoints,
|
|
145
40
|
labelBBox: e.data.labelBBox ? { ...e.data.labelBBox, ...pt } : null,
|
|
146
|
-
labelXY:
|
|
41
|
+
labelXY: null
|
|
147
42
|
}
|
|
148
43
|
};
|
|
149
44
|
}
|
|
@@ -151,60 +46,6 @@ const onEdgeDoubleClick = () => machine.assign(({ context, event }) => {
|
|
|
151
46
|
})
|
|
152
47
|
};
|
|
153
48
|
});
|
|
154
|
-
const emitOnChange = () => machine.enqueueActions(({ event, enqueue }) => {
|
|
155
|
-
assertEvent(event, "emit.onChange");
|
|
156
|
-
enqueue.assign({
|
|
157
|
-
viewportChangedManually: true
|
|
158
|
-
});
|
|
159
|
-
enqueue.emit({
|
|
160
|
-
type: "onChange",
|
|
161
|
-
change: event.change
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
const emitOnLayoutTypeChange = () => machine.enqueueActions(({ event, system, context, enqueue }) => {
|
|
165
|
-
if (!context.features.enableCompareWithLatest) {
|
|
166
|
-
console.warn("Layout type cannot be changed while CompareWithLatest feature is disabled");
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const currentLayoutType = context.view._layout;
|
|
170
|
-
let nextLayoutType = currentLayoutType === "auto" ? "manual" : "auto";
|
|
171
|
-
if (event.type === "emit.onLayoutTypeChange") {
|
|
172
|
-
nextLayoutType = event.layoutType;
|
|
173
|
-
}
|
|
174
|
-
if (currentLayoutType === nextLayoutType) {
|
|
175
|
-
console.warn("Ignoring layout type change event, layout type is already", currentLayoutType);
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
if (context.toggledFeatures.enableCompareWithLatest === true) {
|
|
179
|
-
if (currentLayoutType === "manual" && nextLayoutType === "auto") {
|
|
180
|
-
const syncLayoutActor = typedSystem(system).syncLayoutActorRef;
|
|
181
|
-
const syncState = syncLayoutActor?.getSnapshot().value;
|
|
182
|
-
const isPending = syncLayoutActor && (syncState === "pending" || syncState === "paused");
|
|
183
|
-
if (isPending) {
|
|
184
|
-
enqueue.sendTo(syncLayoutActor, { type: "cancel" });
|
|
185
|
-
enqueue.emit({
|
|
186
|
-
type: "onChange",
|
|
187
|
-
change: createViewChange(context)
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
const currentViewport = context.viewport;
|
|
192
|
-
if (currentLayoutType === "auto") {
|
|
193
|
-
enqueue.assign({
|
|
194
|
-
viewportOnAutoLayout: currentViewport
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
if (currentLayoutType === "manual") {
|
|
198
|
-
enqueue.assign({
|
|
199
|
-
viewportOnManualLayout: currentViewport
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
enqueue.emit({
|
|
204
|
-
type: "onLayoutTypeChange",
|
|
205
|
-
layoutType: nextLayoutType
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
49
|
const assignLastClickedNode = () => machine.assign(({ context, event }) => {
|
|
209
50
|
assertEvent(event, "xyflow.nodeClick");
|
|
210
51
|
const { lastClickedNode } = context;
|
|
@@ -256,10 +97,23 @@ const updateInputs = () => machine.assign(({ event }) => {
|
|
|
256
97
|
});
|
|
257
98
|
const updateXYNodesEdges = () => machine.assign(({ context, event }) => {
|
|
258
99
|
assertEvent(event, "update.view");
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
100
|
+
const update = mergeXYNodesEdges(context, event);
|
|
101
|
+
let { lastClickedNode, focusedNode } = context;
|
|
102
|
+
if (lastClickedNode || focusedNode) {
|
|
103
|
+
const nodeIds = new Set(update.xynodes.map((n) => n.id));
|
|
104
|
+
if (lastClickedNode && !nodeIds.has(lastClickedNode.id)) {
|
|
105
|
+
lastClickedNode = null;
|
|
106
|
+
}
|
|
107
|
+
if (focusedNode && !nodeIds.has(focusedNode)) {
|
|
108
|
+
focusedNode = null;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
...update,
|
|
112
|
+
lastClickedNode,
|
|
113
|
+
focusedNode
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return update;
|
|
263
117
|
});
|
|
264
118
|
const focusOnNodesAndEdges = () => machine.assign(focusNodesEdges);
|
|
265
119
|
const undimEverything = () => machine.assign(({ context }) => ({
|
|
@@ -269,7 +123,6 @@ const undimEverything = () => machine.assign(({ context }) => ({
|
|
|
269
123
|
active: false
|
|
270
124
|
}))
|
|
271
125
|
}));
|
|
272
|
-
const updateActiveWalkthroughState = () => machine.assign(updateActiveWalkthrough);
|
|
273
126
|
const assignDynamicViewVariant = () => machine.assign(({ event }) => {
|
|
274
127
|
assertEvent(event, "switch.dynamicViewVariant");
|
|
275
128
|
return {
|
|
@@ -306,9 +159,6 @@ const onNodeMouseLeave = (params) => machine.assign(({ context, event }) => {
|
|
|
306
159
|
})
|
|
307
160
|
};
|
|
308
161
|
});
|
|
309
|
-
const emitWalkthroughStopped = () => machine.emit(() => ({
|
|
310
|
-
type: "walkthroughStopped"
|
|
311
|
-
}));
|
|
312
162
|
const emitPaneClick = () => machine.emit(() => ({
|
|
313
163
|
type: "paneClick"
|
|
314
164
|
}));
|
|
@@ -341,6 +191,10 @@ const emitNodeClick = () => machine.emit(({ context, event }) => {
|
|
|
341
191
|
xynode: event.node
|
|
342
192
|
};
|
|
343
193
|
});
|
|
194
|
+
const emitNavigateTo = (params) => machine.emit(({ context }) => ({
|
|
195
|
+
type: "navigateTo",
|
|
196
|
+
viewId: params?.viewId ?? nonNullable(context.lastOnNavigate, "Invalid state, lastOnNavigate is null").toView
|
|
197
|
+
}));
|
|
344
198
|
const emitEdgeClick = () => machine.emit(({ context, event }) => {
|
|
345
199
|
assertEvent(event, "xyflow.edgeClick");
|
|
346
200
|
const edge = nonNullable(findDiagramEdge(context, event.edge.id), `Edge ${event.edge.id} not found in diagram`);
|
|
@@ -350,21 +204,59 @@ const emitEdgeClick = () => machine.emit(({ context, event }) => {
|
|
|
350
204
|
xyedge: event.edge
|
|
351
205
|
};
|
|
352
206
|
});
|
|
353
|
-
const
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
207
|
+
const emitOnChange = () => machine.enqueueActions(({ event, enqueue }) => {
|
|
208
|
+
assertEvent(event, "emit.onChange");
|
|
209
|
+
enqueue.assign({
|
|
210
|
+
viewportChangedManually: true
|
|
211
|
+
});
|
|
212
|
+
enqueue.emit({
|
|
213
|
+
type: "onChange",
|
|
214
|
+
change: event.change
|
|
215
|
+
});
|
|
360
216
|
});
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
217
|
+
const emitOnLayoutTypeChange = () => machine.enqueueActions(({ event, system, context, enqueue }) => {
|
|
218
|
+
if (!context.features.enableCompareWithLatest) {
|
|
219
|
+
console.warn("Layout type cannot be changed while CompareWithLatest feature is disabled");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const currentLayoutType = context.view._layout;
|
|
223
|
+
let nextLayoutType = currentLayoutType === "auto" ? "manual" : "auto";
|
|
224
|
+
if (event.type === "emit.onLayoutTypeChange") {
|
|
225
|
+
nextLayoutType = event.layoutType;
|
|
226
|
+
}
|
|
227
|
+
if (currentLayoutType === nextLayoutType) {
|
|
228
|
+
console.warn("Ignoring layout type change event, layout type is already", currentLayoutType);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (context.toggledFeatures.enableCompareWithLatest === true) {
|
|
232
|
+
if (currentLayoutType === "manual" && nextLayoutType === "auto") {
|
|
233
|
+
const syncLayoutActor = typedSystem(system).syncLayoutActorRef;
|
|
234
|
+
const syncState = syncLayoutActor?.getSnapshot().value;
|
|
235
|
+
const isPending = syncLayoutActor && (syncState === "pending" || syncState === "paused");
|
|
236
|
+
if (isPending) {
|
|
237
|
+
enqueue.sendTo(syncLayoutActor, { type: "cancel" });
|
|
238
|
+
enqueue.emit({
|
|
239
|
+
type: "onChange",
|
|
240
|
+
change: createViewChange(context)
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const currentViewport = context.viewport;
|
|
245
|
+
if (currentLayoutType === "auto") {
|
|
246
|
+
enqueue.assign({
|
|
247
|
+
viewportOnAutoLayout: currentViewport
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
if (currentLayoutType === "manual") {
|
|
251
|
+
enqueue.assign({
|
|
252
|
+
viewportOnManualLayout: currentViewport
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
enqueue.emit({
|
|
257
|
+
type: "onLayoutTypeChange",
|
|
258
|
+
layoutType: nextLayoutType
|
|
259
|
+
});
|
|
368
260
|
});
|
|
369
261
|
const layoutAlign = (params) => machine.createAction(({ context, event }) => {
|
|
370
262
|
let mode;
|
|
@@ -448,7 +340,7 @@ const tagHighlight = () => machine.assign(({ context, event }) => {
|
|
|
448
340
|
})
|
|
449
341
|
};
|
|
450
342
|
});
|
|
451
|
-
const
|
|
343
|
+
const assignToggledFeatures = () => machine.assign(({ context, event }) => {
|
|
452
344
|
assertEvent(event, "toggle.feature");
|
|
453
345
|
const currentValue = context.toggledFeatures[`enable${event.feature}`] ?? context.features[`enable${event.feature}`];
|
|
454
346
|
const nextValue = event.forceValue ?? !currentValue;
|
|
@@ -471,29 +363,28 @@ const closeAllOverlays = () => machine.sendTo(
|
|
|
471
363
|
type: "close.all"
|
|
472
364
|
}
|
|
473
365
|
);
|
|
474
|
-
const isReadOnly = (context) => context.features.enableReadOnly || context.toggledFeatures.enableReadOnly === true;
|
|
475
366
|
const stopSyncLayout = () => machine.enqueueActions(({ enqueue, system }) => {
|
|
476
367
|
const syncLayoutActor = typedSystem(system).syncLayoutActorRef;
|
|
477
368
|
if (!syncLayoutActor) return;
|
|
478
369
|
enqueue.stopChild(syncLayoutActor);
|
|
479
370
|
});
|
|
480
|
-
const
|
|
371
|
+
const ensureSyncLayoutActor = () => machine.enqueueActions(({ context, enqueue, system, check }) => {
|
|
372
|
+
const isReadOnly = check("enabled: Readonly");
|
|
481
373
|
const syncLayoutActor = typedSystem(system).syncLayoutActorRef;
|
|
482
|
-
if (isReadOnly
|
|
483
|
-
|
|
484
|
-
enqueue.stopChild(syncLayoutActor);
|
|
485
|
-
}
|
|
374
|
+
if (isReadOnly && syncLayoutActor) {
|
|
375
|
+
enqueue.stopChild(syncLayoutActor);
|
|
486
376
|
return;
|
|
487
377
|
}
|
|
488
|
-
if (syncLayoutActor)
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
378
|
+
if (!isReadOnly && !syncLayoutActor) {
|
|
379
|
+
enqueue.spawnChild("syncManualLayoutActorLogic", {
|
|
380
|
+
id: "syncLayout",
|
|
381
|
+
systemId: "syncLayout",
|
|
382
|
+
input: {
|
|
383
|
+
viewId: context.view.id
|
|
384
|
+
},
|
|
385
|
+
syncSnapshot: true
|
|
386
|
+
});
|
|
387
|
+
}
|
|
497
388
|
});
|
|
498
389
|
const startEditing = (subject = "node") => machine.sendTo(
|
|
499
390
|
({ system }) => typedSystem(system).syncLayoutActorRef,
|
|
@@ -502,6 +393,12 @@ const startEditing = (subject = "node") => machine.sendTo(
|
|
|
502
393
|
subject
|
|
503
394
|
}
|
|
504
395
|
);
|
|
396
|
+
const sendSynced = () => machine.sendTo(
|
|
397
|
+
({ system }) => typedSystem(system).syncLayoutActorRef,
|
|
398
|
+
{
|
|
399
|
+
type: "synced"
|
|
400
|
+
}
|
|
401
|
+
);
|
|
505
402
|
const stopEditing = (wasChanged = true) => machine.sendTo(
|
|
506
403
|
({ system }) => typedSystem(system).syncLayoutActorRef,
|
|
507
404
|
{
|
|
@@ -509,6 +406,12 @@ const stopEditing = (wasChanged = true) => machine.sendTo(
|
|
|
509
406
|
wasChanged
|
|
510
407
|
}
|
|
511
408
|
);
|
|
409
|
+
const cancelEditing = () => machine.sendTo(
|
|
410
|
+
({ system }) => typedSystem(system).syncLayoutActorRef,
|
|
411
|
+
{
|
|
412
|
+
type: "cancel"
|
|
413
|
+
}
|
|
414
|
+
);
|
|
512
415
|
const hasModelFqn = (node) => "modelFqn" in node.data && isTruthy(node.data.modelFqn);
|
|
513
416
|
const openElementDetails = (params) => machine.enqueueActions(({ context, event, enqueue, system }) => {
|
|
514
417
|
let initiatedFrom = null;
|
|
@@ -584,8 +487,8 @@ const openSourceOfFocusedOrLastClickedNode = () => machine.enqueueActions(({ con
|
|
|
584
487
|
enqueue.raise({ type: "open.source", element: diagramNode.modelRef });
|
|
585
488
|
}
|
|
586
489
|
});
|
|
587
|
-
const
|
|
588
|
-
const enableOverlays =
|
|
490
|
+
const ensureOverlaysActor = () => machine.enqueueActions(({ enqueue, check, system }) => {
|
|
491
|
+
const enableOverlays = check("enabled: Overlays");
|
|
589
492
|
const hasRunning = typedSystem(system).overlaysActorRef;
|
|
590
493
|
if (enableOverlays && !hasRunning) {
|
|
591
494
|
enqueue.spawnChild("overlaysActorLogic", { id: "overlays", systemId: "overlays" });
|
|
@@ -598,7 +501,7 @@ const ensureOverlaysActorState = () => machine.enqueueActions(({ enqueue, contex
|
|
|
598
501
|
enqueue.stopChild("overlays");
|
|
599
502
|
}
|
|
600
503
|
});
|
|
601
|
-
const
|
|
504
|
+
const ensureSearchActor = () => machine.enqueueActions(({ enqueue, context: { features: { enableSearch } }, system }) => {
|
|
602
505
|
const hasRunning = typedSystem(system).searchActorRef;
|
|
603
506
|
if (enableSearch && !hasRunning) {
|
|
604
507
|
enqueue.spawnChild("searchActorLogic", { id: "search", systemId: "search" });
|
|
@@ -647,89 +550,95 @@ const onEdgeMouseLeave = () => machine.enqueueActions(({ enqueue, context, event
|
|
|
647
550
|
event: event.event
|
|
648
551
|
});
|
|
649
552
|
});
|
|
650
|
-
const
|
|
651
|
-
const
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
553
|
+
const startHotKeyActor = () => machine.spawnChild("hotkeyActorLogic", { id: "hotkey" });
|
|
554
|
+
const stopHotKeyActor = () => machine.stopChild("hotkey");
|
|
555
|
+
const handleNavigate = () => machine.enqueueActions(({ enqueue, context, event }) => {
|
|
556
|
+
assertEvent(event, ["navigate.to", "navigate.back", "navigate.forward"]);
|
|
557
|
+
console.log(`Handle ${event.type}`);
|
|
558
|
+
const {
|
|
559
|
+
view,
|
|
560
|
+
focusedNode,
|
|
561
|
+
activeWalkthrough,
|
|
562
|
+
dynamicViewVariant,
|
|
563
|
+
viewport,
|
|
564
|
+
viewportChangedManually,
|
|
565
|
+
viewportBefore,
|
|
566
|
+
navigationHistory: {
|
|
567
|
+
currentIndex,
|
|
568
|
+
history: _history
|
|
661
569
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
enqueue(closeSearch());
|
|
673
|
-
enqueue.assign({
|
|
674
|
-
focusedNode: null
|
|
675
|
-
});
|
|
676
|
-
enqueue(disableCompareWithLatest());
|
|
677
|
-
const { fromNode, toNode } = findCorrespondingNode(context, event);
|
|
678
|
-
if (fromNode && toNode) {
|
|
679
|
-
enqueue(xyflow.alignNodeFromToAfterNavigate({
|
|
680
|
-
fromNode: fromNode.id,
|
|
681
|
-
toPosition: {
|
|
682
|
-
x: toNode.data.x,
|
|
683
|
-
y: toNode.data.y
|
|
684
|
-
}
|
|
685
|
-
}));
|
|
686
|
-
enqueue(raiseFitDiagram({ delay: 80 }));
|
|
570
|
+
} = context;
|
|
571
|
+
let history = [..._history];
|
|
572
|
+
if (currentIndex < _history.length) {
|
|
573
|
+
const updatedEntry = produce(_history[currentIndex], (draft) => {
|
|
574
|
+
draft.viewport = { ...viewport };
|
|
575
|
+
draft.viewportChangedManually = viewportChangedManually;
|
|
576
|
+
draft.focusedNode = focusedNode;
|
|
577
|
+
if (view._type === "dynamic") {
|
|
578
|
+
draft.activeWalkthrough = activeWalkthrough?.stepId ?? null;
|
|
579
|
+
draft.dynamicViewVariant = dynamicViewVariant;
|
|
687
580
|
} else {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
);
|
|
691
|
-
enqueue(raiseFitDiagram({ duration: 200, delay: 25 }));
|
|
692
|
-
}
|
|
693
|
-
enqueue(updateXYNodesEdges());
|
|
694
|
-
enqueue(ensureSyncLayout());
|
|
695
|
-
return;
|
|
696
|
-
}
|
|
697
|
-
enqueue(updateXYNodesEdges());
|
|
698
|
-
const syncLayoutActor = typedSystem(system).syncLayoutActorRef;
|
|
699
|
-
if (syncLayoutActor) {
|
|
700
|
-
enqueue.sendTo(syncLayoutActor, { type: "synced" });
|
|
701
|
-
}
|
|
702
|
-
const nextView = event.view;
|
|
703
|
-
if (context.toggledFeatures.enableCompareWithLatest === true && context.view._layout !== nextView._layout) {
|
|
704
|
-
if (nextView._layout === "auto" && context.viewportOnAutoLayout) {
|
|
705
|
-
enqueue(
|
|
706
|
-
xyflow.setViewport({
|
|
707
|
-
viewport: context.viewportOnAutoLayout,
|
|
708
|
-
duration: 0
|
|
709
|
-
})
|
|
710
|
-
);
|
|
711
|
-
return;
|
|
581
|
+
draft.activeWalkthrough = null;
|
|
582
|
+
draft.dynamicViewVariant = null;
|
|
712
583
|
}
|
|
713
|
-
if (
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
duration: 0
|
|
718
|
-
})
|
|
719
|
-
);
|
|
720
|
-
return;
|
|
584
|
+
if (viewportBefore) {
|
|
585
|
+
draft.viewportBefore = viewportBefore;
|
|
586
|
+
} else {
|
|
587
|
+
delete draft.viewportBefore;
|
|
721
588
|
}
|
|
589
|
+
});
|
|
590
|
+
history = [..._history];
|
|
591
|
+
history[currentIndex] = updatedEntry;
|
|
592
|
+
console.log("Update current history entry", {
|
|
593
|
+
before: _history[currentIndex],
|
|
594
|
+
after: updatedEntry
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
switch (event.type) {
|
|
598
|
+
case "navigate.to": {
|
|
599
|
+
enqueue.assign({
|
|
600
|
+
navigationHistory: {
|
|
601
|
+
currentIndex,
|
|
602
|
+
history
|
|
603
|
+
},
|
|
604
|
+
lastOnNavigate: {
|
|
605
|
+
fromView: context.view.id,
|
|
606
|
+
toView: event.viewId,
|
|
607
|
+
fromNode: event.fromNode ?? null
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
enqueue(emitNavigateTo());
|
|
611
|
+
break;
|
|
722
612
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
613
|
+
case "navigate.back": {
|
|
614
|
+
invariant(currentIndex > 0, "Cannot navigate back");
|
|
615
|
+
const stepBack = history[currentIndex - 1];
|
|
616
|
+
enqueue.assign({
|
|
617
|
+
navigationHistory: {
|
|
618
|
+
currentIndex: currentIndex - 1,
|
|
619
|
+
history
|
|
620
|
+
},
|
|
621
|
+
lastOnNavigate: null
|
|
622
|
+
});
|
|
623
|
+
enqueue(emitNavigateTo({ viewId: stepBack.viewId }));
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
case "navigate.forward": {
|
|
627
|
+
invariant(currentIndex < history.length - 1, "Cannot navigate forward");
|
|
628
|
+
const stepForward = history[currentIndex + 1];
|
|
629
|
+
enqueue.assign({
|
|
630
|
+
navigationHistory: {
|
|
631
|
+
currentIndex: currentIndex + 1,
|
|
632
|
+
history
|
|
633
|
+
},
|
|
634
|
+
lastOnNavigate: null
|
|
635
|
+
});
|
|
636
|
+
enqueue(emitNavigateTo({ viewId: stepForward.viewId }));
|
|
637
|
+
break;
|
|
731
638
|
}
|
|
639
|
+
default:
|
|
640
|
+
nonexhaustive(event);
|
|
732
641
|
}
|
|
733
|
-
);
|
|
642
|
+
});
|
|
734
643
|
|
|
735
|
-
export { assignDynamicViewVariant, assignFocusedNode, assignLastClickedNode,
|
|
644
|
+
export { assignDynamicViewVariant, assignFocusedNode, assignLastClickedNode, assignToggledFeatures, cancelEditing, closeAllOverlays, closeSearch, disableCompareWithLatest, emitEdgeClick, emitInitialized, emitNavigateTo, emitNodeClick, emitOnChange, emitOnLayoutTypeChange, emitOpenSource, emitPaneClick, ensureOverlaysActor, ensureSearchActor, ensureSyncLayoutActor, focusOnNodesAndEdges, handleNavigate, layoutAlign, notationsHighlight, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseLeave, onNodeMouseEnter, onNodeMouseLeave, openElementDetails, openSourceOfFocusedOrLastClickedNode, resetEdgesControlPoints, resetLastClickedNode, sendSynced, startEditing, startHotKeyActor, stopEditing, stopHotKeyActor, stopSyncLayout, tagHighlight, undimEverything, updateFeatures, updateInputs, updateXYNodesEdges };
|