feat: add autofill autocomplete data from response (#3092)

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Yevhen Shevchenko 2023-07-11 11:24:10 +03:00 committed by GitHub
parent 652bd52ea7
commit cc62d2cf71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 38 deletions

View File

@ -3,6 +3,7 @@ import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider';
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields'; import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName'; import { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
import { import {
AutocompleteType,
BaseAutocompleteData, BaseAutocompleteData,
LocalDataType, LocalDataType,
} from 'types/api/queryBuilder/queryAutocompleteResponse'; } from 'types/api/queryBuilder/queryAutocompleteResponse';
@ -50,6 +51,11 @@ export const baseAutoCompleteIdKeysOrder: (keyof Omit<
'id' 'id'
>)[] = ['key', 'dataType', 'type', 'isColumn']; >)[] = ['key', 'dataType', 'type', 'isColumn'];
export const autocompleteType: Record<AutocompleteType, AutocompleteType> = {
resource: 'resource',
tag: 'tag',
};
export const formulasNames: string[] = Array.from( export const formulasNames: string[] = Array.from(
Array(MAX_FORMULAS), Array(MAX_FORMULAS),
(_, i) => `F${i + 1}`, (_, i) => `F${i + 1}`,

View File

@ -3,3 +3,5 @@ export const FORMULA_REGEXP = /F\d+/;
export const HAVING_FILTER_REGEXP = /^[-\d.,\s]+$/; export const HAVING_FILTER_REGEXP = /^[-\d.,\s]+$/;
export const TYPE_ADDON_REGEXP = /_(.+)/; export const TYPE_ADDON_REGEXP = /_(.+)/;
export const SPLIT_FIRST_UNDERSCORE = /(?<!^)_/;

View File

@ -11,6 +11,8 @@ import {
} from 'constants/queryBuilder'; } from 'constants/queryBuilder';
import useDebounce from 'hooks/useDebounce'; import useDebounce from 'hooks/useDebounce';
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields'; import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
import { getAutocompleteValueAndType } from 'lib/newQueryBuilder/getAutocompleteValueAndType';
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix'; import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
import { memo, useCallback, useMemo, useState } from 'react'; import { memo, useCallback, useMemo, useState } from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
@ -33,7 +35,27 @@ export const AggregatorFilter = memo(function AggregatorFilter({
onChange, onChange,
}: AgregatorFilterProps): JSX.Element { }: AgregatorFilterProps): JSX.Element {
const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]); const [optionsData, setOptionsData] = useState<ExtendedSelectOption[]>([]);
const debouncedValue = useDebounce(query.aggregateAttribute.key, 300); const [searchText, setSearchText] = useState<string>(
query.aggregateAttribute.key,
);
const handleChangeAttribute = useCallback(
(data: BaseAutocompleteData[]) => {
const attribute = chooseAutocompleteFromCustomValue(data, [searchText]);
onChange(attribute[0]);
},
[onChange, searchText],
);
const debouncedSearchText = useMemo(() => {
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars
const [_, value] = getAutocompleteValueAndType(searchText);
return value;
}, [searchText]);
const debouncedValue = useDebounce(debouncedSearchText, 300);
const { isFetching } = useQuery( const { isFetching } = useQuery(
[ [
QueryBuilderKeys.GET_AGGREGATE_ATTRIBUTE, QueryBuilderKeys.GET_AGGREGATE_ATTRIBUTE,
@ -64,13 +86,23 @@ export const AggregatorFilter = memo(function AggregatorFilter({
key: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder), key: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder),
})) || []; })) || [];
handleChangeAttribute(data.payload?.attributeKeys || []);
setOptionsData(options); setOptionsData(options);
}, },
}, },
); );
const handleChangeAttribute = useCallback( const handleSearchText = useCallback((text: string): void => {
( setSearchText(text);
}, []);
const placeholder: string =
query.dataSource === DataSource.METRICS
? `${transformToUpperCase(query.dataSource)} name`
: 'Aggregate attribute';
const handleSelect = (
value: string, value: string,
option: ExtendedSelectOption | ExtendedSelectOption[], option: ExtendedSelectOption | ExtendedSelectOption[],
): void => { ): void => {
@ -85,41 +117,45 @@ export const AggregatorFilter = memo(function AggregatorFilter({
isColumn: isColumn === 'true', isColumn: isColumn === 'true',
}; };
const text = transformStringWithPrefix({
str: attribute.key,
prefix: attribute.type || '',
condition: !attribute.isColumn,
});
setSearchText(text);
onChange(attribute); onChange(attribute);
} else { } else {
const attribute = { ...initialAutocompleteData, key: value }; const customAttribute: BaseAutocompleteData = {
...initialAutocompleteData,
key: value,
};
onChange(attribute); const text = transformStringWithPrefix({
str: customAttribute.key,
prefix: customAttribute.type || '',
condition: !customAttribute.isColumn,
});
setSearchText(text);
onChange(customAttribute);
} }
}, };
[onChange],
);
const value = useMemo(
() =>
transformStringWithPrefix({
str: query.aggregateAttribute.key,
prefix: query.aggregateAttribute.type || '',
condition: !query.aggregateAttribute.isColumn,
}),
[query],
);
const placeholder: string =
query.dataSource === DataSource.METRICS
? `${transformToUpperCase(query.dataSource)} name`
: 'Aggregate attribute';
return ( return (
<AutoComplete <AutoComplete
placeholder={placeholder} placeholder={placeholder}
style={selectStyle} style={selectStyle}
showArrow={false} showArrow={false}
searchValue={searchText}
onSearch={handleSearchText}
filterOption={false} filterOption={false}
notFoundContent={isFetching ? <Spin size="small" /> : null} notFoundContent={isFetching ? <Spin size="small" /> : null}
options={optionsData} options={optionsData}
value={value} value={searchText}
onChange={handleChangeAttribute} onSelect={handleSelect}
disabled={disabled} disabled={disabled}
/> />
); );

View File

@ -0,0 +1,19 @@
import { initialAutocompleteData } from 'constants/queryBuilder';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
export const chooseAutocompleteFromCustomValue = (
sourceList: BaseAutocompleteData[],
values: string[],
): BaseAutocompleteData[] => {
console.log({ sourceList });
return values.map((value) => {
const firstBaseAutoCompleteValue = sourceList.find(
(sourceAutoComplete) => value === sourceAutoComplete.key,
);
if (!firstBaseAutoCompleteValue)
return { ...initialAutocompleteData, key: value };
return firstBaseAutoCompleteValue;
});
};

View File

@ -0,0 +1,17 @@
import { autocompleteType } from 'constants/queryBuilder';
import { SPLIT_FIRST_UNDERSCORE } from 'constants/regExp';
export const getAutocompleteValueAndType = (str: string): [string, string] => {
if (str === '') return [str, str];
const [firstValue, secondValue] = str.split(SPLIT_FIRST_UNDERSCORE);
if (
firstValue === autocompleteType.tag ||
firstValue === autocompleteType.resource
) {
return [firstValue, secondValue];
}
return ['', firstValue];
};