Skip to content

Commit 003ede3

Browse files
committed
FE: Add ability to reset pagination after filter change
1 parent adedafd commit 003ede3

File tree

10 files changed

+56
-27
lines changed

10 files changed

+56
-27
lines changed

frontend/src/components/Connect/List/List.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { useConnectors } from 'lib/hooks/api/kafkaConnect';
77
import { ColumnDef } from '@tanstack/react-table';
88
import { useNavigate, useSearchParams } from 'react-router-dom';
99
import BreakableTextCell from 'components/common/NewTable/BreakableTextCell';
10-
import { useQueryPersister } from 'components/common/NewTable/Filter/lib/persisters';
11-
import { getFilterableColumns } from 'components/common/NewTable/Filter/lib';
10+
import { useQueryPersister } from 'components/common/NewTable/Filter';
1211

1312
import ActionsCell from './ActionsCell';
1413
import TopicsCell from './TopicsCell';
@@ -60,8 +59,6 @@ const kafkaConnectColumns: ColumnDef<FullConnectorInfo>[] = [
6059
{ header: '', id: 'action', cell: ActionsCell },
6160
];
6261

63-
const filterableColumns = getFilterableColumns(kafkaConnectColumns);
64-
6562
const List: React.FC = () => {
6663
const navigate = useNavigate();
6764
const { clusterName } = useAppParams<ClusterNameRoute>();
@@ -71,7 +68,7 @@ const List: React.FC = () => {
7168
searchParams.get('q') || ''
7269
);
7370

74-
const persister = useQueryPersister(filterableColumns);
71+
const persister = useQueryPersister(kafkaConnectColumns);
7572

7673
return (
7774
<Table

frontend/src/components/common/NewTable/FIlter/Filter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as FilterVariant from './variants';
66
interface FilterProps<T> {
77
column: Column<T, unknown>;
88
}
9-
const Filter = <T,>(props: FilterProps<T>) => {
9+
export const Filter = <T,>(props: FilterProps<T>) => {
1010
const { column } = props;
1111

1212
switch (column.columnDef.meta?.filterVariant) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Filter from './Filter';
2+
3+
export { type FilterableColumnDef, type KafbatFilterVariant } from './types';
4+
export { type Persister, useQueryPersister } from './lib';
5+
6+
export default Filter;

frontend/src/components/common/NewTable/FIlter/lib/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ export {
22
getFilterableColumns,
33
isFilterableColumn,
44
} from './getFilterableColumns';
5+
6+
export { type Persister, useQueryPersister } from './persisters/index';
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { type Persister } from './Persister';
1+
export { type Persister } from './types';
22

33
export { useQueryPersister } from './queryPersister';

frontend/src/components/common/NewTable/FIlter/lib/persisters/queryPersister.ts

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
import { ColumnFilter, ColumnFiltersState } from '@tanstack/react-table';
1+
import {
2+
ColumnDef,
3+
ColumnFilter,
4+
ColumnFiltersState,
5+
noop,
6+
} from '@tanstack/react-table';
27
import { useSearchParams } from 'react-router-dom';
38
import {
49
FilterableColumnDef,
510
KafbatFilterVariant,
6-
} from 'components/common/NewTable/Filter/types';
11+
} from 'components/common/NewTable/Filter';
712
import { useCallback, useMemo } from 'react';
813

9-
import { Persister } from './Persister';
14+
import { getFilterableColumns } from '../getFilterableColumns';
15+
16+
import { Persister } from './types';
1017

1118
function getParamsByKeys(
1219
params: URLSearchParams,
@@ -19,6 +26,7 @@ function getParamsByKeys(
1926
const foundValue = params.get(key);
2027
if (foundValue) {
2128
if (variant === 'multi-select') {
29+
// Array stored to query params as string, we should recover it back to array of values
2230
acc[key] = foundValue.split(',');
2331
} else {
2432
acc[key] = foundValue;
@@ -29,6 +37,10 @@ function getParamsByKeys(
2937
{} as Record<string, string | string[]>
3038
);
3139
}
40+
// By default tanstack table replace all . in accessrorKey by _
41+
// We should normalize out filterable columns key accordingly
42+
const normalizeAccessorKey = (accessorKey: string) =>
43+
accessorKey.replace(/\./g, '_');
3244

3345
function mapColumnKeyToFilterVariant<TData, TValue>(
3446
columns: FilterableColumnDef<TData, TValue>[]
@@ -38,7 +50,8 @@ function mapColumnKeyToFilterVariant<TData, TValue>(
3850
return columns.reduce(
3951
(acc, cur) => {
4052
if (cur.meta?.filterVariant) {
41-
acc[cur.accessorKey] = cur.meta?.filterVariant;
53+
const key = normalizeAccessorKey(cur.accessorKey);
54+
acc[key] = cur.meta?.filterVariant;
4255
}
4356

4457
return acc;
@@ -56,14 +69,15 @@ function isEmptyFilterValue(columnFilter: ColumnFilter): boolean {
5669
}
5770

5871
export function useQueryPersister<TData, TValue>(
59-
columns: FilterableColumnDef<TData, TValue>[]
72+
columns: ColumnDef<TData, TValue>[]
6073
): Persister {
6174
const [searchParams, setSearchParams] = useSearchParams();
6275

63-
const keyToFilterVariant = useMemo(
64-
() => mapColumnKeyToFilterVariant(columns),
65-
[columns]
66-
);
76+
const keyToFilterVariant = useMemo(() => {
77+
const filterableColumns = getFilterableColumns(columns);
78+
79+
return mapColumnKeyToFilterVariant(filterableColumns);
80+
}, [columns]);
6781

6882
const getPrevState = useCallback(() => {
6983
const filterParams = getParamsByKeys(searchParams, keyToFilterVariant);
@@ -75,8 +89,8 @@ export function useQueryPersister<TData, TValue>(
7589
return prevState;
7690
}, [searchParams, keyToFilterVariant]);
7791

78-
const update = useCallback(
79-
(nextState: ColumnFiltersState) => {
92+
const update: Persister['update'] = useCallback(
93+
(nextState: ColumnFiltersState, resetPage: boolean = true) => {
8094
const prevState: ColumnFiltersState = getPrevState();
8195

8296
const nextKeys = new Set();
@@ -95,6 +109,10 @@ export function useQueryPersister<TData, TValue>(
95109
}
96110
});
97111

112+
if (resetPage) {
113+
searchParams.delete('page');
114+
}
115+
98116
setSearchParams(searchParams);
99117
},
100118
[getPrevState, searchParams]

frontend/src/components/common/NewTable/FIlter/lib/persisters/Persister.ts renamed to frontend/src/components/common/NewTable/FIlter/lib/persisters/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { ColumnFiltersState } from '@tanstack/react-table';
22

33
export interface Persister {
44
getPrevState: () => ColumnFiltersState;
5-
update: (nextState: ColumnFiltersState) => void;
5+
update: (nextState: ColumnFiltersState, resetPagination?: boolean) => void;
66
}

frontend/src/components/common/NewTable/FIlter/variants/MultiSelect/MultiSelect.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useState } from 'react';
1+
import React, { useCallback, useMemo, useState } from 'react';
22
import { Column } from '@tanstack/react-table';
33

44
import * as S from './MultiSelect.styled';
@@ -19,9 +19,6 @@ interface Props<T, K = string> {
1919
function MultiSelect<T, K = string>(props: Props<T, K>) {
2020
const { column } = props;
2121

22-
const allColumnValues = [...column.getFacetedUniqueValues().keys()].flat();
23-
const allOptions = allColumnValues.map(toOption);
24-
2522
const [selectedOptions, setValues] = useState<Option[]>(() => {
2623
const value = column.getFilterValue() as string[] | undefined;
2724

@@ -32,7 +29,12 @@ function MultiSelect<T, K = string>(props: Props<T, K>) {
3229
return [];
3330
});
3431

35-
const sortedOptions = sortOptionSelectedFirst(selectedOptions, allOptions);
32+
const allValues = column.getFacetedUniqueValues();
33+
const sortedOptions = useMemo(() => {
34+
const allColumnValues = [...new Set([...allValues.keys()].flat())];
35+
const allOptions = allColumnValues.map(toOption);
36+
return sortOptionSelectedFirst(selectedOptions, allOptions);
37+
}, [allValues]);
3638

3739
const onSelect = useCallback((options: Option[]) => {
3840
column.setFilterValue(options.map(getOptionValue));

frontend/src/components/common/NewTable/Table.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import ExpanderCell from './ExpanderCell';
3030
import SelectRowCell from './SelectRowCell';
3131
import SelectRowHeader from './SelectRowHeader';
3232
import TableHeader from './TableHeader';
33-
import { Persister } from './Filter/lib/persisters';
33+
import { type Persister } from './Filter';
3434

3535
export interface TableProps<TData> {
3636
data: TData[];
@@ -55,6 +55,7 @@ export interface TableProps<TData> {
5555
enableSorting?: boolean; // Enables sorting for table.
5656

5757
filterPersister?: Persister;
58+
resetPaginationOnFilter?: boolean;
5859

5960
// Placeholder for empty table
6061
emptyMessage?: React.ReactNode;
@@ -150,10 +151,13 @@ function Table<TData>({
150151
onMouseLeave,
151152
setRowId,
152153
filterPersister,
154+
resetPaginationOnFilter = true,
153155
}: TableProps<TData>) {
154156
const [searchParams, setSearchParams] = useSearchParams();
155157
const location = useLocation();
158+
156159
const [rowSelection, setRowSelection] = React.useState({});
160+
157161
const onSortingChange = React.useCallback(
158162
(updater: UpdaterFn<SortingState>) => {
159163
const newState = updateSortingState(updater, searchParams);
@@ -178,7 +182,7 @@ function Table<TData>({
178182
return (updater: UpdaterFn<ColumnFiltersState>) => {
179183
const prevState = filterPersister.getPrevState();
180184
const nextState = updater(prevState);
181-
filterPersister.update(nextState);
185+
filterPersister.update(nextState, resetPaginationOnFilter);
182186
return nextState;
183187
};
184188
}

frontend/src/components/common/NewTable/TableHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { Header, flexRender } from '@tanstack/react-table';
33

44
import * as S from './Table.styled';
5-
import Filter from './Filter/Filter';
5+
import Filter from './Filter';
66

77
interface TableHeaderProps<TData> {
88
header: Header<TData, unknown>;

0 commit comments

Comments
 (0)