mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-06-04 11:25:52 +08:00
feat: add autofill autocomplete data from response (#3092)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
652bd52ea7
commit
cc62d2cf71
@ -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}`,
|
||||
|
@ -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 = /(?<!^)_/;
|
||||
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
@ -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;
|
||||
});
|
||||
};
|
@ -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];
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user