diff --git a/src/frontend/src/components/core/dropdownComponent/index.tsx b/src/frontend/src/components/core/dropdownComponent/index.tsx index a3e9da45e..0cefcaa83 100644 --- a/src/frontend/src/components/core/dropdownComponent/index.tsx +++ b/src/frontend/src/components/core/dropdownComponent/index.tsx @@ -52,9 +52,13 @@ export default function Dropdown({ handleNodeClass, name, dialogInputs, + handleOnNewValue, ...baseInputProps }: BaseInputProps & DropDownComponent): JSX.Element { - const validOptions = useMemo(() => filterNullOptions(options), [options]); + const validOptions = useMemo( + () => filterNullOptions(options), + [options, value], + ); // Initialize state and refs const [open, setOpen] = useState(children ? true : false); @@ -66,11 +70,12 @@ export default function Dropdown({ const refButton = useRef(null); value = useMemo(() => { - if (!options.includes(value)) { + if (!options.includes(value) && !filteredOptions.includes(value)) { return null; } return value; - }, [value, options]); + }, [value, options, filteredOptions]); + // Initialize utilities and constants const placeholderName = name ? formatPlaceholderName(name) @@ -101,14 +106,24 @@ export default function Dropdown({ const searchRoleByTerm = async (event: ChangeEvent) => { const value = event.target.value; + setCustomValue(value); + + if (!value) { + // If search is cleared, show all options + setFilteredOptions(validOptions); + setFilteredMetadata(optionsMetaData); + return; + } + + // Search existing options const searchValues = fuse.search(value); const filtered = searchValues.map((search) => search.item); // Update filteredOptions with the search results - setFilteredOptions(value ? filtered : validOptions); + setFilteredOptions(filtered); // Update filteredMetadata to match the filtered options - if (value && optionsMetaData) { + if (optionsMetaData) { const newMetadata = filtered.map((option) => { const originalIndex = validOptions.indexOf(option); return optionsMetaData[originalIndex]; @@ -117,8 +132,6 @@ export default function Dropdown({ } else { setFilteredMetadata(optionsMetaData); } - - setCustomValue(value); }; const handleRefreshButtonPress = async () => { @@ -166,15 +179,27 @@ export default function Dropdown({ useEffect(() => { if (open) { - const filtered = cloneDeep(validOptions); - if (customValue === value && value && combobox) { - filtered.push(customValue); - } - setFilteredOptions(filtered); + setFilteredOptions(validOptions); + setCustomValue(""); } - }, [open]); + }, [open, validOptions]); - // Render helper functions + const handleInputKeyDown = (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + if (open && customValue) { + const newOptions = [...validOptions]; + if (!newOptions.includes(customValue)) { + newOptions.push(customValue); + } + + setFilteredOptions(newOptions); + + handleOnNewValue?.({ value: customValue }); + onSelect(customValue); + setOpen(false); + } + } + }; const renderLoadingButton = () => (