Skip to content

Commit 4404c4d

Browse files
Fix Bazza UI filter integration issues
1 parent 20b0070 commit 4404c4d

4 files changed

Lines changed: 68 additions & 22 deletions

File tree

packages/components/src/remix-hook-form/data-table-router-form.tsx

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,15 @@ export function DataTableRouterForm<TData, TValue>({
7474
columnsConfig: filterColumnConfigs,
7575
options: dtfOptions,
7676
faceted: dtfFacetedData,
77-
// initialFilters: urlState.filters, // Assuming an initialFilters prop if available for first load
77+
filters: urlState.filters, // Use URL filters as the source of truth
78+
onFiltersChange: (newFilters) => {
79+
// Update URL state when filters change
80+
setUrlState({ filters: newFilters as BazzaFiltersState, page: 0 });
81+
},
7882
});
7983

80-
// Sync Bazza internal filters TO URL
81-
useEffect(() => {
82-
// Avoid loop if urlState.filters already matches dtfInternalFilters
83-
// Deep comparison might be needed if objects are complex
84-
if (JSON.stringify(dtfInternalFilters) !== JSON.stringify(urlState.filters)) {
85-
setUrlState({ filters: dtfInternalFilters as BazzaFiltersState, page: 0 });
86-
}
87-
}, [dtfInternalFilters, urlState.filters, setUrlState]);
88-
8984
// Sync URL filters TO Bazza internal filters (e.g., on back/forward nav)
90-
useEffect(() => {
91-
// Check if an action to set filters exists, e.g., dtfActions.setFiltersState
92-
if (dtfActions.setFiltersState && JSON.stringify(urlState.filters) !== JSON.stringify(dtfInternalFilters)) {
93-
dtfActions.setFiltersState(urlState.filters);
94-
}
95-
// This effect should also handle initial hydration if `initialFilters` prop wasn't used/available
96-
}, [urlState.filters, dtfActions, dtfInternalFilters]);
85+
// This is now handled by the controlled state pattern with filters and onFiltersChange
9786

9887
// Sync RHF state if urlState changes (e.g., back/forward, external link)
9988
useEffect(() => {
@@ -167,11 +156,8 @@ export function DataTableRouterForm<TData, TValue>({
167156
};
168157

169158
const handleResetFiltersAndSearch = () => {
170-
if (dtfActions.setFiltersState) {
171-
dtfActions.setFiltersState([]); // Reset Bazza UI filters
172-
} else if (dtfActions.clearAllFilters) {
173-
// Alternative action name
174-
dtfActions.clearAllFilters();
159+
if (dtfActions.removeAllFilters) {
160+
dtfActions.removeAllFilters(); // Use the action from useDataTableFilters
175161
}
176162
// Then update URL, which will also clear Bazza filters via the effect if setFiltersState was not called
177163
setUrlState({
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { z } from 'zod';
2+
3+
// Define the shape of a single filter item
4+
export const filterItemSchema = z.object({
5+
columnId: z.string(),
6+
type: z.string(),
7+
operator: z.string(),
8+
values: z.array(z.unknown()),
9+
});
10+
11+
// Define the shape of the filters array
12+
export const filtersArraySchema = z.array(filterItemSchema);
13+
14+
// Export the type for the filters state
15+
export type FiltersState = z.infer<typeof filtersArraySchema>;
16+

packages/components/src/ui/utils/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ import { twMerge } from 'tailwind-merge';
44
export function cn(...inputs: ClassValue[]) {
55
return twMerge(clsx(inputs));
66
}
7+
8+
export * from './debounce';
9+
export * from './filters';
10+
export * from './use-filter-sync';
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { useCallback, useEffect } from 'react';
2+
import { useSearchParams } from 'react-router-dom';
3+
import type { BazzaFiltersState } from '../../remix-hook-form/data-table-router-parsers';
4+
import { dataTableRouterParsers } from '../../remix-hook-form/data-table-router-parsers';
5+
6+
/**
7+
* Custom hook for synchronizing filter state with URL parameters
8+
*
9+
* This hook provides a clean interface for working with filter state in data table components,
10+
* automatically syncing the state with URL search parameters.
11+
*
12+
* @returns A tuple containing the current filter state and a function to update it
13+
*/
14+
export function useFilterSync(): [BazzaFiltersState, (newFilters: BazzaFiltersState) => void] {
15+
const [searchParams, setSearchParams] = useSearchParams();
16+
17+
// Parse filters from URL
18+
const filtersFromUrl = dataTableRouterParsers.filters.parse(searchParams.get('filters'));
19+
20+
// Function to update filters in URL
21+
const setFilters = useCallback((newFilters: BazzaFiltersState) => {
22+
const newParams = new URLSearchParams(searchParams);
23+
24+
// Update or remove the filters parameter
25+
if (newFilters.length > 0) {
26+
const serialized = dataTableRouterParsers.filters.serialize(newFilters);
27+
if (serialized !== null) {
28+
newParams.set('filters', serialized);
29+
}
30+
} else {
31+
newParams.delete('filters');
32+
}
33+
34+
// Update the URL with the new search parameters
35+
setSearchParams(newParams, { replace: true });
36+
}, [searchParams, setSearchParams]);
37+
38+
return [filtersFromUrl, setFilters];
39+
}
40+

0 commit comments

Comments
 (0)