Skip to content

Commit dea22d1

Browse files
authored
feat: save sorting columns in queries (#2234)
1 parent c0b3efe commit dea22d1

File tree

6 files changed

+170
-49
lines changed

6 files changed

+170
-49
lines changed

src/containers/Tenant/Diagnostics/TopQueries/RunningQueriesData.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ import {
2222
RUNNING_QUERIES_COLUMNS_WIDTH_LS_KEY,
2323
RUNNING_QUERIES_SELECTED_COLUMNS_LS_KEY,
2424
} from './columns/constants';
25+
import {useRunningQueriesSort} from './hooks/useRunningQueriesSort';
2526
import i18n from './i18n';
26-
import {TOP_QUERIES_TABLE_SETTINGS, useRunningQueriesSort} from './utils';
27+
import {TOP_QUERIES_TABLE_SETTINGS} from './utils';
2728

2829
const b = cn('kv-top-queries');
2930

src/containers/Tenant/Diagnostics/TopQueries/TopQueriesData.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ import {
2626
TOP_QUERIES_SELECTED_COLUMNS_LS_KEY,
2727
} from './columns/constants';
2828
import {DEFAULT_TIME_FILTER_VALUE, TIME_FRAME_OPTIONS} from './constants';
29+
import {useTopQueriesSort} from './hooks/useTopQueriesSort';
2930
import i18n from './i18n';
30-
import {TOP_QUERIES_TABLE_SETTINGS, useTopQueriesSort} from './utils';
31+
import {TOP_QUERIES_TABLE_SETTINGS} from './utils';
3132

3233
const b = cn('kv-top-queries');
3334

@@ -67,6 +68,7 @@ export const TopQueriesData = ({
6768
REQUIRED_TOP_QUERIES_COLUMNS,
6869
);
6970

71+
// Use the sort params from URL in the hook
7072
const {tableSort, handleTableSort, backendSort} = useTopQueriesSort();
7173

7274
const {currentData, data, isFetching, isLoading, error} = topQueriesApi.useGetTopQueriesQuery(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React from 'react';
2+
3+
import type {SortOrder} from '@gravity-ui/react-data-table';
4+
import DataTable from '@gravity-ui/react-data-table';
5+
import {z} from 'zod';
6+
7+
import {prepareBackendSortFieldsFromTableSort, useTableSort} from '../../../../../utils/hooks';
8+
import {QUERIES_COLUMNS_IDS, getRunningQueriesColumnSortField} from '../columns/constants';
9+
10+
import {useSortParam} from './useSortParam';
11+
12+
export const runningQueriesSortColumnSchema = z
13+
.enum([
14+
QUERIES_COLUMNS_IDS.QueryStartAt,
15+
QUERIES_COLUMNS_IDS.UserSID,
16+
QUERIES_COLUMNS_IDS.ApplicationName,
17+
])
18+
.catch(QUERIES_COLUMNS_IDS.QueryStartAt);
19+
20+
export const DEFAULT_RUNNING_QUERIES_SORT: SortOrder = {
21+
columnId: QUERIES_COLUMNS_IDS.QueryStartAt,
22+
order: DataTable.DESCENDING,
23+
};
24+
25+
export function useRunningQueriesSort() {
26+
const {sortParam, updateSortParam} = useSortParam({
27+
paramName: 'runningSort',
28+
schema: runningQueriesSortColumnSchema,
29+
defaultSort: DEFAULT_RUNNING_QUERIES_SORT,
30+
});
31+
32+
const [tableSort, handleTableSort] = useTableSort({
33+
initialSortColumn: sortParam?.[0]?.columnId || DEFAULT_RUNNING_QUERIES_SORT.columnId,
34+
initialSortOrder: sortParam?.[0]?.order || DEFAULT_RUNNING_QUERIES_SORT.order,
35+
multiple: true,
36+
onSort: updateSortParam,
37+
});
38+
39+
return {
40+
tableSort,
41+
handleTableSort,
42+
backendSort: React.useMemo(
43+
() =>
44+
prepareBackendSortFieldsFromTableSort(tableSort, getRunningQueriesColumnSortField),
45+
[tableSort],
46+
),
47+
};
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
3+
import type {SortOrder} from '@gravity-ui/react-data-table';
4+
import type {QueryParamConfig} from 'use-query-params';
5+
import {useQueryParam} from 'use-query-params';
6+
import type {z} from 'zod';
7+
8+
const SortOrderParam: QueryParamConfig<SortOrder[]> = {
9+
encode: (value) => {
10+
if (value === undefined || value === null || !Array.isArray(value)) {
11+
return undefined;
12+
}
13+
14+
return encodeURIComponent(JSON.stringify(value));
15+
},
16+
decode: (value) => {
17+
if (typeof value !== 'string' || !value) {
18+
return [];
19+
}
20+
try {
21+
return JSON.parse(decodeURIComponent(value));
22+
} catch {
23+
return [];
24+
}
25+
},
26+
};
27+
28+
export function useSortParam(options: {
29+
paramName: string;
30+
schema: z.ZodType<string, any, any>;
31+
defaultSort: SortOrder;
32+
}) {
33+
const {paramName, schema, defaultSort} = options;
34+
const [urlSortParam, setUrlSortParam] = useQueryParam<SortOrder[]>(paramName, SortOrderParam);
35+
36+
const parsedUrlSort = React.useMemo(() => {
37+
if (!urlSortParam || !Array.isArray(urlSortParam) || urlSortParam.length === 0) {
38+
return [defaultSort];
39+
}
40+
41+
const validSortParams = urlSortParam.filter((sort: SortOrder) => {
42+
try {
43+
schema.parse(sort.columnId);
44+
return true;
45+
} catch {
46+
return false;
47+
}
48+
});
49+
50+
return validSortParams.length ? validSortParams : [defaultSort];
51+
}, [urlSortParam, schema, defaultSort]);
52+
53+
const updateSortParam = React.useCallback(
54+
(sortOrder?: SortOrder[]) => {
55+
// Using 'replace' instead of 'replaceIn' to ensure a full URL update
56+
// This helps prevent issues with partial URL parameter updates
57+
setUrlSortParam(sortOrder || [], 'replaceIn');
58+
},
59+
[setUrlSortParam],
60+
);
61+
62+
return {
63+
sortParam: parsedUrlSort,
64+
updateSortParam,
65+
};
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
3+
import type {SortOrder} from '@gravity-ui/react-data-table';
4+
import DataTable from '@gravity-ui/react-data-table';
5+
import {z} from 'zod';
6+
7+
import {prepareBackendSortFieldsFromTableSort, useTableSort} from '../../../../../utils/hooks';
8+
import {QUERIES_COLUMNS_IDS, getTopQueriesColumnSortField} from '../columns/constants';
9+
10+
import {useSortParam} from './useSortParam';
11+
12+
export const topQueriesSortColumnSchema = z
13+
.enum([
14+
QUERIES_COLUMNS_IDS.CPUTime,
15+
QUERIES_COLUMNS_IDS.Duration,
16+
QUERIES_COLUMNS_IDS.ReadRows,
17+
QUERIES_COLUMNS_IDS.ReadBytes,
18+
QUERIES_COLUMNS_IDS.QueryText,
19+
])
20+
.catch(QUERIES_COLUMNS_IDS.CPUTime);
21+
22+
export const DEFAULT_TOP_QUERIES_SORT: SortOrder = {
23+
columnId: QUERIES_COLUMNS_IDS.CPUTime,
24+
order: DataTable.DESCENDING,
25+
};
26+
27+
export function useTopQueriesSort() {
28+
const {sortParam, updateSortParam} = useSortParam({
29+
paramName: 'topSort',
30+
schema: topQueriesSortColumnSchema,
31+
defaultSort: DEFAULT_TOP_QUERIES_SORT,
32+
});
33+
34+
const [tableSort, handleTableSort] = useTableSort({
35+
initialSortColumn: sortParam?.[0]?.columnId || DEFAULT_TOP_QUERIES_SORT.columnId,
36+
initialSortOrder: sortParam?.[0]?.order || DEFAULT_TOP_QUERIES_SORT.order,
37+
multiple: true,
38+
fixedOrderType: DataTable.DESCENDING,
39+
onSort: updateSortParam,
40+
});
41+
42+
return {
43+
tableSort,
44+
handleTableSort,
45+
backendSort: React.useMemo(
46+
() => prepareBackendSortFieldsFromTableSort(tableSort, getTopQueriesColumnSortField),
47+
[tableSort],
48+
),
49+
};
50+
}
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,9 @@
1-
import React from 'react';
1+
import type {Settings} from '@gravity-ui/react-data-table';
22

3-
import type {Settings, SortOrder} from '@gravity-ui/react-data-table';
4-
import DataTable from '@gravity-ui/react-data-table';
5-
6-
import {prepareBackendSortFieldsFromTableSort, useTableSort} from '../../../../utils/hooks';
73
import {QUERY_TABLE_SETTINGS} from '../../utils/constants';
84

9-
import {
10-
QUERIES_COLUMNS_IDS,
11-
getRunningQueriesColumnSortField,
12-
getTopQueriesColumnSortField,
13-
} from './columns/constants';
14-
155
export const TOP_QUERIES_TABLE_SETTINGS: Settings = {
166
...QUERY_TABLE_SETTINGS,
177
disableSortReset: true,
188
externalSort: true,
199
};
20-
21-
export function useTopQueriesSort(initialSort?: SortOrder[]) {
22-
const [tableSort, handleTableSort] = useTableSort({
23-
initialSortColumn: initialSort?.[0]?.columnId || QUERIES_COLUMNS_IDS.CPUTime,
24-
initialSortOrder: initialSort?.[0]?.order || DataTable.DESCENDING,
25-
multiple: true,
26-
fixedOrderType: DataTable.DESCENDING,
27-
});
28-
29-
return {
30-
tableSort,
31-
handleTableSort,
32-
backendSort: React.useMemo(
33-
() => prepareBackendSortFieldsFromTableSort(tableSort, getTopQueriesColumnSortField),
34-
[tableSort],
35-
),
36-
};
37-
}
38-
39-
export function useRunningQueriesSort() {
40-
const [tableSort, handleTableSort] = useTableSort({
41-
initialSortColumn: QUERIES_COLUMNS_IDS.QueryStartAt,
42-
initialSortOrder: DataTable.DESCENDING,
43-
multiple: true,
44-
});
45-
46-
return {
47-
tableSort,
48-
handleTableSort,
49-
backendSort: React.useMemo(
50-
() =>
51-
prepareBackendSortFieldsFromTableSort(tableSort, getRunningQueriesColumnSortField),
52-
[tableSort],
53-
),
54-
};
55-
}

0 commit comments

Comments
 (0)