diff --git a/apps/client/src/widgets/attribute_widgets/attribute_editor.ts b/apps/client/src/widgets/attribute_widgets/attribute_editor.ts
index 3e97723a5..24a4e09d2 100644
--- a/apps/client/src/widgets/attribute_widgets/attribute_editor.ts
+++ b/apps/client/src/widgets/attribute_widgets/attribute_editor.ts
@@ -24,58 +24,6 @@ const HELP_TEXT = `
${t("attribute_editor.help_text_body3")}
`;
const TPL = /*html*/`
-
-
-
-
@@ -84,61 +32,6 @@ const TPL = /*html*/`
`;
-const mentionSetup: MentionFeed[] = [
- {
- marker: "@",
- feed: (queryText) => noteAutocompleteService.autocompleteSourceForCKEditor(queryText),
- itemRenderer: (_item) => {
- const item = _item as Suggestion;
- const itemElement = document.createElement("button");
-
- itemElement.innerHTML = `${item.highlightedNotePathTitle} `;
-
- return itemElement;
- },
- minimumCharacters: 0
- },
- {
- marker: "#",
- feed: async (queryText) => {
- const names = await server.get(`attribute-names/?type=label&query=${encodeURIComponent(queryText)}`);
-
- return names.map((name) => {
- return {
- id: `#${name}`,
- name: name
- };
- });
- },
- minimumCharacters: 0
- },
- {
- marker: "~",
- feed: async (queryText) => {
- const names = await server.get(`attribute-names/?type=relation&query=${encodeURIComponent(queryText)}`);
-
- return names.map((name) => {
- return {
- id: `~${name}`,
- name: name
- };
- });
- },
- minimumCharacters: 0
- }
-];
-
-const editorConfig: EditorConfig = {
- toolbar: {
- items: []
- },
- placeholder: t("attribute_editor.placeholder"),
- mention: {
- feeds: mentionSetup
- },
- licenseKey: "GPL"
-};
-
type AttributeCommandNames = FilteredCommandNames;
export default class AttributeEditorWidget extends NoteContextAwareWidget implements EventListener<"entitiesReloaded">, EventListener<"addNewLabel">, EventListener<"addNewRelation"> {
@@ -324,7 +217,6 @@ export default class AttributeEditorWidget extends NoteContextAwareWidget implem
this.$editor.on("click", (e) => this.handleEditorClick(e));
- this.textEditor = await AttributeEditor.create(this.$editor[0], editorConfig);
this.textEditor.model.document.on("change:data", () => this.dataChanged());
this.textEditor.editing.view.document.on(
"enter",
diff --git a/apps/client/src/widgets/ribbon/OwnedAttributesTab.tsx b/apps/client/src/widgets/ribbon/OwnedAttributesTab.tsx
new file mode 100644
index 000000000..33554989c
--- /dev/null
+++ b/apps/client/src/widgets/ribbon/OwnedAttributesTab.tsx
@@ -0,0 +1,10 @@
+import AttributeEditor from "./components/AttributeEditor";
+import { TabContext } from "./ribbon-interface";
+
+export default function OwnedAttributesTab({ note }: TabContext) {
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/ribbon/Ribbon.tsx b/apps/client/src/widgets/ribbon/Ribbon.tsx
index 4702dcf07..032a905a6 100644
--- a/apps/client/src/widgets/ribbon/Ribbon.tsx
+++ b/apps/client/src/widgets/ribbon/Ribbon.tsx
@@ -19,6 +19,7 @@ import FilePropertiesTab from "./FilePropertiesTab";
import ImagePropertiesTab from "./ImagePropertiesTab";
import NotePathsTab from "./NotePathsTab";
import NoteMapTab from "./NoteMapTab";
+import OwnedAttributesTab from "./OwnedAttributesTab";
interface TitleContext {
note: FNote | null | undefined;
@@ -105,9 +106,11 @@ const TAB_CONFIGURATION = numberObjectsInPlace([
toggleCommand: "toggleRibbonTabBasicProperties"
},
{
- // OwnedAttributeListWidget
title: t("owned_attribute_list.owned_attributes"),
- icon: "bx bx-list-check"
+ icon: "bx bx-list-check",
+ content: OwnedAttributesTab,
+ show: ({note}) => !note?.isLaunchBarConfig(),
+ toggleCommand: "toggleRibbonTabOwnedAttributes"
},
{
// InheritedAttributesWidget
diff --git a/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx
new file mode 100644
index 000000000..88bc85139
--- /dev/null
+++ b/apps/client/src/widgets/ribbon/components/AttributeEditor.tsx
@@ -0,0 +1,78 @@
+import { useEffect, useRef } from "preact/hooks"
+import { AttributeEditor as CKEditor, EditorConfig, MentionFeed } from "@triliumnext/ckeditor5";
+import { t } from "../../../services/i18n";
+import server from "../../../services/server";
+import note_autocomplete, { Suggestion } from "../../../services/note_autocomplete";
+
+const mentionSetup: MentionFeed[] = [
+ {
+ marker: "@",
+ feed: (queryText) => note_autocomplete.autocompleteSourceForCKEditor(queryText),
+ itemRenderer: (_item) => {
+ const item = _item as Suggestion;
+ const itemElement = document.createElement("button");
+
+ itemElement.innerHTML = `${item.highlightedNotePathTitle} `;
+
+ return itemElement;
+ },
+ minimumCharacters: 0
+ },
+ {
+ marker: "#",
+ feed: async (queryText) => {
+ const names = await server.get(`attribute-names/?type=label&query=${encodeURIComponent(queryText)}`);
+
+ return names.map((name) => {
+ return {
+ id: `#${name}`,
+ name: name
+ };
+ });
+ },
+ minimumCharacters: 0
+ },
+ {
+ marker: "~",
+ feed: async (queryText) => {
+ const names = await server.get(`attribute-names/?type=relation&query=${encodeURIComponent(queryText)}`);
+
+ return names.map((name) => {
+ return {
+ id: `~${name}`,
+ name: name
+ };
+ });
+ },
+ minimumCharacters: 0
+ }
+];
+
+const editorConfig: EditorConfig = {
+ toolbar: {
+ items: []
+ },
+ placeholder: t("attribute_editor.placeholder"),
+ mention: {
+ feeds: mentionSetup
+ },
+ licenseKey: "GPL"
+};
+
+export default function AttributeEditor() {
+ const editorContainerRef = useRef(null);
+
+ useEffect(() => {
+ if (!editorContainerRef.current) return;
+
+ CKEditor.create(editorContainerRef.current, editorConfig).then((textEditor) => {
+
+ });
+ }, []);
+
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/ribbon/style.css b/apps/client/src/widgets/ribbon/style.css
index c09fa989f..22c9d7b43 100644
--- a/apps/client/src/widgets/ribbon/style.css
+++ b/apps/client/src/widgets/ribbon/style.css
@@ -267,4 +267,68 @@
color: var(--muted-text-color);
display: none;
}
+/* #endregion */
+
+/* #region Attribute editor */
+.attribute-list-editor {
+ border: 0 !important;
+ outline: 0 !important;
+ box-shadow: none !important;
+ padding: 0 0 0 5px !important;
+ margin: 0 !important;
+ max-height: 100px;
+ overflow: auto;
+ transition: opacity .1s linear;
+}
+
+.attribute-list-editor.ck-content .mention {
+ color: var(--muted-text-color) !important;
+ background: transparent !important;
+}
+
+.save-attributes-button {
+ color: var(--muted-text-color);
+ position: absolute;
+ bottom: 14px;
+ right: 25px;
+ cursor: pointer;
+ border: 1px solid transparent;
+ font-size: 130%;
+}
+
+.add-new-attribute-button {
+ color: var(--muted-text-color);
+ position: absolute;
+ bottom: 13px;
+ right: 0;
+ cursor: pointer;
+ border: 1px solid transparent;
+ font-size: 130%;
+}
+
+.add-new-attribute-button:hover, .save-attributes-button:hover {
+ border: 1px solid var(--button-border-color);
+ border-radius: var(--button-border-radius);
+ background: var(--button-background-color);
+ color: var(--button-text-color);
+}
+
+.attribute-errors {
+ color: red;
+ padding: 5px 50px 0px 5px; /* large right padding to avoid buttons */
+}
+/* #endregion */
+
+/* #region Owned Attributes */
+.attribute-list {
+ margin-left: 7px;
+ margin-right: 7px;
+ margin-top: 5px;
+ margin-bottom: 2px;
+ position: relative;
+}
+
+.attribute-list-editor p {
+ margin: 0 !important;
+}
/* #endregion */
\ No newline at end of file
diff --git a/apps/client/src/widgets/ribbon_widgets/owned_attribute_list.ts b/apps/client/src/widgets/ribbon_widgets/owned_attribute_list.ts
index 113e03e0d..6b036bd0e 100644
--- a/apps/client/src/widgets/ribbon_widgets/owned_attribute_list.ts
+++ b/apps/client/src/widgets/ribbon_widgets/owned_attribute_list.ts
@@ -5,40 +5,12 @@ import AttributeEditorWidget from "../attribute_widgets/attribute_editor.js";
import type { CommandListenerData } from "../../components/app_context.js";
import type FAttribute from "../../entities/fattribute.js";
-const TPL = /*html*/`
-
-`;
-
export default class OwnedAttributeListWidget extends NoteContextAwareWidget {
private attributeDetailWidget: AttributeDetailWidget;
private attributeEditorWidget: AttributeEditorWidget;
private $title!: JQuery;
- get name() {
- return "ownedAttributes";
- }
-
- get toggleCommand() {
- return "toggleRibbonTabOwnedAttributes";
- }
-
constructor() {
super();
@@ -49,23 +21,6 @@ export default class OwnedAttributeListWidget extends NoteContextAwareWidget {
this.child(this.attributeEditorWidget, this.attributeDetailWidget);
}
- getTitle() {
- return {
- show: !this.note?.isLaunchBarConfig(),
-
- };
- }
-
- doRender() {
- this.$widget = $(TPL);
- this.contentSized();
-
- this.$widget.find(".attr-editor-placeholder").replaceWith(this.attributeEditorWidget.render());
- this.$widget.append(this.attributeDetailWidget.render());
-
- this.$title = $("");
- }
-
async saveAttributesCommand() {
await this.attributeEditorWidget.save();
}