From 082ea7b5c1855f1a83757e628c8bce485f67b9a0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 29 Sep 2025 21:35:44 +0300 Subject: [PATCH] chore(type_widgets): port relation map overlays --- .../type_widgets/relation_map/RelationMap.tsx | 19 +--- .../type_widgets/relation_map/overlays.ts | 99 +++++++++++++++++++ .../widgets/type_widgets_old/relation_map.ts | 82 --------------- 3 files changed, 104 insertions(+), 96 deletions(-) create mode 100644 apps/client/src/widgets/type_widgets/relation_map/overlays.ts diff --git a/apps/client/src/widgets/type_widgets/relation_map/RelationMap.tsx b/apps/client/src/widgets/type_widgets/relation_map/RelationMap.tsx index 705e5bee9..0ef1ba32b 100644 --- a/apps/client/src/widgets/type_widgets/relation_map/RelationMap.tsx +++ b/apps/client/src/widgets/type_widgets/relation_map/RelationMap.tsx @@ -16,25 +16,13 @@ import { CreateChildrenResponse } from "@triliumnext/commons"; import contextMenu from "../../../menus/context_menu"; import appContext from "../../../components/app_context"; import RelationMapApi, { MapData, MapDataNoteEntry } from "./api"; +import setupOverlays, { uniDirectionalOverlays } from "./overlays"; interface Clipboard { noteId: string; title: string; } -const uniDirectionalOverlays: OverlaySpec[] = [ - [ - "Arrow", - { - location: 1, - id: "arrow", - length: 14, - foldback: 0.8 - } - ], - ["Label", { label: "", id: "label", cssClass: "connection-label" }] -]; - export default function RelationMap({ note, ntxId }: TypeWidgetProps) { const [ data, setData ] = useState(); const containerRef = useRef(null); @@ -128,6 +116,7 @@ export default function RelationMap({ note, ntxId }: TypeWidgetProps) { ConnectionOverlays: uniDirectionalOverlays, HoverPaintStyle: { stroke: "#777", strokeWidth: 1 }, }} + onInstanceCreated={setupOverlays} > {data?.notes.map(note => ( @@ -224,12 +213,13 @@ function useNoteCreation({ ntxId, note, containerRef, mapApiRef }: { return onClickHandler; } -function JsPlumb({ className, props, children, containerRef: externalContainerRef, apiRef }: { +function JsPlumb({ className, props, children, containerRef: externalContainerRef, apiRef, onInstanceCreated }: { className?: string; props: Omit; children: ComponentChildren; containerRef?: RefObject; apiRef?: RefObject; + onInstanceCreated?: (jsPlumbInstance: jsPlumbInstance) => void; }) { const containerRef = useRef(null); @@ -247,6 +237,7 @@ function JsPlumb({ className, props, children, containerRef: externalContainerRe apiRef.current = jsPlumbInstance; } + onInstanceCreated?.(jsPlumbInstance); return () => jsPlumbInstance.cleanupListeners(); }, [ apiRef ]); diff --git a/apps/client/src/widgets/type_widgets/relation_map/overlays.ts b/apps/client/src/widgets/type_widgets/relation_map/overlays.ts new file mode 100644 index 000000000..ab4f39d9c --- /dev/null +++ b/apps/client/src/widgets/type_widgets/relation_map/overlays.ts @@ -0,0 +1,99 @@ +import { jsPlumbInstance, OverlaySpec } from "jsplumb"; + +export const uniDirectionalOverlays: OverlaySpec[] = [ + [ + "Arrow", + { + location: 1, + id: "arrow", + length: 14, + foldback: 0.8 + } + ], + ["Label", { label: "", id: "label", cssClass: "connection-label" }] +]; + +const biDirectionalOverlays = [ + [ + "Arrow", + { + location: 1, + id: "arrow", + length: 14, + foldback: 0.8 + } + ], + ["Label", { label: "", id: "label", cssClass: "connection-label" }], + [ + "Arrow", + { + location: 0, + id: "arrow2", + length: 14, + direction: -1, + foldback: 0.8 + } + ] +]; + +const inverseRelationsOverlays = [ + [ + "Arrow", + { + location: 1, + id: "arrow", + length: 14, + foldback: 0.8 + } + ], + ["Label", { label: "", location: 0.2, id: "label-source", cssClass: "connection-label" }], + ["Label", { label: "", location: 0.8, id: "label-target", cssClass: "connection-label" }], + [ + "Arrow", + { + location: 0, + id: "arrow2", + length: 14, + direction: -1, + foldback: 0.8 + } + ] +]; + +const linkOverlays = [ + [ + "Arrow", + { + location: 1, + id: "arrow", + length: 14, + foldback: 0.8 + } + ] +]; + +export default function setupOverlays(jsPlumbInstance: jsPlumbInstance) { + jsPlumbInstance.registerConnectionType("uniDirectional", { + anchor: "Continuous", + connector: "StateMachine", + overlays: uniDirectionalOverlays + }); + + jsPlumbInstance.registerConnectionType("biDirectional", { + anchor: "Continuous", + connector: "StateMachine", + overlays: biDirectionalOverlays + }); + + jsPlumbInstance.registerConnectionType("inverse", { + anchor: "Continuous", + connector: "StateMachine", + overlays: inverseRelationsOverlays + }); + + jsPlumbInstance.registerConnectionType("link", { + anchor: "Continuous", + connector: "StateMachine", + overlays: linkOverlays + }); +} diff --git a/apps/client/src/widgets/type_widgets_old/relation_map.ts b/apps/client/src/widgets/type_widgets_old/relation_map.ts index 2c9e211d8..fab06ed8c 100644 --- a/apps/client/src/widgets/type_widgets_old/relation_map.ts +++ b/apps/client/src/widgets/type_widgets_old/relation_map.ts @@ -29,65 +29,6 @@ declare module "jsplumb" { } } -const biDirectionalOverlays = [ - [ - "Arrow", - { - location: 1, - id: "arrow", - length: 14, - foldback: 0.8 - } - ], - ["Label", { label: "", id: "label", cssClass: "connection-label" }], - [ - "Arrow", - { - location: 0, - id: "arrow2", - length: 14, - direction: -1, - foldback: 0.8 - } - ] -]; - -const inverseRelationsOverlays = [ - [ - "Arrow", - { - location: 1, - id: "arrow", - length: 14, - foldback: 0.8 - } - ], - ["Label", { label: "", location: 0.2, id: "label-source", cssClass: "connection-label" }], - ["Label", { label: "", location: 0.8, id: "label-target", cssClass: "connection-label" }], - [ - "Arrow", - { - location: 0, - id: "arrow2", - length: 14, - direction: -1, - foldback: 0.8 - } - ] -]; - -const linkOverlays = [ - [ - "Arrow", - { - location: 1, - id: "arrow", - length: 14, - foldback: 0.8 - } - ] -]; - let containerCounter = 1; export type RelationType = "uniDirectional" | "biDirectional" | "inverse"; @@ -243,21 +184,6 @@ export default class RelationMapTypeWidget extends TypeWidget { }); } - saveCurrentTransform() { - if (!this.pzInstance) { - return; - } - - const newTransform = this.pzInstance.getTransform(); - - if (this.mapData && JSON.stringify(newTransform) !== JSON.stringify(this.mapData.transform)) { - // clone transform object - this.mapData.transform = JSON.parse(JSON.stringify(newTransform)); - - this.saveData(); - } - } - cleanup() { if (this.jsPlumbInstance) { this.clearMap(); @@ -280,14 +206,6 @@ export default class RelationMapTypeWidget extends TypeWidget { return; } - this.jsPlumbInstance.registerConnectionType("uniDirectional", { anchor: "Continuous", connector: "StateMachine", overlays: uniDirectionalOverlays }); - - this.jsPlumbInstance.registerConnectionType("biDirectional", { anchor: "Continuous", connector: "StateMachine", overlays: biDirectionalOverlays }); - - this.jsPlumbInstance.registerConnectionType("inverse", { anchor: "Continuous", connector: "StateMachine", overlays: inverseRelationsOverlays }); - - this.jsPlumbInstance.registerConnectionType("link", { anchor: "Continuous", connector: "StateMachine", overlays: linkOverlays }); - this.jsPlumbInstance.bind("connection", (info, originalEvent) => this.connectionCreatedHandler(info, originalEvent)); }