chore(react/promoted_attributes): add back text label autocomplete

This commit is contained in:
Elian Doran 2025-11-23 11:33:14 +02:00
parent aca390ee19
commit 87f30ed3d5
No known key found for this signature in database
2 changed files with 72 additions and 42 deletions

View File

@ -93,7 +93,7 @@ export default function PromotedAttributes() {
} }
function PromotedAttributeCell(props: CellProps) { function PromotedAttributeCell(props: CellProps) {
const { valueName, valueAttr, definition, definitionAttr } = props.cell; const { valueName, valueAttr, definition } = props.cell;
const inputId = useUniqueName(`value-${valueAttr.name}`); const inputId = useUniqueName(`value-${valueAttr.name}`);
useEffect(() => { useEffect(() => {
@ -108,16 +108,7 @@ function PromotedAttributeCell(props: CellProps) {
<div className="promoted-attribute-cell"> <div className="promoted-attribute-cell">
<label for={inputId}>{definition.promotedAlias ?? valueName}</label> <label for={inputId}>{definition.promotedAlias ?? valueName}</label>
<div className="input-group"> <div className="input-group">
<input <LabelInput inputId={inputId} {...props} />
className="form-control promoted-attribute-input"
tabIndex={200 + definitionAttr.position}
id={inputId}
value={valueAttr.value}
placeholder={t("promoted_attributes.unset-field-placeholder")}
data-attribute-id={valueAttr.attributeId}
data-attribute-type={valueAttr.type}
data-attribute-name={valueAttr.name}
/>
</div> </div>
<ActionCell /> <ActionCell />
<MultiplicityCell {...props} /> <MultiplicityCell {...props} />
@ -125,6 +116,39 @@ function PromotedAttributeCell(props: CellProps) {
) )
} }
function LabelInput({ inputId, ...props }: CellProps & { inputId: string }) {
const { valueAttr, definition, definitionAttr } = props.cell;
useEffect(() => {
if (definition.labelType === "text") {
const el = document.getElementById(inputId);
if (el) {
setupTextLabelAutocomplete(el as HTMLInputElement, valueAttr, () => {
// TODO: Implement me.
console.log("Got change");
});
}
}
}, []);
return (
<input
className="form-control promoted-attribute-input"
tabIndex={200 + definitionAttr.position}
id={inputId}
value={valueAttr.value}
placeholder={t("promoted_attributes.unset-field-placeholder")}
data-attribute-id={valueAttr.attributeId}
data-attribute-type={valueAttr.type}
data-attribute-name={valueAttr.name}
/>
)
}
function RelationInput() {
}
function ActionCell() { function ActionCell() {
return ( return (
<div> <div>
@ -205,3 +229,40 @@ function PromotedActionButton({ icon, title, onClick }: {
/> />
) )
} }
function setupTextLabelAutocomplete(el: HTMLInputElement, valueAttr: Attribute, onChangeListener: () => void) {
// no need to await for this, can be done asynchronously
const $input = $(el);
server.get<string[]>(`attribute-values/${encodeURIComponent(valueAttr.name)}`).then((_attributeValues) => {
if (_attributeValues.length === 0) {
return;
}
const attributeValues = _attributeValues.map((attribute) => ({ value: attribute }));
$input.autocomplete(
{
appendTo: document.querySelector("body"),
hint: false,
autoselect: false,
openOnFocus: true,
minLength: 0,
tabAutocomplete: false
},
[
{
displayKey: "value",
source: function (term, cb) {
term = term.toLowerCase();
const filtered = attributeValues.filter((attr) => attr.value.toLowerCase().includes(term));
cb(filtered);
}
}
]
);
$input.on("autocomplete:selected", onChangeListener);
});
}

View File

@ -32,38 +32,7 @@ export default class PromotedAttributesWidget extends NoteContextAwareWidget {
// autocomplete for label values is just nice to have, mobile can keep labels editable without autocomplete // autocomplete for label values is just nice to have, mobile can keep labels editable without autocomplete
if (utils.isDesktop()) { if (utils.isDesktop()) {
// no need to await for this, can be done asynchronously
server.get<string[]>(`attribute-values/${encodeURIComponent(valueAttr.name)}`).then((_attributeValues) => {
if (_attributeValues.length === 0) {
return;
}
const attributeValues = _attributeValues.map((attribute) => ({ value: attribute }));
$input.autocomplete(
{
appendTo: document.querySelector("body"),
hint: false,
autoselect: false,
openOnFocus: true,
minLength: 0,
tabAutocomplete: false
},
[
{
displayKey: "value",
source: function (term, cb) {
term = term.toLowerCase();
const filtered = attributeValues.filter((attr) => attr.value.toLowerCase().includes(term));
cb(filtered);
}
}
]
);
$input.on("autocomplete:selected", (e) => this.promotedAttributeChanged(e));
}); });
} }
} else if (definition.labelType === "number") { } else if (definition.labelType === "number") {