Skip to content

Commit

Permalink
refactor: move table filter logic to custom useTableFilters hook usin…
Browse files Browse the repository at this point in the history
…g useMemo
  • Loading branch information
ST-KO committed Oct 23, 2024
1 parent ddf1de9 commit ad14c2c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 48 deletions.
54 changes: 6 additions & 48 deletions src/components/CompareResults/ResultsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Suspense, useEffect, useState } from 'react';
import { Suspense, useState } from 'react';

import Box from '@mui/material/Box';
import CircularProgress from '@mui/material/CircularProgress';
import { useSearchParams } from 'react-router-dom';
import { useLoaderData, Await } from 'react-router-dom';

import useRawSearchParams from '../../hooks/useRawSearchParams';
import useTableFilters from '../../hooks/useTableFilters';
import type { CompareResultsItem } from '../../types/state';
import { Framework } from '../../types/types';
import type { CompareResultsTableConfig } from '../../types/types';
Expand Down Expand Up @@ -100,56 +101,13 @@ export default function ResultsTable() {
// This is our custom hook that updates the search params without a rerender.
const [rawSearchParams, updateRawSearchParams] = useRawSearchParams();

// This is our custom hook that manages table filters
// and provides methods for clearing and toggling them.
const { tableFilters, onClearFilter, onToggleFilter } = useTableFilters();

const initialSearchTerm = rawSearchParams.get('search') ?? '';
const [searchTerm, setSearchTerm] = useState(initialSearchTerm);
const [frameworkIdVal, setFrameworkIdVal] = useState(frameworkId);
const [tableFilters, setTableFilters] = useState(
new Map() as Map<string, Set<string>>, // ColumnID -> Set<Values to remove>
);

// This useEffect is to extract filter params from the URL (via rawSearchParams)
// and updates the tableFilters state.
useEffect(() => {
const filters = Array.from(rawSearchParams.entries())
.filter(([key]) => key.startsWith('filter'))
.reduce((accumulator: Map<string, Set<string>>, [key, value]) => {
const columnId = key.split('_')[1];
if (!accumulator.has(columnId)) {
accumulator.set(columnId, new Set());
}
const valuesArray = value.split(',').map((item) => item.trim());
valuesArray.forEach((item) => accumulator.get(columnId)?.add(item));
return accumulator;
}, new Map<string, Set<string>>());

setTableFilters(filters);
}, [rawSearchParams]);

const onClearFilter = (columnId: string) => {
rawSearchParams.delete(`filter_${columnId}`);
updateRawSearchParams(rawSearchParams);

setTableFilters((oldFilters) => {
const newFilters = new Map(oldFilters);
newFilters.delete(columnId);
return newFilters;
});
};

const onToggleFilter = (columnId: string, filters: Set<string>) => {
if (filters.size > 0) {
rawSearchParams.set(`filter_${columnId}`, Array.from(filters).join(','));
} else {
rawSearchParams.delete(`filter_${columnId}`);
}
updateRawSearchParams(rawSearchParams);

setTableFilters((oldFilters) => {
const newFilters = new Map(oldFilters);
newFilters.set(columnId, filters);
return newFilters;
});
};

const onFrameworkChange = (newFrameworkId: Framework['id']) => {
setFrameworkIdVal(newFrameworkId);
Expand Down
58 changes: 58 additions & 0 deletions src/hooks/useTableFilters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { useMemo, useState } from 'react';

import useRawSearchParams from './useRawSearchParams';

const useTableFilters = () => {
// This is our custom hook that updates the search params without a rerender.
const [rawSearchParams, updateRawSearchParams] = useRawSearchParams();

const [tableFilters, setTableFilters] = useState(
new Map() as Map<string, Set<string>>, // ColumnID -> Set<Values to remove>
);

useMemo(() => {
const filters = Array.from(rawSearchParams.entries())
.filter(([key]) => key.startsWith('filter'))
.reduce((accumulator: Map<string, Set<string>>, [key, value]) => {
const columnId = key.split('_')[1];
if (!accumulator.has(columnId)) {
accumulator.set(columnId, new Set());
}
const valuesArray = value.split(',').map((item) => item.trim());
valuesArray.forEach((item) => accumulator.get(columnId)?.add(item));
return accumulator;
}, new Map<string, Set<string>>());

setTableFilters(filters);
}, [rawSearchParams]);

const onClearFilter = (columnId: string) => {
rawSearchParams.delete(`filter_${columnId}`);
updateRawSearchParams(rawSearchParams);

setTableFilters((oldFilters) => {
const newFilters = new Map(oldFilters);
newFilters.delete(columnId);
return newFilters;
});
};

const onToggleFilter = (columnId: string, filters: Set<string>) => {
if (filters.size > 0) {
rawSearchParams.set(`filter_${columnId}`, Array.from(filters).join(','));
} else {
rawSearchParams.delete(`filter_${columnId}`);

Check warning on line 44 in src/hooks/useTableFilters.ts

View check run for this annotation

Codecov / codecov/patch

src/hooks/useTableFilters.ts#L43-L44

Added lines #L43 - L44 were not covered by tests
}
updateRawSearchParams(rawSearchParams);

setTableFilters((oldFilters) => {
const newFilters = new Map(oldFilters);
newFilters.set(columnId, filters);
return newFilters;
});
};

return { tableFilters, onClearFilter, onToggleFilter };
};

export default useTableFilters;

0 comments on commit ad14c2c

Please sign in to comment.