@likec4/diagram 1.56.0 → 1.57.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/LikeC4Diagram.js +3 -1
- package/dist/LikeC4View.js +47 -55
- package/dist/adhoc-editor/ElementsTree.js +2 -6
- package/dist/components/RootContainer.js +19 -18
- package/dist/context/DiagramFeatures.d.ts +1 -1
- package/dist/context/DiagramFeatures.js +5 -0
- package/dist/context/RootContainerContext.d.ts +10 -17
- package/dist/context/RootContainerContext.js +1 -13
- package/dist/custom/index.d.ts +1 -1
- package/dist/custom/index.js +1 -2
- package/dist/editor/LikeC4EditorCallbacks.d.ts +5 -0
- package/dist/editor/actor/actions.d.ts +115 -0
- package/dist/editor/actor/actions.js +122 -0
- package/dist/editor/{hotkeyActor.d.ts → actor/hotkey.d.ts} +1 -1
- package/dist/editor/{hotkeyActor.js → actor/hotkey.js} +4 -4
- package/dist/editor/actor/machine.d.ts +11 -0
- package/dist/editor/actor/machine.js +22 -0
- package/dist/editor/{editorActor.setup.d.ts → actor/setup.d.ts} +13 -49
- package/dist/editor/{editorActor.setup.js → actor/setup.js} +13 -10
- package/dist/editor/actor/state.editor.d.ts +97 -0
- package/dist/editor/actor/state.editor.js +55 -0
- package/dist/editor/actor/state.sync-queue.d.ts +420 -0
- package/dist/editor/actor/state.sync-queue.js +235 -0
- package/dist/editor/actor/types.d.ts +59 -0
- package/dist/editor/actor/types.js +5 -0
- package/dist/editor/applyChangesToManualLayout.js +1 -1
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/useEditorActorLogic.d.ts +8 -2
- package/dist/editor/useEditorActorLogic.js +26 -6
- package/dist/hooks/useDiagram.js +6 -1
- package/dist/hooks/useDiagramCompareLayout.js +1 -1
- package/dist/hooks/useEditorActor.d.ts +4 -0
- package/dist/hooks/useEditorActor.js +26 -0
- package/dist/hooks/useLikeC4ElementsTree.d.ts +3 -2
- package/dist/hooks/useLikeC4ElementsTree.js +3 -1
- package/dist/likec4diagram/DiagramUI.js +8 -4
- package/dist/likec4diagram/DiagramXYFlow.js +12 -12
- package/dist/likec4diagram/state/aligners.js +3 -0
- package/dist/likec4diagram/state/assign.js +1 -1
- package/dist/likec4diagram/state/diagram-api.d.ts +16 -0
- package/dist/likec4diagram/state/diagram-api.js +13 -7
- package/dist/likec4diagram/state/machine.actions.js +7 -8
- package/dist/likec4diagram/state/machine.d.ts +1 -1
- package/dist/likec4diagram/state/machine.setup.js +1 -1
- package/dist/likec4diagram/state/types.d.ts +1 -1
- package/dist/likec4diagram/state/utils.d.ts +1 -1
- package/dist/likec4diagram/useLayoutConstraints.js +2 -0
- package/dist/navigationpanel/controls/ToggleReadonly.js +4 -2
- package/dist/navigationpanel/editorpanel/ApplySemanticLayout.d.ts +4 -0
- package/dist/navigationpanel/editorpanel/ApplySemanticLayout.js +36 -0
- package/dist/navigationpanel/editorpanel/EditorPanel.js +45 -33
- package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +61 -61
- package/dist/overlays/overlay/Overlay.d.ts +16 -0
- package/dist/overlays/overlay/Overlay.js +50 -52
- package/dist/overlays/overlaysActor.js +28 -27
- package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +4 -5
- package/dist/overlays/relationship-details/custom/nodeTypes.js +25 -24
- package/dist/overlays/relationships-browser/SelectElement.js +2 -2
- package/dist/search/Search.d.ts +6 -3
- package/dist/search/Search.js +60 -71
- package/dist/search/components/ElementsColumn.js +12 -8
- package/dist/search/searchActor.js +30 -26
- package/dist/shadowroot/ShadowRoot.d.ts +7 -6
- package/dist/shadowroot/ShadowRoot.js +59 -20
- package/dist/shadowroot/styles.css.d.ts +10 -2
- package/dist/shadowroot/styles.css.js +33 -36
- package/dist/styles2.js +1 -1
- package/package.json +17 -23
- package/panda.buildinfo.json +15 -15
- package/src/styles-font.css +114 -0
- package/src/styles-min.css +2 -0
- package/src/styles-xyflow.css +1 -0
- package/src/styles.css +3 -0
- package/styles-min.css +1 -1
- package/styles.css +1 -1
- package/dist/bundle/index.d.ts +0 -1
- package/dist/editor/editorActor.actions.d.ts +0 -153
- package/dist/editor/editorActor.actions.js +0 -133
- package/dist/editor/editorActor.states.d.ts +0 -9
- package/dist/editor/editorActor.states.js +0 -219
- package/dist/hooks/useOverlaysActor.js +0 -11
- package/dist/hooks/useSearchActor.js +0 -11
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Types } from '../../likec4diagram/types';
|
|
2
|
+
import { HotKeyEvent } from './hotkey';
|
|
3
|
+
import type * as t from '@likec4/core/types';
|
|
4
|
+
export type EditorActorEvent = {
|
|
5
|
+
type: 'change.view';
|
|
6
|
+
change: t.ViewChange;
|
|
7
|
+
} | {
|
|
8
|
+
type: 'change.semantic-layout';
|
|
9
|
+
} | {
|
|
10
|
+
type: 'change.latest-to-manual';
|
|
11
|
+
} | {
|
|
12
|
+
type: 'change.sync-snapshot';
|
|
13
|
+
} | {
|
|
14
|
+
type: 'view.synched';
|
|
15
|
+
} | {
|
|
16
|
+
type: 'cancel';
|
|
17
|
+
} | {
|
|
18
|
+
type: 'edit.move.start';
|
|
19
|
+
subject: 'node' | 'edge';
|
|
20
|
+
} | {
|
|
21
|
+
type: 'edit.move.end';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'edit.move.cancel';
|
|
24
|
+
} | HotKeyEvent;
|
|
25
|
+
export type Snapshot = {
|
|
26
|
+
view: t.LayoutedView;
|
|
27
|
+
change: t.ViewChange.SaveViewSnapshot;
|
|
28
|
+
xynodes: Types.Node[];
|
|
29
|
+
xyedges: Types.Edge[];
|
|
30
|
+
};
|
|
31
|
+
export type LinkedSnapshot = {
|
|
32
|
+
head: Snapshot;
|
|
33
|
+
tail: LinkedSnapshot | null;
|
|
34
|
+
};
|
|
35
|
+
export interface EditorActorInput {
|
|
36
|
+
viewId: t.ViewId;
|
|
37
|
+
}
|
|
38
|
+
export type SyncOp = t.ViewChange | 'sync-snapshot' | 'apply-semantic-layout' | 'apply-latest-to-manual';
|
|
39
|
+
export declare const isViewChange: (change: SyncOp) => change is t.ViewChange;
|
|
40
|
+
export interface EditorActorContext {
|
|
41
|
+
viewId: t.ViewId;
|
|
42
|
+
history: LinkedSnapshot | null;
|
|
43
|
+
editing: null | {
|
|
44
|
+
/**
|
|
45
|
+
* The subject of the edit
|
|
46
|
+
*/
|
|
47
|
+
subject: 'node' | 'edge';
|
|
48
|
+
/**
|
|
49
|
+
* The state before editing started
|
|
50
|
+
*/
|
|
51
|
+
before: Snapshot;
|
|
52
|
+
};
|
|
53
|
+
syncQueue: Array<SyncOp>;
|
|
54
|
+
processing: Exclude<SyncOp, 'sync-snapshot'> | null;
|
|
55
|
+
}
|
|
56
|
+
export type EditorActorEmitedEvent = {
|
|
57
|
+
type: 'idle';
|
|
58
|
+
};
|
|
59
|
+
export type EditorActorStateTag = 'pending' | 'busy' | 'ai-semantic-layout';
|
|
@@ -153,7 +153,7 @@ function edgeControlPoints(source, target) {
|
|
|
153
153
|
if (source === target) {
|
|
154
154
|
const loopSize = 80;
|
|
155
155
|
const centerOfTopBoundary = vector(0, source.height || 0).multiply(-.5).add(sourceCenter);
|
|
156
|
-
return [centerOfTopBoundary.add(vector(-
|
|
156
|
+
return [centerOfTopBoundary.add(vector(-80 / 2.5, -80)).trunc().toObject(), centerOfTopBoundary.add(vector(loopSize / 2.5, -80)).trunc().toObject()];
|
|
157
157
|
}
|
|
158
158
|
const sourceToTargetVector = targetCenter.subtract(sourceCenter);
|
|
159
159
|
const sourceBorderPoint = getBorderPointOnVector(source, sourceCenter, sourceToTargetVector);
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export type * from './
|
|
1
|
+
export type * from './actor/machine';
|
|
2
|
+
export type * from './actor/types';
|
|
2
3
|
export { createLikeC4Editor } from './LikeC4EditorCallbacks';
|
|
3
4
|
export type { LikeC4EditorCallbacks } from './LikeC4EditorCallbacks';
|
|
4
5
|
export { EnsureEditorContext, LikeC4EditorProvider, useOptionalLikeC4Editor, } from './LikeC4EditorProvider';
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import { EditorActorLogic } from './
|
|
2
|
-
export declare function useEditorActorLogic(): EditorActorLogic
|
|
1
|
+
import { EditorActorLogic } from './actor/machine';
|
|
2
|
+
export declare function useEditorActorLogic(): EditorActorLogic & {
|
|
3
|
+
/**
|
|
4
|
+
* True if the editor is running in stub mode (no actual editor port available)
|
|
5
|
+
* This happens when the diagram is rendered outside of vscode extension / vite- plugin
|
|
6
|
+
*/
|
|
7
|
+
readonly isStub: boolean;
|
|
8
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { useCallbackRef } from "../hooks/useCallbackRef.js";
|
|
3
3
|
import { useOptionalLikeC4Editor } from "./LikeC4EditorProvider.js";
|
|
4
|
-
import { editorActorLogic } from "./
|
|
4
|
+
import { editorActorLogic } from "./actor/machine.js";
|
|
5
5
|
import { applyChangesToManualLayout } from "./applyChangesToManualLayout.js";
|
|
6
6
|
import { useMemo } from "react";
|
|
7
|
+
import { isNullish } from "remeda";
|
|
7
8
|
import { fromPromise } from "xstate";
|
|
8
9
|
//#region src/editor/useEditorActorLogic.ts
|
|
9
10
|
var promisify = (fn) => {
|
|
@@ -11,25 +12,44 @@ var promisify = (fn) => {
|
|
|
11
12
|
};
|
|
12
13
|
function useEditorActorLogic() {
|
|
13
14
|
const port = useOptionalLikeC4Editor();
|
|
15
|
+
const isStub = isNullish(port);
|
|
14
16
|
const applyLatest = useCallbackRef(async ({ input: { viewId, current } }) => {
|
|
15
17
|
if (!port) {
|
|
16
18
|
console.error("No editor port available for applying latest to manual layout");
|
|
17
|
-
|
|
19
|
+
throw new Error("No editor port");
|
|
18
20
|
}
|
|
19
21
|
return { updated: applyChangesToManualLayout(await promisify(() => current ?? port.fetchView(viewId, "manual")), await promisify(() => port.fetchView(viewId, "auto"))) };
|
|
20
22
|
});
|
|
21
23
|
const executeChange = useCallbackRef(async ({ input }) => {
|
|
22
24
|
if (!port) {
|
|
23
25
|
console.error("No editor port available for executing change");
|
|
24
|
-
|
|
26
|
+
throw new Error("No editor port");
|
|
25
27
|
}
|
|
26
28
|
for (const change of input.changes) await promisify(() => port.handleChange(input.viewId, change));
|
|
27
29
|
return {};
|
|
28
30
|
});
|
|
29
|
-
|
|
31
|
+
const applySemanticLayout = useCallbackRef(async ({ input }) => {
|
|
32
|
+
if (!port) {
|
|
33
|
+
console.error("No editor port available for applying semantic layout");
|
|
34
|
+
throw new Error("No editor port");
|
|
35
|
+
}
|
|
36
|
+
if (!port.applySemanticLayout) {
|
|
37
|
+
console.error("No applySemanticLayout method available on editor port");
|
|
38
|
+
throw new Error("No applySemanticLayout method");
|
|
39
|
+
}
|
|
40
|
+
await port.applySemanticLayout(input.viewId);
|
|
41
|
+
return {};
|
|
42
|
+
});
|
|
43
|
+
return useMemo(() => Object.assign(editorActorLogic.provide({ actors: {
|
|
30
44
|
applyLatest: fromPromise(applyLatest),
|
|
31
|
-
executeChange: fromPromise(executeChange)
|
|
32
|
-
|
|
45
|
+
executeChange: fromPromise(executeChange),
|
|
46
|
+
applySemanticLayout: fromPromise(applySemanticLayout)
|
|
47
|
+
} }), { isStub }), [
|
|
48
|
+
applyLatest,
|
|
49
|
+
executeChange,
|
|
50
|
+
applySemanticLayout,
|
|
51
|
+
isStub
|
|
52
|
+
]);
|
|
33
53
|
}
|
|
34
54
|
//#endregion
|
|
35
55
|
export { useEditorActorLogic };
|
package/dist/hooks/useDiagram.js
CHANGED
|
@@ -45,7 +45,11 @@ function useOnDiagramEvent(event, callback, options) {
|
|
|
45
45
|
useEffect(() => {
|
|
46
46
|
if (once && wasCalled.current) return;
|
|
47
47
|
let subscription = actorRef.on(event, (payload) => {
|
|
48
|
-
|
|
48
|
+
if (!once || !wasCalled.current) try {
|
|
49
|
+
callbackRef(payload);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(error);
|
|
52
|
+
}
|
|
49
53
|
wasCalled.current = true;
|
|
50
54
|
if (once) {
|
|
51
55
|
subscription?.unsubscribe();
|
|
@@ -56,6 +60,7 @@ function useOnDiagramEvent(event, callback, options) {
|
|
|
56
60
|
subscription?.unsubscribe();
|
|
57
61
|
};
|
|
58
62
|
}, [
|
|
63
|
+
callbackRef,
|
|
59
64
|
actorRef,
|
|
60
65
|
event,
|
|
61
66
|
once
|
|
@@ -68,7 +68,7 @@ function useDiagramCompareLayout() {
|
|
|
68
68
|
console.warn("Compare with latest feature is not enabled");
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
|
-
nonNullable(actorRef.system?.get("editor"), "editor actor not found").send({ type: "
|
|
71
|
+
nonNullable(actorRef.system?.get("editor"), "editor actor not found").send({ type: "change.latest-to-manual" });
|
|
72
72
|
if (state.isActive) actorRef.send({
|
|
73
73
|
type: "toggle.feature",
|
|
74
74
|
feature: "CompareWithLatest",
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { EditorActorRef } from '../editor/actor/machine';
|
|
2
|
+
import { EditorActorStateTag } from '../editor/actor/types';
|
|
3
|
+
export declare function useEditorActorRef(): EditorActorRef | null;
|
|
4
|
+
export declare function useEditorActorStateHasTag(tag: EditorActorStateTag): boolean;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { selectDiagramActor, useDiagramSnapshot } from "./useDiagram.js";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
//#region src/hooks/useEditorActor.ts
|
|
5
|
+
var select = selectDiagramActor((s) => {
|
|
6
|
+
return s.children.editor ?? null;
|
|
7
|
+
});
|
|
8
|
+
function useEditorActorRef() {
|
|
9
|
+
return useDiagramSnapshot(select, Object.is);
|
|
10
|
+
}
|
|
11
|
+
function useEditorActorStateHasTag(tag) {
|
|
12
|
+
const editorActor = useEditorActorRef();
|
|
13
|
+
const [hasTag, setHasTag] = useState(() => editorActor?.getSnapshot().hasTag(tag) ?? false);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const subscription = editorActor?.subscribe((snapshot) => {
|
|
16
|
+
setHasTag(snapshot.hasTag(tag));
|
|
17
|
+
});
|
|
18
|
+
return () => {
|
|
19
|
+
subscription?.unsubscribe();
|
|
20
|
+
setHasTag(false);
|
|
21
|
+
};
|
|
22
|
+
}, [editorActor, tag]);
|
|
23
|
+
return hasTag;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { useEditorActorStateHasTag };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Fqn, ViewId } from '@likec4/core/types';
|
|
2
|
-
|
|
2
|
+
import { TreeNodeData } from '@mantine/core';
|
|
3
|
+
export interface LikeC4ModelTreeNodeData extends TreeNodeData {
|
|
3
4
|
label: string;
|
|
4
5
|
value: Fqn;
|
|
5
6
|
children: LikeC4ModelTreeNodeData[];
|
|
7
|
+
hasChildren: boolean;
|
|
6
8
|
}
|
|
7
9
|
export declare const sortByLabel: (a: LikeC4ModelTreeNodeData, b: LikeC4ModelTreeNodeData) => number;
|
|
8
10
|
/**
|
|
@@ -10,4 +12,3 @@ export declare const sortByLabel: (a: LikeC4ModelTreeNodeData, b: LikeC4ModelTre
|
|
|
10
12
|
* If `viewId` is provided, returns the tree of elements in the view.
|
|
11
13
|
*/
|
|
12
14
|
export declare function useLikeC4ElementsTree(viewId?: ViewId): LikeC4ModelTreeNodeData[];
|
|
13
|
-
export {};
|
|
@@ -5,10 +5,12 @@ import { compareNatural } from "@likec4/core/utils";
|
|
|
5
5
|
//#region src/hooks/useLikeC4ElementsTree.ts
|
|
6
6
|
var sortByLabel = (a, b) => compareNatural(a.label, b.label);
|
|
7
7
|
function buildNode(element) {
|
|
8
|
+
const children = [...element.children()].map(buildNode).sort(sortByLabel);
|
|
8
9
|
return {
|
|
9
10
|
label: element.title || element.id,
|
|
10
11
|
value: element.id,
|
|
11
|
-
children
|
|
12
|
+
children,
|
|
13
|
+
hasChildren: children.length > 0
|
|
12
14
|
};
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { useEnabledFeatures } from "../context/DiagramFeatures.js";
|
|
3
|
+
import { selectDiagramActor, useDiagramSnapshot } from "../hooks/useDiagram.js";
|
|
3
4
|
import { ErrorBoundary } from "../components/ErrorFallback.js";
|
|
4
|
-
import { useOverlaysActorRef } from "../hooks/useOverlaysActor.js";
|
|
5
5
|
import { NavigationPanel } from "../navigationpanel/NavigationPanel.js";
|
|
6
6
|
import { Overlays } from "../overlays/Overlays.js";
|
|
7
7
|
import { Search } from "../search/Search.js";
|
|
@@ -12,10 +12,14 @@ import { memo, useCallback } from "react";
|
|
|
12
12
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
13
|
import { useRerender } from "@react-hookz/web";
|
|
14
14
|
//#region src/likec4diagram/DiagramUI.tsx
|
|
15
|
+
var selectChildren = selectDiagramActor((s) => ({
|
|
16
|
+
overlays: s.children.overlays ?? null,
|
|
17
|
+
search: s.children.search ?? null
|
|
18
|
+
}));
|
|
15
19
|
var LikeC4DiagramUI = memo(() => {
|
|
16
20
|
const { enableControls, enableNotations, enableSearch, enableRelationshipDetails, enableReadOnly, enableCompareWithLatest } = useEnabledFeatures();
|
|
17
21
|
const rerender = useRerender();
|
|
18
|
-
const
|
|
22
|
+
const actors = useDiagramSnapshot(selectChildren);
|
|
19
23
|
return /* @__PURE__ */ jsxs(ErrorBoundary, {
|
|
20
24
|
onReset: useCallback(() => {
|
|
21
25
|
console.warn("DiagramUI: resetting error boundary and rerendering...");
|
|
@@ -23,9 +27,9 @@ var LikeC4DiagramUI = memo(() => {
|
|
|
23
27
|
}, []),
|
|
24
28
|
children: [
|
|
25
29
|
enableControls && /* @__PURE__ */ jsx(NavigationPanel, {}),
|
|
26
|
-
|
|
30
|
+
actors.overlays && /* @__PURE__ */ jsx(Overlays, { overlaysActorRef: actors.overlays }),
|
|
27
31
|
enableNotations && /* @__PURE__ */ jsx(NotationPanel, {}),
|
|
28
|
-
enableSearch && /* @__PURE__ */ jsx(Search, {}),
|
|
32
|
+
enableSearch && actors.search && /* @__PURE__ */ jsx(Search, { searchActorRef: actors.search }),
|
|
29
33
|
enableRelationshipDetails && enableReadOnly && /* @__PURE__ */ jsx(RelationshipPopover, {}),
|
|
30
34
|
enableCompareWithLatest && /* @__PURE__ */ jsx(LayoutDriftFrame, {})
|
|
31
35
|
]
|
|
@@ -2,13 +2,12 @@ import "../_virtual/_rolldown/runtime.js";
|
|
|
2
2
|
import { useCallbackRef as useCallbackRef$1 } from "../hooks/useCallbackRef.js";
|
|
3
3
|
import { depsShallowEqual, useUpdateEffect as useUpdateEffect$1 } from "../hooks/useUpdateEffect.js";
|
|
4
4
|
import { BaseXYFlow } from "../base/BaseXYFlow.js";
|
|
5
|
-
import {
|
|
5
|
+
import { useRootContainer } from "../context/RootContainerContext.js";
|
|
6
6
|
import { useDiagramEventHandlers } from "../context/DiagramEventHandlers.js";
|
|
7
7
|
import { useDiagram } from "../hooks/safeContext.js";
|
|
8
8
|
import { selectDiagramActor, useDiagramSnapshot } from "../hooks/useDiagram.js";
|
|
9
9
|
import { viewBounds } from "./state/utils.js";
|
|
10
10
|
import { deriveToggledFeatures } from "./state/machine.setup.js";
|
|
11
|
-
import { memoNode } from "../base-primitives/memoNode.js";
|
|
12
11
|
import { BuiltinEdges, BuiltinNodes } from "./custom/index.js";
|
|
13
12
|
import { useLayoutConstraints } from "./useLayoutConstraints.js";
|
|
14
13
|
import { cx } from "@likec4/styles/css";
|
|
@@ -23,13 +22,13 @@ var edgeTypes = {
|
|
|
23
22
|
"seq-step": BuiltinEdges.SequenceStepEdge
|
|
24
23
|
};
|
|
25
24
|
var builtinNodes = {
|
|
26
|
-
element:
|
|
27
|
-
deployment:
|
|
28
|
-
"compound-element":
|
|
29
|
-
"compound-deployment":
|
|
30
|
-
"view-group":
|
|
31
|
-
"seq-actor":
|
|
32
|
-
"seq-parallel":
|
|
25
|
+
element: BuiltinNodes.ElementNode,
|
|
26
|
+
deployment: BuiltinNodes.DeploymentNode,
|
|
27
|
+
"compound-element": BuiltinNodes.CompoundElementNode,
|
|
28
|
+
"compound-deployment": BuiltinNodes.CompoundDeploymentNode,
|
|
29
|
+
"view-group": BuiltinNodes.ViewGroupNode,
|
|
30
|
+
"seq-actor": BuiltinNodes.SequenceActorNode,
|
|
31
|
+
"seq-parallel": BuiltinNodes.SequenceParallelArea
|
|
33
32
|
};
|
|
34
33
|
function prepareNodeTypes(nodeTypes) {
|
|
35
34
|
if (!nodeTypes || isEmpty(nodeTypes)) return builtinNodes;
|
|
@@ -53,7 +52,7 @@ var viewportToTopLeft = (ctx) => {
|
|
|
53
52
|
};
|
|
54
53
|
var selectXYProps = selectDiagramActor(({ context: ctx, children }) => {
|
|
55
54
|
const { enableReadOnly } = deriveToggledFeatures(ctx);
|
|
56
|
-
const isNotEditingEdge = enableReadOnly || children.editor?.getSnapshot().context.editing !== "edge";
|
|
55
|
+
const isNotEditingEdge = enableReadOnly || children.editor?.getSnapshot().context.editing?.subject !== "edge";
|
|
57
56
|
let nodesDraggable = !enableReadOnly && ctx.nodesDraggable;
|
|
58
57
|
if (ctx.dynamicViewVariant === "sequence" && ctx.view._type === "dynamic") nodesDraggable = false;
|
|
59
58
|
return {
|
|
@@ -74,9 +73,10 @@ function LikeC4DiagramXYFlow({ background = "dots", reactFlowProps = {}, childre
|
|
|
74
73
|
const diagram = useDiagram();
|
|
75
74
|
let { enableReadOnly, initialized, nodes, edges, enableFitView, nodesDraggable, nodesSelectable, ...props } = useDiagramSnapshot(selectXYProps);
|
|
76
75
|
const { onNodeContextMenu, onCanvasContextMenu, onEdgeContextMenu, onNodeClick, onEdgeClick, onCanvasClick, onCanvasDblClick } = useDiagramEventHandlers();
|
|
77
|
-
const
|
|
76
|
+
const { reducedGraphics, $panning } = useRootContainer();
|
|
77
|
+
const isReducedGraphics = reducedGraphics;
|
|
78
78
|
const layoutConstraints = useLayoutConstraints();
|
|
79
|
-
const $isPanning =
|
|
79
|
+
const $isPanning = $panning;
|
|
80
80
|
const isPanning = useTimeout(() => {
|
|
81
81
|
$isPanning.set(true);
|
|
82
82
|
}, isReducedGraphics ? 200 : 800);
|
|
@@ -5,6 +5,9 @@ import { getNodeDimensions } from "@xyflow/system";
|
|
|
5
5
|
//#region src/likec4diagram/state/aligners.ts
|
|
6
6
|
var Aligner = class {};
|
|
7
7
|
var LinearAligner = class extends Aligner {
|
|
8
|
+
getEdgePosition;
|
|
9
|
+
computePosition;
|
|
10
|
+
propertyToEdit;
|
|
8
11
|
alignTo;
|
|
9
12
|
constructor(getEdgePosition, computePosition, propertyToEdit) {
|
|
10
13
|
super();
|
|
@@ -86,7 +86,7 @@ function resetEdgeControlPoints(nodeLookup, edge) {
|
|
|
86
86
|
if (source === target) {
|
|
87
87
|
const loopSize = 80;
|
|
88
88
|
const centerOfTopBoundary = vector(0, source.height || 0).multiply(-.5).add(sourceCenter);
|
|
89
|
-
return [centerOfTopBoundary.add(vector(-
|
|
89
|
+
return [centerOfTopBoundary.add(vector(-80 / 2.5, -80)).round().toObject(), centerOfTopBoundary.add(vector(loopSize / 2.5, -80)).round().toObject()];
|
|
90
90
|
}
|
|
91
91
|
const sourceToTargetVector = targetCenter.subtract(sourceCenter);
|
|
92
92
|
const sourceBorderPoint = getBorderPointOnVector(source, sourceCenter, sourceToTargetVector);
|
|
@@ -2,8 +2,10 @@ import { DynamicViewDisplayVariant, NodeNotation as ElementNotation, ViewChange
|
|
|
2
2
|
import { RefObject } from 'react';
|
|
3
3
|
import { PartialDeep } from 'type-fest';
|
|
4
4
|
import { FeatureName } from '../../context/DiagramFeatures';
|
|
5
|
+
import { EditorActorRef } from '../../editor/actor/machine';
|
|
5
6
|
import { OpenSourceParams } from '../../LikeC4Diagram.props';
|
|
6
7
|
import { OverlaysActorRef } from '../../overlays/overlaysActor';
|
|
8
|
+
import { SearchActorRef } from '../../search/searchActor';
|
|
7
9
|
import { Types } from '../types';
|
|
8
10
|
import { AlignmentMode } from './aligners';
|
|
9
11
|
import { DiagramActorRef, DiagramContext, DiagramEvents } from './types';
|
|
@@ -27,7 +29,21 @@ export interface DiagramApi<A extends Any = Unknown> {
|
|
|
27
29
|
* @warning Do not use in render phase
|
|
28
30
|
*/
|
|
29
31
|
readonly currentView: t.DiagramView<A>;
|
|
32
|
+
/**
|
|
33
|
+
* Editor actor reference
|
|
34
|
+
* @warning Do not use in render phase
|
|
35
|
+
*/
|
|
36
|
+
editorActor(): EditorActorRef;
|
|
37
|
+
/**
|
|
38
|
+
* Overlays actor reference
|
|
39
|
+
* @warning Do not use in render phase
|
|
40
|
+
*/
|
|
30
41
|
overlays(): OverlaysActorRef;
|
|
42
|
+
/**
|
|
43
|
+
* Search actor reference
|
|
44
|
+
* @warning Do not use in render phase
|
|
45
|
+
*/
|
|
46
|
+
searchActor(): SearchActorRef;
|
|
31
47
|
/**
|
|
32
48
|
* Send event to diagram actor
|
|
33
49
|
*/
|
|
@@ -8,8 +8,17 @@ function makeDiagramApi(actorRef) {
|
|
|
8
8
|
get actor() {
|
|
9
9
|
return actorRef.current;
|
|
10
10
|
},
|
|
11
|
+
editorActor() {
|
|
12
|
+
const editorActor = typedSystem(actorRef.current.system).editorActorRef;
|
|
13
|
+
return nonNullable(editorActor, "Editor actor not found in actor system");
|
|
14
|
+
},
|
|
11
15
|
overlays() {
|
|
12
|
-
|
|
16
|
+
const overlaysActor = typedSystem(actorRef.current.system).overlaysActorRef;
|
|
17
|
+
return nonNullable(overlaysActor, "Overlays actor not found in actor system");
|
|
18
|
+
},
|
|
19
|
+
searchActor() {
|
|
20
|
+
const searchActor = typedSystem(actorRef.current.system).searchActorRef;
|
|
21
|
+
return nonNullable(searchActor, "Search actor not found in actor system");
|
|
13
22
|
},
|
|
14
23
|
send: (event) => actorRef.current.send(event),
|
|
15
24
|
navigateTo: (viewId, fromNode, focusOnElement) => {
|
|
@@ -79,22 +88,19 @@ function makeDiagramApi(actorRef) {
|
|
|
79
88
|
const editorActor = typedSystem(actorRef.current.system).editorActorRef;
|
|
80
89
|
invariant(editorActor, "No editor actor found in diagram actor system");
|
|
81
90
|
editorActor.send({
|
|
82
|
-
type: "edit.start",
|
|
91
|
+
type: "edit.move.start",
|
|
83
92
|
subject
|
|
84
93
|
});
|
|
85
94
|
},
|
|
86
95
|
stopEditing: (wasChanged = false) => {
|
|
87
96
|
const editorActor = typedSystem(actorRef.current.system).editorActorRef;
|
|
88
97
|
invariant(editorActor, "No editor actor found in diagram actor system");
|
|
89
|
-
editorActor.send({
|
|
90
|
-
type: "edit.finish",
|
|
91
|
-
wasChanged
|
|
92
|
-
});
|
|
98
|
+
editorActor.send({ type: wasChanged ? "edit.move.end" : "edit.move.cancel" });
|
|
93
99
|
},
|
|
94
100
|
undoEditing: () => {
|
|
95
101
|
const editorActor = typedSystem(actorRef.current.system).editorActorRef;
|
|
96
102
|
invariant(editorActor, "No editor actor found in diagram actor system");
|
|
97
|
-
const hasUndo = editorActor.getSnapshot().context.history
|
|
103
|
+
const hasUndo = editorActor.getSnapshot().context.history !== null;
|
|
98
104
|
if (hasUndo) editorActor.send({ type: "undo" });
|
|
99
105
|
return hasUndo;
|
|
100
106
|
},
|
|
@@ -214,7 +214,7 @@ var triggerChange = (viewChange) => machine.enqueueActions(({ event, enqueue })
|
|
|
214
214
|
}
|
|
215
215
|
enqueue.assign({ viewportChangedManually: true });
|
|
216
216
|
enqueue.sendTo(typedSystem.editorActor, {
|
|
217
|
-
type: "change",
|
|
217
|
+
type: "change.view",
|
|
218
218
|
change
|
|
219
219
|
});
|
|
220
220
|
});
|
|
@@ -388,14 +388,13 @@ var ensureEditorActor = () => machine.enqueueActions(({ enqueue, context, system
|
|
|
388
388
|
});
|
|
389
389
|
});
|
|
390
390
|
var startEditing = (subject = "node") => machine.sendTo(typedSystem.editorActor, {
|
|
391
|
-
type: "edit.start",
|
|
391
|
+
type: "edit.move.start",
|
|
392
392
|
subject
|
|
393
393
|
});
|
|
394
|
-
var sendSynced = () =>
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
});
|
|
394
|
+
var sendSynced = () => {
|
|
395
|
+
return machine.sendTo(typedSystem.editorActor, { type: "view.synched" });
|
|
396
|
+
};
|
|
397
|
+
var stopEditing = (wasChanged = false) => machine.sendTo(typedSystem.editorActor, { type: wasChanged ? "edit.move.end" : "edit.move.cancel" });
|
|
399
398
|
var cancelEditing = () => machine.sendTo(typedSystem.editorActor, { type: "cancel" });
|
|
400
399
|
var hasModelFqn = (node) => "modelFqn" in node.data && isTruthy(node.data.modelFqn);
|
|
401
400
|
var openElementDetails = (params) => machine.enqueueActions(({ context, event, enqueue }) => {
|
|
@@ -591,7 +590,7 @@ var stopHotKeyActor = () => machine.stopChild("hotkey");
|
|
|
591
590
|
*/
|
|
592
591
|
var AUTO_UNFOCUS_DELAY = 3e3;
|
|
593
592
|
var startAutoUnfocusTimer = () => machine.enqueueActions(({ context, enqueue }) => {
|
|
594
|
-
if (context.autoUnfocusTimer &&
|
|
593
|
+
if (context.autoUnfocusTimer && true) enqueue.raise({ type: "focus.autoUnfocus" }, {
|
|
595
594
|
delay: AUTO_UNFOCUS_DELAY,
|
|
596
595
|
id: "autoUnfocusTimer"
|
|
597
596
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActorRef, MachineSnapshot, StateMachine } from 'xstate';
|
|
2
|
-
import { EditorActorRef } from '../../editor/
|
|
2
|
+
import { EditorActorRef } from '../../editor/actor/machine';
|
|
3
3
|
import { OverlaysActorRef } from '../../overlays/overlaysActor';
|
|
4
4
|
import { SearchActorRef } from '../../search/searchActor';
|
|
5
5
|
import { Context as DiagramContext, EmittedEvents as DiagramEmittedEvents, Events as DiagramEvents, Input } from './machine.setup';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { editorActorLogic } from "../../editor/
|
|
2
|
+
import { editorActorLogic } from "../../editor/actor/machine.js";
|
|
3
3
|
import { overlaysActorLogic } from "../../overlays/overlaysActor.js";
|
|
4
4
|
import { searchActorLogic } from "../../search/searchActor.js";
|
|
5
5
|
import { hotkeyActorLogic } from "./hotkeyActor.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActorSystem } from 'xstate';
|
|
2
|
-
import { EditorActorRef } from '../../editor/
|
|
2
|
+
import { EditorActorRef } from '../../editor/actor/machine';
|
|
3
3
|
import { OverlaysActorRef } from '../../overlays/overlaysActor';
|
|
4
4
|
import { SearchActorRef } from '../../search/searchActor';
|
|
5
5
|
import { DiagramMachineRef } from './machine';
|
|
@@ -2,7 +2,7 @@ import { BBox } from '@likec4/core/geometry';
|
|
|
2
2
|
import { DeploymentFqn, DiagramEdge, DiagramNode, DiagramView, Fqn } from '@likec4/core/types';
|
|
3
3
|
import { Viewport } from '@xyflow/system';
|
|
4
4
|
import { ActorSystem } from 'xstate';
|
|
5
|
-
import { EditorActorRef } from '../../editor/
|
|
5
|
+
import { EditorActorRef } from '../../editor/actor/machine';
|
|
6
6
|
import { OverlaysActorRef } from '../../overlays/overlaysActor';
|
|
7
7
|
import { SearchActorRef } from '../../search/searchActor';
|
|
8
8
|
import { Types } from '../types';
|
|
@@ -85,6 +85,7 @@ var Rect = class {
|
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
87
|
var CompoundRect = class extends Rect {
|
|
88
|
+
parent;
|
|
88
89
|
children = [];
|
|
89
90
|
constructor(xynode, parent = null) {
|
|
90
91
|
super(xynode, parent);
|
|
@@ -92,6 +93,7 @@ var CompoundRect = class extends Rect {
|
|
|
92
93
|
}
|
|
93
94
|
};
|
|
94
95
|
var Leaf = class extends Rect {
|
|
96
|
+
parent;
|
|
95
97
|
constructor(xynode, parent = null) {
|
|
96
98
|
super(xynode, parent);
|
|
97
99
|
this.parent = parent;
|
|
@@ -14,10 +14,12 @@ import * as m$1 from "motion/react-m";
|
|
|
14
14
|
var selector = (ctx) => {
|
|
15
15
|
const comparingLatest = deriveToggledFeatures(ctx).enableCompareWithLatest && !!ctx.view.drifts && ctx.view._layout === "auto";
|
|
16
16
|
const noActiveWalkthrough = !isTruthy(ctx.activeWalkthrough);
|
|
17
|
+
const hasEditor = ctx.features.enableEditor;
|
|
18
|
+
const isReadOnly = ctx.toggledFeatures.enableReadOnly ?? false;
|
|
17
19
|
return {
|
|
18
|
-
visible:
|
|
20
|
+
visible: hasEditor && noActiveWalkthrough,
|
|
19
21
|
disabled: comparingLatest,
|
|
20
|
-
isReadOnly
|
|
22
|
+
isReadOnly
|
|
21
23
|
};
|
|
22
24
|
};
|
|
23
25
|
var ToggleReadonly = () => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { useDiagram } from "../../hooks/safeContext.js";
|
|
3
|
+
import { PanelActionIcon } from "../_common.js";
|
|
4
|
+
import { useEditorActorStateHasTag } from "../../hooks/useEditorActor.js";
|
|
5
|
+
import { Tooltip } from "./_common.js";
|
|
6
|
+
import { IconSparkles } from "@tabler/icons-react";
|
|
7
|
+
import { memo } from "react";
|
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
//#region src/navigationpanel/editorpanel/ApplySemanticLayout.tsx
|
|
10
|
+
var ApplySemanticLayout = memo(({ visible = true }) => {
|
|
11
|
+
const diagram = useDiagram();
|
|
12
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
13
|
+
label: "Semantic Layout with AI",
|
|
14
|
+
children: /* @__PURE__ */ jsx(PanelActionIcon, {
|
|
15
|
+
loading: useEditorActorStateHasTag("ai-semantic-layout"),
|
|
16
|
+
initial: { display: visible ? "block" : "none" },
|
|
17
|
+
animate: {
|
|
18
|
+
display: visible ? "block" : "none",
|
|
19
|
+
opacity: visible ? 1 : .2,
|
|
20
|
+
x: visible ? 0 : -5,
|
|
21
|
+
y: visible ? 0 : -8
|
|
22
|
+
},
|
|
23
|
+
onClick: (e) => {
|
|
24
|
+
e.stopPropagation();
|
|
25
|
+
diagram.editorActor().send({ type: "change.semantic-layout" });
|
|
26
|
+
},
|
|
27
|
+
children: /* @__PURE__ */ jsx(IconSparkles, {
|
|
28
|
+
size: 14,
|
|
29
|
+
stroke: 2
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
ApplySemanticLayout.displayName = "ApplySemanticLayout";
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ApplySemanticLayout };
|