diff --git a/apps/client/src/widgets/attribute_widgets/attribute_editor.ts b/apps/client/src/widgets/attribute_widgets/attribute_editor.ts index 9dc426c6e..cb6d8272e 100644 --- a/apps/client/src/widgets/attribute_widgets/attribute_editor.ts +++ b/apps/client/src/widgets/attribute_widgets/attribute_editor.ts @@ -1,25 +1,12 @@ import { t } from "../../services/i18n.js"; import NoteContextAwareWidget from "../note_context_aware_widget.js"; -import server from "../../services/server.js"; import contextMenuService from "../../menus/context_menu.js"; -import attributeParser, { type Attribute } from "../../services/attribute_parser.js"; import { AttributeEditor, type EditorConfig, type ModelElement, type MentionFeed, type ModelNode, type ModelPosition } from "@triliumnext/ckeditor5"; -import froca from "../../services/froca.js"; import noteCreateService from "../../services/note_create.js"; import attributeService from "../../services/attributes.js"; -import linkService from "../../services/link.js"; import type AttributeDetailWidget from "./attribute_detail.js"; import type { CommandData, EventData, EventListener, FilteredCommandNames } from "../../components/app_context.js"; import type { default as FAttribute, AttributeType } from "../../entities/fattribute.js"; -import { escapeQuotes } from "../../services/utils.js"; - -const TPL = /*html*/` - -
- -`; - -type AttributeCommandNames = FilteredCommandNames; export default class AttributeEditorWidget extends NoteContextAwareWidget implements EventListener<"entitiesReloaded">, EventListener<"addNewLabel">, EventListener<"addNewRelation"> { private attributeDetailWidget: AttributeDetailWidget; @@ -48,30 +35,9 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem this.$editor.on("blur", () => setTimeout(() => this.save(), 100)); // Timeout to fix https://github.com/zadam/trilium/issues/4160 - this.$addNewAttributeButton = this.$widget.find(".add-new-attribute-button"); - this.$addNewAttributeButton.on("click", (e) => this.addNewAttribute(e)); - this.$saveAttributesButton.on("click", () => this.save()); } - addNewAttribute(e: JQuery.ClickEvent) { - contextMenuService.show({ - x: e.pageX, - y: e.pageY, - orientation: "left", - items: [ - { title: t("attribute_editor.add_new_label"), command: "addNewLabel", uiIcon: "bx bx-hash" }, - { title: t("attribute_editor.add_new_relation"), command: "addNewRelation", uiIcon: "bx bx-transfer" }, - { title: "----" }, - { title: t("attribute_editor.add_new_label_definition"), command: "addNewLabelDefinition", uiIcon: "bx bx-empty" }, - { title: t("attribute_editor.add_new_relation_definition"), command: "addNewRelationDefinition", uiIcon: "bx bx-empty" } - ], - selectMenuItemHandler: ({ command }) => this.handleAddNewAttributeCommand(command) - }); - // Prevent automatic hiding of the context menu due to the button being clicked. - e.stopPropagation(); - } - // triggered from keyboard shortcut async addNewLabelEvent({ ntxId }: EventData<"addNewLabel">) { if (this.isNoteContext(ntxId)) { @@ -90,66 +56,6 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem } } - async handleAddNewAttributeCommand(command: AttributeCommandNames | undefined) { - // TODO: Not sure what the relation between FAttribute[] and Attribute[] is. - const attrs = this.parseAttributes() as FAttribute[]; - - if (!attrs) { - return; - } - - let type: AttributeType; - let name; - let value; - - if (command === "addNewLabel") { - type = "label"; - name = "myLabel"; - value = ""; - } else if (command === "addNewRelation") { - type = "relation"; - name = "myRelation"; - value = ""; - } else if (command === "addNewLabelDefinition") { - type = "label"; - name = "label:myLabel"; - value = "promoted,single,text"; - } else if (command === "addNewRelationDefinition") { - type = "label"; - name = "relation:myRelation"; - value = "promoted,single"; - } else { - return; - } - - // TODO: Incomplete type - //@ts-ignore - attrs.push({ - type, - name, - value, - isInheritable: false - }); - - await this.renderOwnedAttributes(attrs, false); - - this.$editor.scrollTop(this.$editor[0].scrollHeight); - - const rect = this.$editor[0].getBoundingClientRect(); - - setTimeout(() => { - // showing a little bit later because there's a conflict with outside click closing the attr detail - this.attributeDetailWidget.showAttributeDetail({ - allAttributes: attrs, - attribute: attrs[attrs.length - 1], - isOwned: true, - x: (rect.left + rect.right) / 2, - y: rect.bottom, - focus: "name" - }); - }, 100); - } - async save() { if (this.lastUpdatedNoteId !== this.noteId) { // https://github.com/zadam/trilium/issues/3090 diff --git a/apps/client/src/widgets/react/ActionButton.tsx b/apps/client/src/widgets/react/ActionButton.tsx index 65eb60469..a6a1ee740 100644 --- a/apps/client/src/widgets/react/ActionButton.tsx +++ b/apps/client/src/widgets/react/ActionButton.tsx @@ -2,7 +2,7 @@ interface ActionButtonProps { text: string; icon: string; className?: string; - onClick?: () => void; + onClick?: (e: MouseEvent) => void; } export default function ActionButton({ text, icon, className, onClick }: ActionButtonProps) { diff --git a/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx index 9ea7ebaca..f868744c5 100644 --- a/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx +++ b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx @@ -16,6 +16,11 @@ import { ParentComponent } from "../../react/react_utils"; import Component from "../../../components/component"; import link from "../../../services/link"; import froca from "../../../services/froca"; +import contextMenu from "../../../menus/context_menu"; +import type { CommandData, FilteredCommandNames } from "../../../components/app_context"; +import { AttributeType } from "@triliumnext/commons"; + +type AttributeCommandNames = FilteredCommandNames; const HELP_TEXT = `

${t("attribute_editor.help_text_body1")}

@@ -143,6 +148,65 @@ export default function AttributeEditor({ note, componentId }: { note: FNote, co } } + async function handleAddNewAttributeCommand(command: AttributeCommandNames | undefined) { + // TODO: Not sure what the relation between FAttribute[] and Attribute[] is. + const attrs = parseAttributes() as FAttribute[]; + + if (!attrs) { + return; + } + + let type: AttributeType; + let name; + let value; + + if (command === "addNewLabel") { + type = "label"; + name = "myLabel"; + value = ""; + } else if (command === "addNewRelation") { + type = "relation"; + name = "myRelation"; + value = ""; + } else if (command === "addNewLabelDefinition") { + type = "label"; + name = "label:myLabel"; + value = "promoted,single,text"; + } else if (command === "addNewRelationDefinition") { + type = "label"; + name = "relation:myRelation"; + value = "promoted,single"; + } else { + return; + } + + // TODO: Incomplete type + //@ts-ignore + attrs.push({ + type, + name, + value, + isInheritable: false + }); + + await renderOwnedAttributes(attrs, false); + + // this.$editor.scrollTop(this.$editor[0].scrollHeight); + const rect = wrapperRef.current?.getBoundingClientRect(); + + setTimeout(() => { + // showing a little bit later because there's a conflict with outside click closing the attr detail + attributeDetailWidget.showAttributeDetail({ + allAttributes: attrs, + attribute: attrs[attrs.length - 1], + isOwned: true, + x: rect ? (rect.left + rect.right) / 2 : 0, + y: rect?.bottom ?? 0, + focus: "name" + }); + }, 100); + } + useEffect(() => { renderOwnedAttributes(note.getOwnedAttributes(), true); }, [ note ]); @@ -228,6 +292,30 @@ export default function AttributeEditor({ note, componentId }: { note: FNote, co onClick={save} /> } + { + // Prevent automatic hiding of the context menu due to the button being clicked. + e.stopPropagation(); + + contextMenu.show({ + x: e.pageX, + y: e.pageY, + orientation: "left", + items: [ + { title: t("attribute_editor.add_new_label"), command: "addNewLabel", uiIcon: "bx bx-hash" }, + { title: t("attribute_editor.add_new_relation"), command: "addNewRelation", uiIcon: "bx bx-transfer" }, + { title: "----" }, + { title: t("attribute_editor.add_new_label_definition"), command: "addNewLabelDefinition", uiIcon: "bx bx-empty" }, + { title: t("attribute_editor.add_new_relation_definition"), command: "addNewRelationDefinition", uiIcon: "bx bx-empty" } + ], + selectMenuItemHandler: (item) => handleAddNewAttributeCommand(item.command) + }); + }} + /> + { error && (
{typeof error === "object" && "message" in error && typeof error.message === "string" && error.message}