Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 66x 66x 51x 48x 48x 48x 48x 48x 48x 48x 48x 48x 48x 48x 24x 24x 8x 16x 12x 48x 64x | import React, { CSSProperties, ReactElement, useEffect, useState } from 'react';
import { Select, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import { EnumMetaProps } from "@props/RecordProps";
import { getReadOnlyClass } from '@utils/ComponentUtils';
import { SuffixIcon, ErrorBoundary } from '../../components';
import { getEnumLabelFromCache } from "@utils/EnumUtils";
const { Option } = Select;
export interface EnumSelectProps {
type: string;
mode?: "tags" | "multiple";
placeholder: string;
notFoundContent: string;
value?: string | { enumType: string; name: string };
style?: CSSProperties | undefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onSelect?: any;
updatable?: boolean;
onChange?: (e: string) => void;
options?: Array<EnumMetaProps>;
}
const EnumSelect = (props: EnumSelectProps): ReactElement => {
const {
type, mode, placeholder, value,
notFoundContent, updatable, options
} = props;
const { t } = useTranslation();
const [data, setData] = useState<Array<EnumMetaProps>>([] as Array<EnumMetaProps>);
const [fetching, setFetching] = useState<boolean>(false);
const disabled = (updatable == null) ? false : !updatable;
const enumName = (typeof value === 'string') ? value : value?.name;
function removeUpdatableAttribute(): EnumSelectProps {
const propsToSelect = {} as EnumSelectProps;
Object.assign(propsToSelect, props);
delete propsToSelect.updatable;
return propsToSelect;
}
const propsToSelect = removeUpdatableAttribute();
useEffect(() => {
setFetching(true);
if (options != null) {
setData(options);
} else if (data?.length === 0) {
getEnumLabelFromCache(type).then(setData);
}
}, [type, options, data]);
// **** Attention ****
// zIndex of the select dropdown should higher than the zIndex of modal(by
// default 1051) because the dropdown might be displayed on a modal
// https://stackoverflow.com/questions/53926911/antd-select-not-working-inside-a-full-screen-dialog
// Set in App.less by .ant-select-dropdown
return (
<ErrorBoundary>
<Select
{...propsToSelect}
mode={mode}
showSearch
disabled={disabled}
value={enumName}
placeholder={t(placeholder)}
defaultActiveFirstOption={true}
showArrow={true}
notFoundContent={fetching ? <Spin size="small" /> : notFoundContent}
dropdownMatchSelectWidth={true}
optionFilterProp="children"
dropdownStyle={{ zIndex: 2000 }}
filterOption={(input, option) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (option == null || option.value == null || input == null) {
return false;
}
const il = input.toLowerCase();
const validOption = ('children' in option) ?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
(option.children.toLowerCase().indexOf(il) >= 0 || option.label?.toLowerCase()?.indexOf(il) >= 0) :
(option.value.toLowerCase().indexOf(il) >= 0 || option.label?.toLowerCase()?.indexOf(il) >= 0);
return validOption;
}}
className={`enum ${getReadOnlyClass(updatable)}`}
suffixIcon={<SuffixIcon updatable={updatable} />}
allowClear={true}
>
{data?.map(d => <Option key={d.value} value={d.value}>{d.label}</Option>)}
</Select>
</ErrorBoundary>
);
};
export default EnumSelect;
|