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(); }