chore(type_widgets): port relation map overlays

This commit is contained in:
Elian Doran 2025-09-29 21:35:44 +03:00
parent c58414bbc1
commit 082ea7b5c1
No known key found for this signature in database
3 changed files with 104 additions and 96 deletions

View File

@ -16,25 +16,13 @@ import { CreateChildrenResponse } from "@triliumnext/commons";
import contextMenu from "../../../menus/context_menu"; import contextMenu from "../../../menus/context_menu";
import appContext from "../../../components/app_context"; import appContext from "../../../components/app_context";
import RelationMapApi, { MapData, MapDataNoteEntry } from "./api"; import RelationMapApi, { MapData, MapDataNoteEntry } from "./api";
import setupOverlays, { uniDirectionalOverlays } from "./overlays";
interface Clipboard { interface Clipboard {
noteId: string; noteId: string;
title: 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) { export default function RelationMap({ note, ntxId }: TypeWidgetProps) {
const [ data, setData ] = useState<MapData>(); const [ data, setData ] = useState<MapData>();
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
@ -128,6 +116,7 @@ export default function RelationMap({ note, ntxId }: TypeWidgetProps) {
ConnectionOverlays: uniDirectionalOverlays, ConnectionOverlays: uniDirectionalOverlays,
HoverPaintStyle: { stroke: "#777", strokeWidth: 1 }, HoverPaintStyle: { stroke: "#777", strokeWidth: 1 },
}} }}
onInstanceCreated={setupOverlays}
> >
{data?.notes.map(note => ( {data?.notes.map(note => (
<NoteBox {...note} mapApiRef={mapApiRef} /> <NoteBox {...note} mapApiRef={mapApiRef} />
@ -224,12 +213,13 @@ function useNoteCreation({ ntxId, note, containerRef, mapApiRef }: {
return onClickHandler; return onClickHandler;
} }
function JsPlumb({ className, props, children, containerRef: externalContainerRef, apiRef }: { function JsPlumb({ className, props, children, containerRef: externalContainerRef, apiRef, onInstanceCreated }: {
className?: string; className?: string;
props: Omit<Defaults, "container">; props: Omit<Defaults, "container">;
children: ComponentChildren; children: ComponentChildren;
containerRef?: RefObject<HTMLElement>; containerRef?: RefObject<HTMLElement>;
apiRef?: RefObject<jsPlumbInstance>; apiRef?: RefObject<jsPlumbInstance>;
onInstanceCreated?: (jsPlumbInstance: jsPlumbInstance) => void;
}) { }) {
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
@ -247,6 +237,7 @@ function JsPlumb({ className, props, children, containerRef: externalContainerRe
apiRef.current = jsPlumbInstance; apiRef.current = jsPlumbInstance;
} }
onInstanceCreated?.(jsPlumbInstance);
return () => jsPlumbInstance.cleanupListeners(); return () => jsPlumbInstance.cleanupListeners();
}, [ apiRef ]); }, [ apiRef ]);

View File

@ -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
});
}

View File

@ -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; let containerCounter = 1;
export type RelationType = "uniDirectional" | "biDirectional" | "inverse"; 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() { cleanup() {
if (this.jsPlumbInstance) { if (this.jsPlumbInstance) {
this.clearMap(); this.clearMap();
@ -280,14 +206,6 @@ export default class RelationMapTypeWidget extends TypeWidget {
return; 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)); this.jsPlumbInstance.bind("connection", (info, originalEvent) => this.connectionCreatedHandler(info, originalEvent));
} }