feat: Allows new values for single value filters (#24388)

This commit is contained in:
Michael S. Molina 2023-06-15 17:27:42 -03:00 committed by GitHub
parent 892de8a232
commit dc042c6c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 31 deletions

View File

@ -21,7 +21,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
AppSection,
DataMask,
DataRecordValue,
ensureIsArray,
ExtraFormData,
GenericDataType,
@ -36,7 +35,7 @@ import debounce from 'lodash/debounce';
import { useImmerReducer } from 'use-immer';
import { Select } from 'src/components';
import { SLOW_DEBOUNCE } from 'src/constants';
import { propertyComparator } from 'src/components/Select/utils';
import { hasOption, propertyComparator } from 'src/components/Select/utils';
import { FilterBarOrientation } from 'src/dashboard/types';
import { uniqWith, isEqual } from 'lodash';
import { PluginFilterSelectProps, SelectValue } from './types';
@ -109,6 +108,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
);
const [col] = groupby;
const [initialColtypeMap] = useState(coltypeMap);
const [search, setSearch] = useState('');
const [dataMask, dispatchDataMask] = useImmerReducer(reducer, {
extraFormData: {},
filterState,
@ -168,29 +168,25 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
const isDisabled =
appSection === AppSection.FILTER_CONFIG_MODAL && defaultToFirstItem;
const debouncedOwnStateFunc = useCallback(
debounce((val: string) => {
dispatchDataMask({
type: 'ownState',
ownState: {
coltypeMap: initialColtypeMap,
search: val,
},
});
}, SLOW_DEBOUNCE),
[],
);
const searchWrapper = useCallback(
(val: string) => {
if (searchAllOptions) {
debouncedOwnStateFunc(val);
}
},
[debouncedOwnStateFunc, searchAllOptions],
const onSearch = useMemo(
() =>
debounce((search: string) => {
setSearch(search);
if (searchAllOptions) {
dispatchDataMask({
type: 'ownState',
ownState: {
coltypeMap: initialColtypeMap,
search,
},
});
}
}, SLOW_DEBOUNCE),
[dispatchDataMask, initialColtypeMap, searchAllOptions],
);
const clearSuggestionSearch = useCallback(() => {
setSearch('');
if (searchAllOptions) {
dispatchDataMask({
type: 'ownState',
@ -236,20 +232,29 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
return undefined;
}, [filterState.validateMessage, filterState.validateStatus]);
const options = useMemo(() => {
const uniqueOptions = useMemo(() => {
const allOptions = [...data];
const uniqueOptions = uniqWith(allOptions, isEqual);
const selectOptions: { label: string; value: DataRecordValue }[] = [];
uniqueOptions.forEach(row => {
return uniqWith(allOptions, isEqual).map(row => {
const [value] = groupby.map(col => row[col]);
selectOptions.push({
return {
label: labelFormatter(value, datatype),
value,
});
isNewOption: false,
};
});
return selectOptions;
}, [data, datatype, groupby, labelFormatter]);
const options = useMemo(() => {
if (search && !multiSelect && !hasOption(search, uniqueOptions, true)) {
uniqueOptions.unshift({
label: search,
value: search,
isNewOption: true,
});
}
return uniqueOptions;
}, [multiSelect, search, uniqueOptions]);
const sortComparator = useCallback(
(a: AntdLabeledValue, b: AntdLabeledValue) => {
const labelComparator = propertyComparator('label');
@ -317,7 +322,7 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
showSearch={showSearch}
mode={multiSelect ? 'multiple' : 'single'}
placeholder={placeholderText}
onSearch={searchWrapper}
onSearch={onSearch}
onSelect={clearSuggestionSearch}
onBlur={handleBlur}
onFocus={setFocusedFilter}
@ -329,7 +334,6 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
loading={isRefreshing}
oneLine={filterBarOrientation === FilterBarOrientation.HORIZONTAL}
invertSelection={inverseSelection}
// @ts-ignore
options={options}
sortComparator={sortComparator}
onDropdownVisibleChange={setFilterActive}