mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-16 09:05:54 +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 { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
|
||||
import { QueryBuilderKeys } from 'constants/queryBuilder';
|
||||
import { IOption } from 'hooks/useResourceAttribute/types';
|
||||
import { uniqWith } from 'lodash-es';
|
||||
import * as Papa from 'papaparse';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
@ -9,6 +11,7 @@ import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
|
||||
|
||||
import { selectStyle } from '../QueryBuilderSearch/config';
|
||||
import { getRemoveOrderFromValue } from '../QueryBuilderSearch/utils';
|
||||
import { FILTERS } from './config';
|
||||
import { OrderByFilterProps } from './OrderByFilter.interfaces';
|
||||
import {
|
||||
checkIfKeyPresent,
|
||||
@ -22,7 +25,7 @@ export function OrderByFilter({
|
||||
onChange,
|
||||
}: OrderByFilterProps): JSX.Element {
|
||||
const [searchText, setSearchText] = useState<string>('');
|
||||
const [selectedValue, setSelectedValue] = useState<string[]>([]);
|
||||
const [selectedValue, setSelectedValue] = useState<IOption[]>([]);
|
||||
|
||||
const { data, isFetching } = useQuery(
|
||||
[QueryBuilderKeys.GET_AGGREGATE_KEYS, searchText],
|
||||
@ -55,23 +58,41 @@ export function OrderByFilter({
|
||||
.flat()
|
||||
.concat([
|
||||
{
|
||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) asc`,
|
||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}asc`,
|
||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) ${FILTERS.ASC}`,
|
||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}${FILTERS.ASC}`,
|
||||
},
|
||||
{
|
||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) desc`,
|
||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}desc`,
|
||||
label: `${query.aggregateOperator}(${query.aggregateAttribute.key}) ${FILTERS.DESC}`,
|
||||
value: `${query.aggregateOperator}(${query.aggregateAttribute.key})${orderByValueDelimiter}${FILTERS.DESC}`,
|
||||
},
|
||||
]),
|
||||
[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 options =
|
||||
query.aggregateOperator === MetricAggregateOperator.NOOP
|
||||
? noAggregationOptions
|
||||
: aggregationOptions;
|
||||
return options.filter(
|
||||
|
||||
const resultOption = [...customValue, ...options];
|
||||
|
||||
return resultOption.filter(
|
||||
(option) =>
|
||||
!getLabelFromValue(selectedValue).includes(
|
||||
getRemoveOrderFromValue(option.value),
|
||||
@ -79,30 +100,58 @@ export function OrderByFilter({
|
||||
);
|
||||
}, [
|
||||
aggregationOptions,
|
||||
customValue,
|
||||
noAggregationOptions,
|
||||
query.aggregateOperator,
|
||||
selectedValue,
|
||||
]);
|
||||
|
||||
const handleChange = (values: string[]): void => {
|
||||
setSelectedValue(values);
|
||||
const orderByValues: OrderByPayload[] = values.map((item) => {
|
||||
const match = Papa.parse(item, { delimiter: '|' });
|
||||
const getUniqValues = useCallback((values: IOption[]): IOption[] => {
|
||||
const modifiedValues = values.map((item) => {
|
||||
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter });
|
||||
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) {
|
||||
const [columnName, order] = match.data.flat() as string[];
|
||||
return {
|
||||
columnName: checkIfKeyPresent(columnName, query.aggregateAttribute.key)
|
||||
? '#SIGNOZ_VALUE'
|
||||
: columnName,
|
||||
order,
|
||||
order: order ?? 'asc',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
columnName: item,
|
||||
order: '',
|
||||
columnName: item.value,
|
||||
order: 'asc',
|
||||
};
|
||||
});
|
||||
|
||||
setSearchText('');
|
||||
onChange(orderByValues);
|
||||
};
|
||||
|
||||
@ -126,6 +175,8 @@ export function OrderByFilter({
|
||||
showSearch
|
||||
disabled={isMetricsDataSource && isDisabledSelect}
|
||||
showArrow={false}
|
||||
value={selectedValue}
|
||||
labelInValue
|
||||
filterOption={false}
|
||||
options={optionsData}
|
||||
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 * as Papa from 'papaparse';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { OrderByPayload } from 'types/api/queryBuilder/queryBuilderData';
|
||||
|
||||
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(
|
||||
arr: BaseAutocompleteData[],
|
||||
): 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) => {
|
||||
const match = Papa.parse(item, { delimiter: orderByValueDelimiter });
|
||||
const match = Papa.parse(item.value, { delimiter: orderByValueDelimiter });
|
||||
if (match) {
|
||||
const [key] = match.data as string[];
|
||||
return key[0];
|
||||
}
|
||||
return item;
|
||||
|
||||
return item.value;
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user