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}