mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-18 04:25:57 +08:00
feat: add custom orderBy (#2975)
* feat: add custom orderBy * chore: magic string is removed --------- Co-authored-by: Vishal Sharma <makeavish786@gmail.com> Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
3464b2a59c
commit
0f998a4845
@ -1,6 +1,8 @@
|
|||||||
import { Select, Spin } from 'antd';
|
import { Select, Spin } from 'antd';
|
||||||
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
|
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
|
||||||
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
||||||
|
import { IOption } from 'hooks/useResourceAttribute/types';
|
||||||
|
import { uniqWith } from 'lodash-es';
|
||||||
import * as Papa from 'papaparse';
|
import * as Papa from 'papaparse';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
@ -9,6 +11,7 @@ import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
|
|||||||
|
|
||||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||||
import { getRemoveOrderFromValue } from '../QueryBuilderSearch/utils';
|
import { getRemoveOrderFromValue } from '../QueryBuilderSearch/utils';
|
||||||
|
import { FILTERS } from './config';
|
||||||
import { OrderByFilterProps } from './OrderByFilter.interfaces';
|
import { OrderByFilterProps } from './OrderByFilter.interfaces';
|
||||||
import {
|
import {
|
||||||
checkIfKeyPresent,
|
checkIfKeyPresent,
|
||||||
@ -22,7 +25,7 @@ export function OrderByFilter({
|
|||||||
onChange,
|
onChange,
|
||||||
}: OrderByFilterProps): JSX.Element {
|
}: OrderByFilterProps): JSX.Element {
|
||||||
const [searchText, setSearchText] = useState<string>('');
|
const [searchText, setSearchText] = useState<string>('');
|
||||||
const [selectedValue, setSelectedValue] = useState<string[]>([]);
|
const [selectedValue, setSelectedValue] = useState<IOption[]>([]);
|
||||||
|
|
||||||
const { data, isFetching } = useQuery(
|
const { data, isFetching } = useQuery(
|
||||||
[QueryBuilderKeys.GET_AGGREGATE_KEYS, searchText],
|
[QueryBuilderKeys.GET_AGGREGATE_KEYS, searchText],
|
||||||
@ -55,23 +58,41 @@ export function OrderByFilter({
|
|||||||
.flat()
|
.flat()
|
||||||
.concat([
|
.concat([
|
||||||
{
|
{
|
||||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) asc`,
|
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) ${FILTERS.ASC}`,
|
||||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}asc`,
|
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}${FILTERS.ASC}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) desc`,
|
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) ${FILTERS.DESC}`,
|
||||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}desc`,
|
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}${FILTERS.DESC}`,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
[query.aggregateAttribute.key, query.aggregateOperator, query.groupBy],
|
[query.aggregateAttribute.key, query.aggregateOperator, query.groupBy],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const customValue: IOption[] = useMemo(() => {
|
||||||
|
if (!searchText) return [];
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: `${searchText} ${FILTERS.ASC}`,
|
||||||
|
value: `${searchText}${orderByValueDelimiter}${FILTERS.ASC}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `${searchText} ${FILTERS.DESC}`,
|
||||||
|
value: `${searchText}${orderByValueDelimiter}${FILTERS.DESC}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}, [searchText]);
|
||||||
|
|
||||||
const optionsData = useMemo(() => {
|
const optionsData = useMemo(() => {
|
||||||
const options =
|
const options =
|
||||||
query.aggregateOperator === MetricAggregateOperator.NOOP
|
query.aggregateOperator === MetricAggregateOperator.NOOP
|
||||||
? noAggregationOptions
|
? noAggregationOptions
|
||||||
: aggregationOptions;
|
: aggregationOptions;
|
||||||
return options.filter(
|
|
||||||
|
const resultOption = [...customValue, ...options];
|
||||||
|
|
||||||
|
return resultOption.filter(
|
||||||
(option) =>
|
(option) =>
|
||||||
!getLabelFromValue(selectedValue).includes(
|
!getLabelFromValue(selectedValue).includes(
|
||||||
getRemoveOrderFromValue(option.value),
|
getRemoveOrderFromValue(option.value),
|
||||||
@ -79,30 +100,58 @@ export function OrderByFilter({
|
|||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
aggregationOptions,
|
aggregationOptions,
|
||||||
|
customValue,
|
||||||
noAggregationOptions,
|
noAggregationOptions,
|
||||||
query.aggregateOperator,
|
query.aggregateOperator,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const handleChange = (values: string[]): void => {
|
const getUniqValues = useCallback((values: IOption[]): IOption[] => {
|
||||||
setSelectedValue(values);
|
const modifiedValues = values.map((item) => {
|
||||||
const orderByValues: OrderByPayload[] = values.map((item) => {
|
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter });
|
||||||
const match = Papa.parse(item, { delimiter: '|' });
|
if (!match) return { label: item.label, value: item.value };
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars
|
||||||
|
const [_, order] = match.data.flat() as string[];
|
||||||
|
if (order) return { label: item.label, value: item.value };
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: `${item.value} ${FILTERS.ASC}`,
|
||||||
|
value: `${item.value}${orderByValueDelimiter}${FILTERS.ASC}`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return uniqWith(
|
||||||
|
modifiedValues,
|
||||||
|
(current, next) =>
|
||||||
|
getRemoveOrderFromValue(current.value) ===
|
||||||
|
getRemoveOrderFromValue(next.value),
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleChange = (values: IOption[]): void => {
|
||||||
|
const result = getUniqValues(values);
|
||||||
|
|
||||||
|
setSelectedValue(result);
|
||||||
|
const orderByValues: OrderByPayload[] = result.map((item) => {
|
||||||
|
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter });
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
const [columnName, order] = match.data.flat() as string[];
|
const [columnName, order] = match.data.flat() as string[];
|
||||||
return {
|
return {
|
||||||
columnName: checkIfKeyPresent(columnName, query.aggregateAttribute.key)
|
columnName: checkIfKeyPresent(columnName, query.aggregateAttribute.key)
|
||||||
? '#SIGNOZ_VALUE'
|
? '#SIGNOZ_VALUE'
|
||||||
: columnName,
|
: columnName,
|
||||||
order,
|
order: order ?? 'asc',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columnName: item,
|
columnName: item.value,
|
||||||
order: '',
|
order: 'asc',
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setSearchText('');
|
||||||
onChange(orderByValues);
|
onChange(orderByValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -126,6 +175,8 @@ export function OrderByFilter({
|
|||||||
showSearch
|
showSearch
|
||||||
disabled={isMetricsDataSource && isDisabledSelect}
|
disabled={isMetricsDataSource && isDisabledSelect}
|
||||||
showArrow={false}
|
showArrow={false}
|
||||||
|
value={selectedValue}
|
||||||
|
labelInValue
|
||||||
filterOption={false}
|
filterOption={false}
|
||||||
options={optionsData}
|
options={optionsData}
|
||||||
notFoundContent={isFetching ? <Spin size="small" /> : null}
|
notFoundContent={isFetching ? <Spin size="small" /> : null}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
export const FILTERS = {
|
||||||
|
ASC: 'asc',
|
||||||
|
DESC: 'desc',
|
||||||
|
};
|
@ -2,9 +2,18 @@ import { IOption } from 'hooks/useResourceAttribute/types';
|
|||||||
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
|
import { transformStringWithPrefix } from 'lib/query/transformStringWithPrefix';
|
||||||
import * as Papa from 'papaparse';
|
import * as Papa from 'papaparse';
|
||||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
|
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
|
|
||||||
export const orderByValueDelimiter = '|';
|
export const orderByValueDelimiter = '|';
|
||||||
|
|
||||||
|
export const transformToOrderByStringValues = (
|
||||||
|
orderBy: OrderByPayload[],
|
||||||
|
): IOption[] =>
|
||||||
|
orderBy.map((item) => ({
|
||||||
|
label: `${item.columnName} ${item.order}`,
|
||||||
|
value: `${item.columnName}${orderByValueDelimiter}${item.order}`,
|
||||||
|
}));
|
||||||
|
|
||||||
export function mapLabelValuePairs(
|
export function mapLabelValuePairs(
|
||||||
arr: BaseAutocompleteData[],
|
arr: BaseAutocompleteData[],
|
||||||
): Array<IOption>[] {
|
): Array<IOption>[] {
|
||||||
@ -28,14 +37,15 @@ export function mapLabelValuePairs(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLabelFromValue(arr: string[]): string[] {
|
export function getLabelFromValue(arr: IOption[]): string[] {
|
||||||
return arr.flat().map((item) => {
|
return arr.flat().map((item) => {
|
||||||
const match = Papa.parse(item, { delimiter: orderByValueDelimiter });
|
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter });
|
||||||
if (match) {
|
if (match) {
|
||||||
const [key] = match.data as string[];
|
const [key] = match.data as string[];
|
||||||
return key[0];
|
return key[0];
|
||||||
}
|
}
|
||||||
return item;
|
|
||||||
|
return item.value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user