Untitled
typescript
11 days ago
3.2 kB
1
Indexable
Never
import { Select, SelectProps, Spin } from "antd"; import { DefaultOptionType } from "antd/lib/select"; import { debounce, rest } from "lodash"; import { useEffect, useState } from "react"; import { QueryParamsType } from "types/common/RequestType"; import { filterOption } from "utils/select-options"; interface SelectAsyncFetchDataProps { queryParams?: QueryParamsType; columnsToSearch?: Array<string>; } export interface SelectAsyncProps extends SelectProps { fetchData: (props: SelectAsyncFetchDataProps) => Promise<any>; fetchItem?: (itemId: string) => Promise<any>; fieldsLabel: string[]; columnsToSearch: string[]; propInValue?: string; selectValue?: string | string[]; } const ITEMS_PER_PAGE = "20"; function optionLabelFormatter(option: any, fieldsLabel: string[]) { if (fieldsLabel.length > 1) { const label = fieldsLabel.map(field => option[field]); return label.join(" - ") } else { const [field] = fieldsLabel; return option[field]; } } function generateOptions(data: any, fieldsLabel: string[], propInValue?: string) { const optionsFormatted = data.map(option => { return { value: propInValue ? option[propInValue] ?? "" : option.uuid, label: optionLabelFormatter(option, fieldsLabel) } }); return optionsFormatted; } export function SelectAsync({ fetchData, fetchItem, fieldsLabel, columnsToSearch, propInValue, selectValue, ...props }: SelectAsyncProps) { const [options, setOptions] = useState<DefaultOptionType[]>([]); const [optionsIsLoading, setOptionsIsLoading] = useState<boolean>(false); useEffect(() => { if (selectValue && !propInValue && fetchItem) { // tem que ter selectValue (array ou não), não pode ser propInValue (o fetch não funciona se for propInValue porque não é o UUID) setOptionsIsLoading(true); if (Array.isArray(selectValue)) { Promise.all(selectValue.map(itemToFetch => fetchItem(itemToFetch))).then(responses => { const optionsFormatted = generateOptions([...responses], fieldsLabel); setOptions(optionsFormatted); }).catch(error => { setOptions([]); }).finally(() => { setOptionsIsLoading(false) }) return; } fetchItem(selectValue).then(response => { const optionsFormatted = generateOptions([response], fieldsLabel); setOptions(optionsFormatted); }).catch(error => { setOptions([]); }).finally(() => { setOptionsIsLoading(false); }); } }, [JSON.stringify(selectValue)]); return ( <Select value={selectValue} placeholder={"Selecione uma opção"} showSearch allowClear filterOption={false} onSearch={() => { }} onClear={() => { }} options={options} loading={optionsIsLoading} notFoundContent={optionsIsLoading ? <Spin size="small" /> : "Nenhum resultado encontrado"} defaultActiveFirstOption={false} {...selectValue && Array.isArray(selectValue) && { mode: "multiple" }} {...props} /> ); }