Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 fix(autocomplete): tags not generated for preselected options #1403

50 changes: 22 additions & 28 deletions client/src/app/components/Autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,13 @@
}) => {
const [inputValue, setInputValue] = useState(searchString);
const [menuIsOpen, setMenuIsOpen] = useState(false);
const [currentChips, setCurrentChips] = useState<Set<string>>(
new Set(selections)
);
const [hint, setHint] = useState("");
const [menuItems, setMenuItems] = useState<React.ReactElement[]>([]);

/** refs used to detect when clicks occur inside vs outside of the textInputGroup and menu popper */
const menuRef = useRef<HTMLDivElement>(null);
const searchInputRef = useRef<HTMLInputElement>(null);

React.useEffect(() => {
onChange([...currentChips]);
buildMenu();
}, [currentChips]);

React.useEffect(() => {
buildMenu();
}, [options]);
Expand All @@ -67,7 +59,7 @@
.filter(
(item: string, index: number, arr: string[]) =>
arr.indexOf(item) === index &&
!currentChips.has(item) &&
!selections.includes(item) &&

Check warning on line 62 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L62

Added line #L62 was not covered by tests
(!inputValue || item.toLowerCase().includes(inputValue.toLowerCase()))
)
.map((currentValue, index) => (
Expand Down Expand Up @@ -127,33 +119,32 @@
buildMenu();
};

/** callback for removing a chip from the chip selections */
const deleteChip = (chipToDelete: string) => {
const newChips = new Set(currentChips);
newChips.delete(chipToDelete);
setCurrentChips(newChips);
/** callback for removing a selection */
const deleteSelection = (selectionToDelete: string) => {
onChange(selections.filter((s) => s !== selectionToDelete));

Check warning on line 124 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L124

Added line #L124 was not covered by tests
};

/** add the given string as a chip in the chip group and clear the input */
const addChip = (newChipText: string) => {
/** add the given string as a selection */
const addSelection = (newSelectionText: string) => {
if (!allowUserOptions) {
const matchingOption = options.find(
(o) => o.toLowerCase() === (hint || newChipText).toLowerCase()
(o) => o.toLowerCase() === (hint || newSelectionText).toLowerCase()
);
if (!matchingOption) {
console.log({ matchingOption, newSelectionText, options });

Check warning on line 133 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L133

Added line #L133 was not covered by tests
if (!matchingOption || selections.includes(matchingOption)) {
return;
}
newChipText = matchingOption;
newSelectionText = matchingOption;

Check warning on line 137 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L137

Added line #L137 was not covered by tests
}
setCurrentChips(new Set([...currentChips, newChipText]));
onChange([...selections, newSelectionText]);

Check warning on line 139 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L139

Added line #L139 was not covered by tests
setInputValue("");
setMenuIsOpen(false);
};

/** add the current input value as a chip */
/** add the current input value as a selection */
const handleEnter = () => {
if (inputValue.length) {
addChip(inputValue);
addSelection(inputValue);

Check warning on line 147 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L147

Added line #L147 was not covered by tests
}
};

Expand Down Expand Up @@ -216,13 +207,13 @@
closeMenu && setMenuIsOpen(false);
};

/** add the text of the selected item as a new chip */
/** add the text of the selected menu item to the selected items */
const onSelect = (event?: React.MouseEvent<Element, MouseEvent>) => {
if (!event) {
return;
}
const selectedText = (event.target as HTMLElement).innerText;
addChip(selectedText);
addSelection(selectedText);

Check warning on line 216 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L216

Added line #L216 was not covered by tests
event.stopPropagation();
focusTextInput(true);
};
Expand Down Expand Up @@ -301,10 +292,13 @@
</FlexItem>
<FlexItem key="chips">
<Flex spaceItems={{ default: "spaceItemsXs" }}>
{Array.from(currentChips).map((currentChip) => (
<FlexItem key={currentChip}>
<Label color={labelColor} onClose={() => deleteChip(currentChip)}>
{currentChip}
{selections.map((currentSelection) => (
<FlexItem key={currentSelection}>

Check warning on line 296 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L296

Added line #L296 was not covered by tests
<Label
color={labelColor}
onClose={() => deleteSelection(currentSelection)}

Check warning on line 299 in client/src/app/components/Autocomplete.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/components/Autocomplete.tsx#L299

Added line #L299 was not covered by tests
>
{currentSelection}
</Label>
</FlexItem>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,12 @@
}
}, []);

const tagOptions =
tags?.map((tag) => {
return {
value: tag.name,
toString: () => tag.name,
};
}) || [];
const tagOptions = new Set(
(tags || []).reduce<string[]>(
(acc, curr) => (!curr.source ? [...acc, curr.name] : acc),
[]
)
);

const getBinaryInitialValue = (
application: Application | null,
Expand Down Expand Up @@ -385,7 +384,7 @@
];

const getTagRef = (tagName: string) =>
tags?.find((tag) => tag.name === tagName);
Object.assign({ source: "" }, tags?.find((tag) => tag.name === tagName));

Check warning on line 387 in client/src/app/pages/applications/components/application-form/application-form.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/pages/applications/components/application-form/application-form.tsx#L387

Added line #L387 was not covered by tests

return (
<Form onSubmit={handleSubmit(onSubmit)}>
Expand Down Expand Up @@ -445,78 +444,34 @@
name="tags"
label={t("terms.tags")}
fieldId="tags"
renderInput={({ field: { value, name, onChange } }) => (
<Autocomplete
noResultsMessage={t("message.noResultsFoundTitle")}
onChange={(selections) => {
onChange(
selections
.map((sel) => getTagRef(sel))
.filter((sel) => sel !== undefined) as TagRef[]
);
}}
options={tagOptions.map((o) => o.value)}
placeholderText={t("composed.selectMany", {
what: t("terms.tags").toLowerCase(),
})}
searchInputAriaLabel="tags-select-toggle"
selections={
value
.map(
(formTag) =>
tags?.find((tagRef) => tagRef.name === formTag.name)
)
.map((matchingTag) =>
matchingTag ? matchingTag.name : undefined
)
.filter((e) => e !== undefined) as string[]
}
/>
// <SimpleSelect
// maxHeight={DEFAULT_SELECT_MAX_HEIGHT}
// placeholderText={t("composed.selectMany", {
// what: t("terms.tags").toLowerCase(),
// })}
// id="tags-select"
// variant="typeaheadmulti"
// toggleId="tags-select-toggle"
// toggleAriaLabel="tags dropdown toggle"
// aria-label={name}
// value={value
// .map((formTag) =>
// tags?.find((tagRef) => tagRef.name === formTag.name)
// )
// .map((matchingTag) =>
// matchingTag
// ? {
// value: matchingTag.name,
// toString: () => matchingTag.name,
// }
// : undefined
// )
// .filter((e) => e !== undefined)}
// options={tagOptions}
// onChange={(selection) => {
// const selectionWithValue = selection.toString();

// const currentValue = value || [];
// const e = currentValue.find(
// (f) => f.name === selectionWithValue
// );
// if (e) {
// onChange(
// currentValue.filter((f) => f.name !== selectionWithValue)
// );
// } else {
// const tag = getTagRef(selectionWithValue);
// if (currentValue && typeof tag !== "undefined")
// onChange([...currentValue, tag]);
// }
// }}
// onClear={() => onChange([])}
// noResultsFoundText={t("message.noResultsFoundTitle")}
// />
)}
renderInput={({ field: { value, name, onChange } }) => {
const selections = value.reduce<string[]>(
(acc, curr) =>
curr.source === "" && tagOptions.has(curr.name)
? [...acc, curr.name]
: acc,

Check warning on line 452 in client/src/app/pages/applications/components/application-form/application-form.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/pages/applications/components/application-form/application-form.tsx#L451-L452

Added lines #L451 - L452 were not covered by tests
[]
);

return (
<Autocomplete
noResultsMessage={t("message.noResultsFoundTitle")}
onChange={(selections) => {
onChange(

Check warning on line 460 in client/src/app/pages/applications/components/application-form/application-form.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/pages/applications/components/application-form/application-form.tsx#L459-L460

Added lines #L459 - L460 were not covered by tests
selections
.map((sel) => getTagRef(sel))
.filter((sel) => sel !== undefined) as TagRef[]

Check warning on line 463 in client/src/app/pages/applications/components/application-form/application-form.tsx

View check run for this annotation

Codecov / codecov/patch

client/src/app/pages/applications/components/application-form/application-form.tsx#L462-L463

Added lines #L462 - L463 were not covered by tests
);
}}
options={Array.from(tagOptions)}
placeholderText={t("composed.selectMany", {
what: t("terms.tags").toLowerCase(),
})}
searchInputAriaLabel="tags-select-toggle"
selections={selections}
/>
);
}}
/>
<HookFormPFGroupController
control={control}
Expand Down
Loading