Untitled
unknown
typescript
2 years ago
3.2 kB
11
Indexable
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}
/>
);
}Editor is loading...