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 { createNewBuilderItemName } from 'lib/newQueryBuilder/createNewBuilderItemName';
import {
AutocompleteType,
BaseAutocompleteData,
LocalDataType,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
@ -50,6 +51,11 @@ export const baseAutoCompleteIdKeysOrder: (keyof Omit<
'id'
>)[] = ['key', 'dataType', 'type', 'isColumn'];
export const autocompleteType: Record<AutocompleteType, AutocompleteType> = {
resource: 'resource',
tag: 'tag',
};
export const formulasNames: string[] = Array.from(
Array(MAX_FORMULAS),
(_, 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 TYPE_ADDON_REGEXP = /_(.+)/;
export const SPLIT_FIRST_UNDERSCORE = /(?<!^)_/;

View File

@ -11,6 +11,8 @@ import {
} from 'constants/queryBuilder';
import useDebounce from 'hooks/useDebounce';
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
import { getAutocompleteValueAndType } from 'lib/newQueryBuilder/getAutocompleteValueAndType';
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
import { memo, useCallback, useMemo, useState } from 'react';
import { useQuery } from 'react-query';
@ -33,7 +35,27 @@ export const AggregatorFilter = memo(function AggregatorFilter({
onChange,
}: AgregatorFilterProps): JSX.Element {
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(
[
QueryBuilderKeys.GET_AGGREGATE_ATTRIBUTE,
@ -64,62 +86,76 @@ export const AggregatorFilter = memo(function AggregatorFilter({
key: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder),
})) || [];
handleChangeAttribute(data.payload?.attributeKeys || []);
setOptionsData(options);
},
},
);
const handleChangeAttribute = useCallback(
(
value: string,
option: ExtendedSelectOption | ExtendedSelectOption[],
): void => {
const currentOption = option as ExtendedSelectOption;
if (currentOption.key) {
const [key, dataType, type, isColumn] = currentOption.key.split(idDivider);
const attribute: BaseAutocompleteData = {
key,
dataType: dataType as DataType,
type: type as AutocompleteType,
isColumn: isColumn === 'true',
};
onChange(attribute);
} else {
const attribute = { ...initialAutocompleteData, key: value };
onChange(attribute);
}
},
[onChange],
);
const value = useMemo(
() =>
transformStringWithPrefix({
str: query.aggregateAttribute.key,
prefix: query.aggregateAttribute.type || '',
condition: !query.aggregateAttribute.isColumn,
}),
[query],
);
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,
option: ExtendedSelectOption | ExtendedSelectOption[],
): void => {
const currentOption = option as ExtendedSelectOption;
if (currentOption.key) {
const [key, dataType, type, isColumn] = currentOption.key.split(idDivider);
const attribute: BaseAutocompleteData = {
key,
dataType: dataType as DataType,
type: type as AutocompleteType,
isColumn: isColumn === 'true',
};
const text = transformStringWithPrefix({
str: attribute.key,
prefix: attribute.type || '',
condition: !attribute.isColumn,
});
setSearchText(text);
onChange(attribute);
} else {
const customAttribute: BaseAutocompleteData = {
...initialAutocompleteData,
key: value,
};
const text = transformStringWithPrefix({
str: customAttribute.key,
prefix: customAttribute.type || '',
condition: !customAttribute.isColumn,
});
setSearchText(text);
onChange(customAttribute);
}
};
return (
<AutoComplete
placeholder={placeholder}
style={selectStyle}
showArrow={false}
searchValue={searchText}
onSearch={handleSearchText}
filterOption={false}
notFoundContent={isFetching ? <Spin size="small" /> : null}
options={optionsData}
value={value}
onChange={handleChangeAttribute}
value={searchText}
onSelect={handleSelect}
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];
};