import React, { useState, useEffect, useCallback } from 'react'; import { FormTokenField } from "../ui/form-token-field"; import { ComboboxControl } from "../ui/combobox-control"; import { ProgressBar } from "../ui/progress-bar"; import type { TokenItem } from "../ui/form-token-field"; import type { ComboboxControlOption } from "../ui/combobox-control"; import { Controller, useFormContext } from 'react-hook-form'; import { useValueSetServiceContext, IValueSet } from '../../services'; import { debounce } from 'lodash'; interface UcumUnitSearchProps { label: string; context: string; multiple?: boolean; required?: boolean; disabled?: boolean; placeholder?: string; helperText?: string; } interface UcumApiResponse { total: number; results: IValueSet[]; } const UcumUnitSearch: React.FC = ({ label, context, multiple = true, required = false, disabled = false, placeholder = 'Search for units...' }) => { const { control } = useFormContext(); const [options, setOptions] = useState([]); const [loading, setLoading] = useState(false); const { fetchUnit } = useValueSetServiceContext(); const debouncedSearch = useCallback(debounce(async (term: string) => { if (!term) { setOptions([]); return; } setLoading(true); try { const response: UcumApiResponse = await fetchUnit(term); if (response && response.results) { setOptions(response.results); } else { setOptions([]); } } catch (error) { console.error('Error fetching units:', error); setOptions([]); } finally { setLoading(false); } }, 300), [fetchUnit]); const handleSearchChange = (term: string) => { debouncedSearch(term); }; useEffect(() => { setOptions([]); }, [context]); useEffect(() => { return () => { debouncedSearch.cancel(); }; }, [debouncedSearch]); return ( { if (multiple) { const tokenValues = Array.isArray(field.value) ? field.value.map(item => item.code) : []; return ( <> option.code)} onChange={(tokens: (string | TokenItem)[]) => { const unitObjects = tokens.map(token => { const tokenStr = typeof token === 'string' ? token : token.value; const unitOption = options.find(option => option.code === tokenStr); return unitOption || { system: "http://unitsofmeasure.org", code: tokenStr, display: tokenStr }; }); field.onChange(unitObjects); }} onInputChange={handleSearchChange} disabled={disabled} placeholder={placeholder}/> {loading && } ); } const selectedOption: string = field.value ? field.value.code : undefined; if (selectedOption && options.length === 0) { handleSearchChange(selectedOption); } const comboboxOptions: ComboboxControlOption[] = options.map(option => ({ value: option.code, label: `${option.code} - ${option.display}` })); return ( <> { const selectedOption = options.find(option => option.code === value); field.onChange(selectedOption); }} onFilterValueChange={handleSearchChange} placeholder={placeholder}/> ); }}/> ); }; export default UcumUnitSearch;