diff --git a/src/public/app/components/app_context.ts b/src/public/app/components/app_context.ts index 54041b3d0..ac48070d0 100644 --- a/src/public/app/components/app_context.ts +++ b/src/public/app/components/app_context.ts @@ -262,6 +262,9 @@ type EventMappings = { }; noteContextRemovedEvent: { ntxIds: string[]; + }; + exportSvg: { + ntxId: string; } }; diff --git a/src/public/app/entities/fnote.ts b/src/public/app/entities/fnote.ts index 9759f8b07..9dea5071e 100644 --- a/src/public/app/entities/fnote.ts +++ b/src/public/app/entities/fnote.ts @@ -35,7 +35,7 @@ const NOTE_TYPE_ICONS = { * end user. Those types should be used only for checking against, they are * not for direct use. */ -type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code"; +type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap"; interface NotePathRecord { isArchived: boolean; diff --git a/src/public/app/types-lib.d.ts b/src/public/app/types-lib.d.ts index f91e4d553..d84101b80 100644 --- a/src/public/app/types-lib.d.ts +++ b/src/public/app/types-lib.d.ts @@ -20,3 +20,7 @@ declare module "draggabilly" { destroy(); } } + +declare module '@mind-elixir/node-menu' { + export default mindmap; +} diff --git a/src/public/app/widgets/type_widgets/mind_map.js b/src/public/app/widgets/type_widgets/mind_map.ts similarity index 85% rename from src/public/app/widgets/type_widgets/mind_map.js rename to src/public/app/widgets/type_widgets/mind_map.ts index fafe99b18..3bd72836a 100644 --- a/src/public/app/widgets/type_widgets/mind_map.js +++ b/src/public/app/widgets/type_widgets/mind_map.ts @@ -1,7 +1,11 @@ import TypeWidget from "./type_widget.js"; import utils from "../../services/utils.js"; -import MindElixir from "mind-elixir"; +import MindElixir, { type MindElixirCtor } from "mind-elixir"; import nodeMenu from "@mind-elixir/node-menu"; +import type FNote from "../../entities/fnote.js"; +import type { EventData } from "../../components/app_context.js"; + +const NEW_TOPIC_NAME = ""; const TPL = `
@@ -138,6 +142,11 @@ const TPL = ` `; export default class MindMapWidget extends TypeWidget { + + private $content!: JQuery; + private triggeredByUserOperation?: boolean; + private mind?: ReturnType; + static getType() { return "mindMap"; } @@ -164,7 +173,7 @@ export default class MindMapWidget extends TypeWidget { super.doRender(); } - async doRefresh(note) { + async doRefresh(note: FNote) { if (this.triggeredByUserOperation) { this.triggeredByUserOperation = false; return; @@ -178,12 +187,14 @@ export default class MindMapWidget extends TypeWidget { this.triggeredByUserOperation = false; } - async #loadData(note) { + async #loadData(note: FNote) { const blob = await note.getBlob(); - const content = blob.getJsonContent() || MindElixir.new(); + const content = blob?.getJsonContent() || MindElixir.new(NEW_TOPIC_NAME); - this.mind.refresh(content); - this.mind.toCenter(); + if (this.mind) { + this.mind.refresh(content); + this.mind.toCenter(); + } } #initLibrary() { @@ -194,8 +205,9 @@ export default class MindMapWidget extends TypeWidget { mind.install(nodeMenu); this.mind = mind; - mind.init(MindElixir.new()); - mind.bus.addListener("operation", (operation) => { + mind.init(MindElixir.new(NEW_TOPIC_NAME)); + // TODO: See why the typeof mindmap is not correct. + mind.bus.addListener("operation", (operation: { name: string }) => { this.triggeredByUserOperation = true; if (operation.name !== "beginEdit") { this.spacedUpdate.scheduleUpdate(); @@ -234,14 +246,14 @@ export default class MindMapWidget extends TypeWidget { return await this.mind.exportSvg().text(); } - async entitiesReloadedEvent({ loadResults }) { - if (loadResults.isNoteReloaded(this.noteId)) { + async entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded"> ) { + if (this.noteId && loadResults.isNoteReloaded(this.noteId)) { this.refresh(); } } - async exportSvgEvent({ ntxId }) { - if (!this.isNoteContext(ntxId) || this.note.type !== "mindMap") { + async exportSvgEvent({ ntxId }: EventData<"exportSvg">) { + if (!this.isNoteContext(ntxId) || this.note?.type !== "mindMap") { return; } diff --git a/src/public/app/widgets/type_widgets/type_widget.ts b/src/public/app/widgets/type_widgets/type_widget.ts index 50afb3c61..eab836b2b 100644 --- a/src/public/app/widgets/type_widgets/type_widget.ts +++ b/src/public/app/widgets/type_widgets/type_widget.ts @@ -2,8 +2,12 @@ import NoteContextAwareWidget from "../note_context_aware_widget.js"; import appContext, { type EventData, type EventNames } from "../../components/app_context.js"; import type FNote from "../../entities/fnote.js"; import type NoteDetailWidget from "../note_detail.js"; +import type SpacedUpdate from "../../services/spaced_update.js"; export default abstract class TypeWidget extends NoteContextAwareWidget { + + protected spacedUpdate!: SpacedUpdate; + // for overriding static getType() {}