mirror of
https://github.com/zadam/trilium.git
synced 2025-11-11 08:58:58 +01:00
chore(react/type_widgets): finalize porting relation map
This commit is contained in:
parent
67d9154795
commit
9cceff4f02
@ -11,7 +11,7 @@ import dialog from "../../../services/dialog";
|
||||
import server from "../../../services/server";
|
||||
import toast from "../../../services/toast";
|
||||
import { CreateChildrenResponse, RelationMapPostResponse, RelationMapRelation } from "@triliumnext/commons";
|
||||
import RelationMapApi, { ClientRelation, MapData, MapDataNoteEntry } from "./api";
|
||||
import RelationMapApi, { ClientRelation, MapData, MapDataNoteEntry, RelationType } from "./api";
|
||||
import setupOverlays, { uniDirectionalOverlays } from "./overlays";
|
||||
import { JsPlumb } from "./jsplumb";
|
||||
import { getMousePosition, getZoom, idToNoteId, noteIdToId } from "./utils";
|
||||
@ -26,6 +26,23 @@ interface Clipboard {
|
||||
title: string;
|
||||
}
|
||||
|
||||
declare module "jsplumb" {
|
||||
|
||||
interface Connection {
|
||||
canvas: HTMLCanvasElement;
|
||||
getType(): string;
|
||||
bind(event: string, callback: (obj: unknown, event: MouseEvent) => void): void;
|
||||
}
|
||||
|
||||
interface Overlay {
|
||||
setLabel(label: string): void;
|
||||
}
|
||||
|
||||
interface ConnectParams {
|
||||
type: RelationType;
|
||||
}
|
||||
}
|
||||
|
||||
export default function RelationMap({ note, ntxId }: TypeWidgetProps) {
|
||||
const [ data, setData ] = useState<MapData>();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
import server from "../../services/server.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import contextMenu from "../../menus/context_menu.js";
|
||||
import toastService from "../../services/toast.js";
|
||||
import attributeAutocompleteService from "../../services/attribute_autocomplete.js";
|
||||
import TypeWidget from "./type_widget.js";
|
||||
import appContext, { type EventData } from "../../components/app_context.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import froca from "../../services/froca.js";
|
||||
import dialogService from "../../services/dialog.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import type { ConnectionMadeEventInfo, jsPlumbInstance, OverlaySpec } from "jsplumb";
|
||||
|
||||
declare module "jsplumb" {
|
||||
|
||||
interface Connection {
|
||||
canvas: HTMLCanvasElement;
|
||||
getType(): string;
|
||||
bind(event: string, callback: (obj: unknown, event: MouseEvent) => void): void;
|
||||
}
|
||||
|
||||
interface Overlay {
|
||||
setLabel(label: string): void;
|
||||
}
|
||||
|
||||
interface ConnectParams {
|
||||
type: RelationType;
|
||||
}
|
||||
}
|
||||
|
||||
let containerCounter = 1;
|
||||
|
||||
type MenuCommands = "openInNewTab" | "remove" | "editTitle";
|
||||
|
||||
export default class RelationMapTypeWidget extends TypeWidget {
|
||||
|
||||
private clipboard?: Clipboard | null;
|
||||
private jsPlumbInstance?: import("jsplumb").jsPlumbInstance | null;
|
||||
private pzInstance?: PanZoom | null;
|
||||
private mapData?: MapData | null;
|
||||
private relations?: Relation[] | null;
|
||||
|
||||
private $relationMapContainer!: JQuery<HTMLElement>;
|
||||
private $relationMapWrapper!: JQuery<HTMLElement>;
|
||||
|
||||
static getType() {
|
||||
return "relationMap";
|
||||
}
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$relationMapContainer = this.$widget.find(".relation-map-container");
|
||||
|
||||
this.mapData = null;
|
||||
this.jsPlumbInstance = null;
|
||||
// outside of mapData because they are not persisted in the note content
|
||||
this.relations = null;
|
||||
this.pzInstance = null;
|
||||
|
||||
this.$relationMapWrapper = this.$widget.find(".relation-map-wrapper");
|
||||
this.$relationMapWrapper.on("click", (event) => {
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
this.$relationMapContainer.attr("id", "relation-map-container-" + containerCounter++);
|
||||
|
||||
this.clipboard = null;
|
||||
|
||||
this.$widget.on("drop", (ev) => this.dropNoteOntoRelationMapHandler(ev));
|
||||
|
||||
this.initialized = new Promise(async (res) => {
|
||||
// Weird typecast is needed probably due to bad typings in the module itself.
|
||||
const jsPlumb = (await import("jsplumb")).default.jsPlumb as unknown as jsPlumbInstance;
|
||||
jsPlumb.ready(res);
|
||||
});
|
||||
|
||||
super.doRender();
|
||||
}
|
||||
|
||||
async doRefresh(note: FNote) {
|
||||
await this.initJsPlumbInstance();
|
||||
this.loadNotesAndRelations();
|
||||
}
|
||||
|
||||
clearMap() {
|
||||
// delete all endpoints and connections
|
||||
// this is done at this point (after async operations) to reduce flicker to the minimum
|
||||
this.jsPlumbInstance?.deleteEveryEndpoint();
|
||||
|
||||
// without this, we still end up with note boxes remaining in the canvas
|
||||
this.$relationMapContainer.empty();
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this.jsPlumbInstance) {
|
||||
this.clearMap();
|
||||
}
|
||||
|
||||
if (this.pzInstance) {
|
||||
this.pzInstance.dispose();
|
||||
this.pzInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
async initJsPlumbInstance() {
|
||||
if (this.jsPlumbInstance) {
|
||||
this.cleanup();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.jsPlumbInstance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saveData() {
|
||||
this.spacedUpdate.scheduleUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user