diff --git a/apps/client/src/widgets/PromotedAttributes.tsx b/apps/client/src/widgets/PromotedAttributes.tsx
index 9fca59704..54ed808a2 100644
--- a/apps/client/src/widgets/PromotedAttributes.tsx
+++ b/apps/client/src/widgets/PromotedAttributes.tsx
@@ -8,8 +8,10 @@ import { t } from "../services/i18n";
import { DefinitionObject, LabelType } from "../services/promoted_attribute_definition_parser";
import server from "../services/server";
import FNote from "../entities/fnote";
-import { HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact";
+import { ComponentChild, HTMLInputTypeAttribute, InputHTMLAttributes, MouseEventHandler, TargetedEvent, TargetedInputEvent } from "preact";
import tree from "../services/tree";
+import NoteAutocomplete from "./react/NoteAutocomplete";
+import ws from "../services/ws";
interface Cell {
definitionAttr: FAttribute;
@@ -112,11 +114,24 @@ function PromotedAttributeCell(props: CellProps) {
}
}, [ props.shouldFocus ]);
+ let correspondingInput: ComponentChild;
+ switch (valueAttr.type) {
+ case "label":
+ correspondingInput = ;
+ break;
+ case "relation":
+ correspondingInput = ;
+ break;
+ default:
+ ws.logError(t(`promoted_attributes.unknown_attribute_type`, { type: valueAttr.type }));
+ break;
+ }
+
return (
{definition.labelType !== "boolean" &&
}
-
+ {correspondingInput}
@@ -136,7 +151,7 @@ const LABEL_MAPPINGS: Record = {
function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) {
const { valueName, valueAttr, definition, definitionAttr } = props.cell;
- const onChangeListener = buildPromotedAttributeChangedListener({...props});
+ const onChangeListener = buildPromotedAttributeLabelChangedListener({...props});
const extraInputProps: InputHTMLAttributes = {};
useEffect(() => {
@@ -249,8 +264,17 @@ function ColorPicker({ cell, onChange, inputId }: CellProps & {
)
}
-function RelationInput() {
-
+function RelationInput({ inputId, ...props }: CellProps & { inputId: string }) {
+ return (
+ {
+ const { note, cell, componentId } = props;
+ cell.valueAttr.attributeId = (await updateAttribute(note, cell, componentId, value)).attributeId;
+ }}
+ />
+ )
}
function ActionCell() {
@@ -384,32 +408,30 @@ function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute,
});
}
-function buildPromotedAttributeChangedListener({ note, cell, componentId }: CellProps) {
- return async (e: TargetedEvent) => {
+function buildPromotedAttributeLabelChangedListener({ note, cell, componentId, ...props }: CellProps) {
+ return async (e: TargetedEvent | InputEvent) => {
const inputEl = e.target as HTMLInputElement;
let value: string;
if (inputEl.type === "checkbox") {
value = inputEl.checked ? "true" : "false";
- } else if (inputEl.dataset.attributeType === "relation") {
- const selectedPath = $(inputEl).getSelectedNotePath();
- value = selectedPath ? tree.getNoteIdFromUrl(selectedPath) ?? "" : "";
- console.log("Got relation ", value);
} else {
value = inputEl.value;
}
- const result = await server.put(
- `notes/${note.noteId}/attribute`,
- {
- attributeId: cell.valueAttr.attributeId,
- type: cell.valueAttr.type,
- name: cell.valueName,
- value: value
- },
- componentId
- );
-
- cell.valueAttr.attributeId = result.attributeId;
+ cell.valueAttr.attributeId = (await updateAttribute(note, cell, componentId, value)).attributeId;
}
}
+
+function updateAttribute(note: FNote, cell: Cell, componentId: string, value: string) {
+ return server.put(
+ `notes/${note.noteId}/attribute`,
+ {
+ attributeId: cell.valueAttr.attributeId,
+ type: cell.valueAttr.type,
+ name: cell.valueName,
+ value: value
+ },
+ componentId
+ );
+}
diff --git a/apps/client/src/widgets/promoted_attributes.ts b/apps/client/src/widgets/promoted_attributes.ts
index 074e2437f..5aafa4ed3 100644
--- a/apps/client/src/widgets/promoted_attributes.ts
+++ b/apps/client/src/widgets/promoted_attributes.ts
@@ -1,49 +1,5 @@
export default class PromotedAttributesWidget extends NoteContextAwareWidget {
- async createPromotedAttributeCell(definitionAttr: FAttribute, valueAttr: Attribute, valueName: string) {
- const definition = definitionAttr.getDefinition();
-
- const $input = $("")
- .on("change", (event) => this.promotedAttributeChanged(event));
-
- if (valueAttr.type === "label") {
- $wrapper.addClass(`promoted-attribute-label-${definition.labelType}`);
- } else if (definition.labelType === "boolean") {
- $input.wrap($(``));
- $wrapper.find(".input-group").removeClass("input-group");
-
- if (valueAttr.value === "true") {
- $input.prop("checked", "checked");
- }
- } else {
- ws.logError(t("promoted_attributes.unknown_label_type", { type: definition.labelType }));
- }
- } else if (valueAttr.type === "relation") {
- if (valueAttr.value) {
- $input.val(await treeService.getNoteTitle(valueAttr.value));
- }
-
- if (utils.isDesktop()) {
- // no need to wait for this
- noteAutocompleteService.initNoteAutocomplete($input, { allowCreatingNotes: true });
-
- $input.on("autocomplete:noteselected", (event, suggestion, dataset) => {
- this.promotedAttributeChanged(event);
- });
-
- $input.setSelectedNotePath(valueAttr.value);
- } else {
- // we can't provide user a way to edit the relation so make it read only
- $input.attr("readonly", "readonly");
- }
- } else {
- ws.logError(t(`promoted_attributes.unknown_attribute_type`, { type: valueAttr.type }));
- return;
- }
-
- return $wrapper;
- }
-
focus() {
this.$widget.find(".promoted-attribute-input:first").focus();
}