From cc62d2cf71291d84a19da9ad1d2461909c35eb8d Mon Sep 17 00:00:00 2001 From: Yevhen Shevchenko <90138953+yeshev@users.noreply.github.com> Date: Tue, 11 Jul 2023 11:24:10 +0300 Subject: [PATCH] feat: add autofill autocomplete data from response (#3092) Co-authored-by: Palash Gupta --- frontend/src/constants/queryBuilder.ts | 6 + frontend/src/constants/regExp.ts | 2 + .../AggregatorFilter/AggregatorFilter.tsx | 112 ++++++++++++------ .../chooseAutocompleteFromCustomValue.ts | 19 +++ .../getAutocompleteValueAndType.ts | 17 +++ 5 files changed, 118 insertions(+), 38 deletions(-) create mode 100644 frontend/src/lib/newQueryBuilder/chooseAutocompleteFromCustomValue.ts create mode 100644 frontend/src/lib/newQueryBuilder/getAutocompleteValueAndType.ts diff --git a/frontend/src/constants/queryBuilder.ts b/frontend/src/constants/queryBuilder.ts index 8db0f7d297..26cc32d3c4 100644 --- a/frontend/src/constants/queryBuilder.ts +++ b/frontend/src/constants/queryBuilder.ts @@ -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 = { + resource: 'resource', + tag: 'tag', +}; + export const formulasNames: string[] = Array.from( Array(MAX_FORMULAS), (_, i) => `F${i + 1}`, diff --git a/frontend/src/constants/regExp.ts b/frontend/src/constants/regExp.ts index 3ea1e3179c..40de740221 100644 --- a/frontend/src/constants/regExp.ts +++ b/frontend/src/constants/regExp.ts @@ -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 = /(?([]); - const debouncedValue = useDebounce(query.aggregateAttribute.key, 300); + const [searchText, setSearchText] = useState( + 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 ( : null} options={optionsData} - value={value} - onChange={handleChangeAttribute} + value={searchText} + onSelect={handleSelect} disabled={disabled} /> ); diff --git a/frontend/src/lib/newQueryBuilder/chooseAutocompleteFromCustomValue.ts b/frontend/src/lib/newQueryBuilder/chooseAutocompleteFromCustomValue.ts new file mode 100644 index 0000000000..1834822c6d --- /dev/null +++ b/frontend/src/lib/newQueryBuilder/chooseAutocompleteFromCustomValue.ts @@ -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; + }); +}; diff --git a/frontend/src/lib/newQueryBuilder/getAutocompleteValueAndType.ts b/frontend/src/lib/newQueryBuilder/getAutocompleteValueAndType.ts new file mode 100644 index 0000000000..bbc7c8fcfe --- /dev/null +++ b/frontend/src/lib/newQueryBuilder/getAutocompleteValueAndType.ts @@ -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]; +};