@matthew.ngo/react-filter-pilot
Version:
Powerful filtering, pagination, and sorting for React with TanStack Query integration
1 lines • 36.7 kB
Source Map (JSON)
{"version":3,"sources":["../../src/hooks/useFilterPilot.ts"],"names":["useFilterPilot","options","filterConfigs","paginationConfig","sortConfig","fetchConfig","providedUrlHandler","initialFiltersProvider","enablePresets","defaultUrlHandler","useDefaultUrlHandler","urlHandler","useMemo","defaultFilters","getDefaultFilters","defaultPagination","defaultSort","filters","setFiltersState","useState","pagination","setPaginationState","sort","setSortState","presets","setPresets","debouncedFilters","setDebouncedFilters","debounceTimers","useRef","isInitialized","managedParamKeys","keys","config","urlKey","useEffect","__name","urlParams","urlFilters","parseUrlParams","initialFilters","providedFilters","mergeFilters","finalFilters","page","pageSize","prev","sortField","sortDirection","syncUrlWithValues","useCallback","newFilters","newPagination","newSort","params","currentFilters","currentPagination","currentSort","key","buildSyncableUrlParams","value","triggerDebouncedApiCall","filterName","c","queryKey","baseKey","normalizeQueryKey","stableFilters","stablePagination","stableSort","shouldFetch","fetchReason","controlledFetch","useFetchControl","fetchData","transformedParams","transformedValue","transformFilterValue","query","useQuery","lastTotalRecords","setFilterValue","name","setFilters","updatedFilters","resetFilters","resetFilter","defaultValue","setPage","setPageSize","nextPage","newPage","previousPage","setSort","field","direction","toggleSort","newState","clearSort","getActiveFiltersCount","count","isFilterActive","hasActiveFilters","getQueryKey","presetMethods","newPreset","preset","id","p","updatedPresets","savedPresets","stableFilterHandlers"],"mappings":"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","file":"useFilterPilot.cjs","sourcesContent":["import { useState, useEffect, useCallback, useMemo, useRef } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport {\n UseFilterPilotOptions,\n UseFilterPilotResult,\n PaginationState,\n SortState,\n FilterPreset,\n FetchParams,\n FetchResult,\n} from '../types';\nimport {\n getDefaultFilters,\n isFilterActive,\n mergeFilters,\n parseUrlParams,\n buildSyncableUrlParams,\n transformFilterValue,\n} from '../utils';\nimport { useDefaultUrlHandler } from './useUrlHandler';\nimport { useFetchControl } from './useAdvancedFetchControl';\nimport { normalizeQueryKey } from '../utils/normalize';\n\nexport function useFilterPilot<TData, TFilters = Record<string, any>>(\n options: UseFilterPilotOptions<TData, TFilters>\n): UseFilterPilotResult<TData, TFilters> {\n const {\n filterConfigs,\n paginationConfig = {},\n sortConfig = {},\n fetchConfig,\n urlHandler: providedUrlHandler,\n initialFiltersProvider,\n enablePresets = false,\n } = options;\n\n // URL handler - Stable reference\n const defaultUrlHandler = useDefaultUrlHandler();\n const urlHandler = useMemo(() => providedUrlHandler || defaultUrlHandler, [providedUrlHandler]);\n\n // Default values - Memoized for stability\n const defaultFilters = useMemo(\n () => getDefaultFilters(filterConfigs) as TFilters,\n [filterConfigs]\n );\n\n const defaultPagination: PaginationState = useMemo(\n () => ({\n page: paginationConfig.initialPage || 1,\n pageSize: paginationConfig.initialPageSize || 10,\n totalPages: 0,\n totalRecords: 0,\n hasNextPage: false,\n hasPreviousPage: false,\n }),\n [paginationConfig.initialPage, paginationConfig.initialPageSize]\n );\n\n const defaultSort: SortState | undefined = useMemo(\n () =>\n sortConfig.initialSortField\n ? {\n field: sortConfig.initialSortField,\n direction: sortConfig.initialSortDirection || 'asc',\n }\n : undefined,\n [sortConfig.initialSortField, sortConfig.initialSortDirection]\n );\n\n // State\n const [filters, setFiltersState] = useState<TFilters>(defaultFilters);\n const [pagination, setPaginationState] = useState<PaginationState>(defaultPagination);\n const [sort, setSortState] = useState<SortState | undefined>(defaultSort);\n const [presets, setPresets] = useState<FilterPreset[]>([]);\n\n const [debouncedFilters, setDebouncedFilters] = useState<TFilters>(defaultFilters);\n\n // Refs for debouncing\n const debounceTimers = useRef<Record<string, NodeJS.Timeout>>({});\n const isInitialized = useRef(false);\n\n // Memoize all param keys that this hook manages - CHỈ sync filters\n const managedParamKeys = useMemo(() => {\n const keys = new Set<string>();\n\n // Add filter param keys - CHỈ những filter sync với URL\n filterConfigs.forEach((config) => {\n if (config.syncWithUrl !== false) {\n const urlKey = config.urlKey || config.name;\n keys.add(urlKey);\n }\n });\n\n // Add pagination param keys\n if (paginationConfig.syncWithUrl !== false) {\n keys.add('page');\n keys.add('pageSize');\n }\n\n // Add sort param keys\n if (sortConfig.syncWithUrl !== false) {\n keys.add('sortBy');\n keys.add('sortOrder');\n }\n\n return keys;\n }, [filterConfigs, paginationConfig.syncWithUrl, sortConfig.syncWithUrl]);\n\n // Initialize from URL on mount\n useEffect(() => {\n if (isInitialized.current) return;\n\n const initializeFromUrl = async () => {\n const urlParams = urlHandler.getParams();\n const urlFilters = parseUrlParams(urlParams, filterConfigs);\n\n // Get initial filters from provider if available\n let initialFilters = defaultFilters;\n if (initialFiltersProvider) {\n try {\n const providedFilters = await initialFiltersProvider();\n // @ts-ignore\n initialFilters = mergeFilters(providedFilters, defaultFilters) as TFilters;\n } catch (error) {\n console.error('Error loading initial filters:', error);\n }\n }\n\n // Merge URL filters with initial filters\n // @ts-ignore\n const finalFilters = mergeFilters(urlFilters, initialFilters) as TFilters;\n setFiltersState(finalFilters);\n setDebouncedFilters(finalFilters);\n\n // Initialize pagination from URL\n if (paginationConfig.syncWithUrl !== false) {\n const page = parseInt(urlParams.get('page') || '1', 10);\n const pageSize = parseInt(\n urlParams.get('pageSize') || String(defaultPagination.pageSize),\n 10\n );\n setPaginationState((prev) => ({ ...prev, page, pageSize }));\n }\n\n // Initialize sort from URL\n if (sortConfig.syncWithUrl !== false) {\n const sortField = urlParams.get('sortBy');\n const sortDirection = urlParams.get('sortOrder') as 'asc' | 'desc' | null;\n if (sortField) {\n setSortState({\n field: sortField,\n direction: sortDirection || 'asc',\n });\n }\n }\n\n isInitialized.current = true;\n };\n\n initializeFromUrl();\n }, []); // Only run on mount\n\n const syncUrlWithValues = useCallback(\n (\n newFilters?: TFilters,\n newPagination?: Partial<PaginationState>,\n newSort?: SortState | undefined\n ) => {\n if (!isInitialized.current) return;\n\n const params = urlHandler.getParams();\n\n // Use provided values or current state\n const currentFilters = newFilters !== undefined ? newFilters : debouncedFilters;\n const currentPagination = newPagination ? { ...pagination, ...newPagination } : pagination;\n const currentSort = newSort !== undefined ? newSort : sort;\n\n // Clear managed params - CHỈ những params đang được manage\n managedParamKeys.forEach((key) => {\n params.delete(key);\n });\n\n // @ts-ignore\n const filterParams = buildSyncableUrlParams(currentFilters, filterConfigs);\n filterParams.forEach((value, key) => {\n params.set(key, value);\n });\n\n // Set pagination params\n if (paginationConfig.syncWithUrl !== false) {\n params.set('page', String(currentPagination.page));\n params.set('pageSize', String(currentPagination.pageSize));\n }\n\n // Set sort params\n if (sortConfig.syncWithUrl !== false && currentSort) {\n params.set('sortBy', currentSort.field);\n params.set('sortOrder', currentSort.direction);\n }\n\n urlHandler.setParams(params);\n },\n [\n filterConfigs,\n paginationConfig.syncWithUrl,\n sortConfig.syncWithUrl,\n urlHandler,\n pagination,\n sort,\n debouncedFilters,\n managedParamKeys,\n ]\n );\n\n // Separate debounced sync for API calls only (not URL)\n const triggerDebouncedApiCall = useCallback(\n (filterName: string, value: any) => {\n const config = filterConfigs.find((c) => c.name === filterName);\n\n if (config?.debounceMs) {\n if (debounceTimers.current[filterName]) {\n clearTimeout(debounceTimers.current[filterName]);\n }\n\n debounceTimers.current[filterName] = setTimeout(() => {\n setDebouncedFilters((prev) => ({\n ...prev,\n [filterName]: value,\n }));\n\n // Reset pagination if configured\n if (paginationConfig.resetOnFilterChange !== false) {\n if (\n !paginationConfig.resetPageOnFilterChange ||\n paginationConfig.resetPageOnFilterChange(filterName)\n ) {\n setPaginationState((prev) => ({ ...prev, page: 1 }));\n }\n }\n }, config.debounceMs);\n } else {\n // No debouncing, update immediately\n setDebouncedFilters((prev) => ({\n ...prev,\n [filterName]: value,\n }));\n\n // Reset pagination if configured\n if (paginationConfig.resetOnFilterChange !== false) {\n if (\n !paginationConfig.resetPageOnFilterChange ||\n paginationConfig.resetPageOnFilterChange(filterName)\n ) {\n setPaginationState((prev) => ({ ...prev, page: 1 }));\n }\n }\n }\n },\n [filterConfigs, paginationConfig.resetOnFilterChange, paginationConfig.resetPageOnFilterChange]\n );\n\n // Query key with proper dependencies\n const queryKey = useMemo(() => {\n const baseKey = normalizeQueryKey(fetchConfig.queryKey);\n\n // Create stable objects for comparison\n const stableFilters = JSON.stringify(debouncedFilters);\n const stablePagination = JSON.stringify({\n page: pagination.page,\n pageSize: pagination.pageSize,\n });\n const stableSort = JSON.stringify(sort);\n\n return [\n ...baseKey,\n 'filters',\n stableFilters,\n 'pagination',\n stablePagination,\n 'sort',\n stableSort,\n ];\n }, [fetchConfig.queryKey, debouncedFilters, pagination.page, pagination.pageSize, sort]);\n\n // Fetch control\n const { shouldFetch, fetchReason, controlledFetch } = useFetchControl(\n debouncedFilters,\n options.fetchControl\n );\n\n // Fetch function\n const fetchData = useCallback(async () => {\n const params: FetchParams<TFilters> = {\n filters: debouncedFilters,\n pagination: {\n page: pagination.page,\n pageSize: pagination.pageSize,\n },\n sort,\n };\n\n // Transform filters for API\n const transformedParams = { ...params };\n transformedParams.filters = {} as TFilters;\n\n Object.entries(params.filters as Record<string, any>).forEach(([key, value]) => {\n const config = filterConfigs.find((c) => c.name === key);\n const transformedValue = transformFilterValue(value, config?.transformForApi);\n (transformedParams.filters as any)[key] = transformedValue;\n });\n\n // Wrap with fetch control\n return controlledFetch(() => fetchConfig.fetchFn(transformedParams));\n }, [\n debouncedFilters,\n pagination.page,\n pagination.pageSize,\n sort,\n filterConfigs,\n fetchConfig.fetchFn,\n controlledFetch,\n ]);\n\n // Query\n const query = useQuery<FetchResult<TData>, Error, FetchResult<TData>, unknown[]>({\n queryKey,\n queryFn: fetchData,\n enabled: fetchConfig.enabled !== false && shouldFetch && isInitialized.current,\n staleTime: fetchConfig.staleTime,\n gcTime: fetchConfig.gcTime || fetchConfig.cacheTime,\n refetchOnWindowFocus: fetchConfig.refetchOnWindowFocus,\n refetchInterval: fetchConfig.refetchInterval,\n refetchIntervalInBackground: fetchConfig.refetchIntervalInBackground,\n select: fetchConfig.select,\n placeholderData: fetchConfig.placeholderData,\n initialData: fetchConfig.initialData,\n initialDataUpdatedAt: fetchConfig.initialDataUpdatedAt,\n retry: fetchConfig.retry,\n retryDelay: fetchConfig.retryDelay,\n networkMode: fetchConfig.networkMode,\n meta: fetchConfig.meta,\n queryKeyHashFn: fetchConfig.queryKeyHashFn,\n structuralSharing: fetchConfig.structuralSharing,\n });\n\n // Handle success/error with useEffect\n const lastTotalRecords = useRef<number>();\n useEffect(() => {\n if (query.isSuccess && query.data && lastTotalRecords.current !== query.data.totalRecords) {\n lastTotalRecords.current = query.data.totalRecords;\n setPaginationState((prev) => ({\n ...prev,\n totalRecords: query.data.totalRecords,\n totalPages: Math.ceil(query.data.totalRecords / prev.pageSize),\n hasNextPage: prev.page < Math.ceil(query.data.totalRecords / prev.pageSize),\n hasPreviousPage: prev.page > 1,\n }));\n\n fetchConfig.onSuccess?.(query.data);\n }\n }, [query.isSuccess, query.data?.totalRecords, fetchConfig.onSuccess]);\n\n useEffect(() => {\n if (query.isError && query.error) {\n fetchConfig.onError?.(query.error);\n }\n }, [query.isError, query.error, fetchConfig.onError]);\n\n const setFilterValue = useCallback(\n (name: keyof TFilters, value: any) => {\n const config = filterConfigs.find((c) => c.name === String(name));\n\n console.log('🎯 setFilterValue called:', {\n name: String(name),\n value,\n debounceMs: config?.debounceMs,\n syncWithUrl: config?.syncWithUrl,\n timestamp: new Date().toISOString(),\n });\n\n const newFilters = { ...filters, [name]: value } as TFilters;\n setFiltersState(newFilters);\n\n if (config?.syncWithUrl !== false) {\n if (config?.debounceMs) {\n console.log('🕐 Setting URL debounce timer:', config.debounceMs + 'ms');\n\n if (debounceTimers.current[`url_${String(name)}`]) {\n clearTimeout(debounceTimers.current[`url_${String(name)}`]);\n console.log('🗑️ Cleared previous URL timer');\n }\n\n debounceTimers.current[`url_${String(name)}`] = setTimeout(() => {\n console.log('🚀 URL debounce triggered for:', String(name));\n syncUrlWithValues(newFilters);\n }, config.debounceMs);\n } else {\n console.log('⚡ Immediate URL sync (no debounce)');\n syncUrlWithValues(newFilters);\n }\n }\n\n triggerDebouncedApiCall(String(name), value);\n },\n [syncUrlWithValues, triggerDebouncedApiCall, filterConfigs]\n );\n\n const setFilters = useCallback(\n (newFilters: Partial<TFilters>) => {\n const updatedFilters = { ...filters, ...newFilters } as TFilters;\n\n setFiltersState(updatedFilters);\n\n // Sync URL immediately with new filters\n syncUrlWithValues(updatedFilters);\n\n // Update debounced filters immediately (no individual debouncing for batch updates)\n setDebouncedFilters(updatedFilters);\n\n // Reset pagination if configured\n if (paginationConfig.resetOnFilterChange !== false) {\n const shouldResetPage =\n !paginationConfig.resetPageOnFilterChange ||\n Object.keys(newFilters).some(\n (key) =>\n paginationConfig.resetPageOnFilterChange &&\n paginationConfig.resetPageOnFilterChange(key)\n );\n\n if (shouldResetPage) {\n setPaginationState((prev) => ({ ...prev, page: 1 }));\n }\n }\n },\n [\n filters,\n syncUrlWithValues,\n paginationConfig.resetOnFilterChange,\n paginationConfig.resetPageOnFilterChange,\n ]\n );\n\n const resetFilters = useCallback(() => {\n setFiltersState(defaultFilters);\n setDebouncedFilters(defaultFilters);\n\n // Sync URL immediately with reset filters\n syncUrlWithValues(defaultFilters);\n\n setPaginationState((prev) => ({ ...prev, page: 1 }));\n }, [defaultFilters, syncUrlWithValues]);\n\n const resetFilter = useCallback(\n (name: keyof TFilters) => {\n const defaultValue = (defaultFilters as any)[name];\n setFilterValue(name, defaultValue);\n },\n [defaultFilters, setFilterValue]\n );\n\n // Pagination functions - use unified sync function\n const setPage = useCallback(\n (page: number) => {\n setPaginationState((prev) => ({ ...prev, page }));\n syncUrlWithValues(undefined, { page });\n },\n [syncUrlWithValues]\n );\n\n const setPageSize = useCallback(\n (pageSize: number) => {\n const newPagination = { pageSize, page: 1 };\n setPaginationState((prev) => ({ ...prev, ...newPagination }));\n syncUrlWithValues(undefined, newPagination);\n },\n [syncUrlWithValues]\n );\n\n const nextPage = useCallback(() => {\n setPaginationState((prev) => {\n if (prev.hasNextPage) {\n const newPage = prev.page + 1;\n syncUrlWithValues(undefined, { page: newPage });\n return { ...prev, page: newPage };\n }\n return prev;\n });\n }, [syncUrlWithValues]);\n\n const previousPage = useCallback(() => {\n setPaginationState((prev) => {\n if (prev.hasPreviousPage) {\n const newPage = prev.page - 1;\n syncUrlWithValues(undefined, { page: newPage });\n return { ...prev, page: newPage };\n }\n return prev;\n });\n }, [syncUrlWithValues]);\n\n // Sort functions - use unified sync function\n const setSort = useCallback(\n (field: string, direction: 'asc' | 'desc' = 'asc') => {\n const newSort = { field, direction };\n setSortState(newSort);\n syncUrlWithValues(undefined, undefined, newSort);\n },\n [syncUrlWithValues]\n );\n\n const toggleSort = useCallback(\n (field: string) => {\n setSortState((prev) => {\n let newState: SortState | undefined;\n if (!prev || prev.field !== field) {\n newState = { field, direction: 'asc' };\n } else if (prev.direction === 'asc') {\n newState = { field, direction: 'desc' };\n } else {\n newState = undefined;\n }\n\n syncUrlWithValues(undefined, undefined, newState);\n return newState;\n });\n },\n [syncUrlWithValues]\n );\n\n const clearSort = useCallback(() => {\n setSortState(undefined);\n syncUrlWithValues(undefined, undefined, undefined);\n }, [syncUrlWithValues]);\n\n // Utility functions\n const getActiveFiltersCount = useCallback(() => {\n // @ts-ignore\n return Object.entries(filters).reduce((count, [key, value]) => {\n const config = filterConfigs.find((c) => c.name === key);\n if (isFilterActive(value, config?.defaultValue)) {\n return count + 1;\n }\n return count;\n }, 0);\n }, [filters, filterConfigs]);\n\n const hasActiveFilters = useCallback(() => {\n return getActiveFiltersCount() > 0;\n }, [getActiveFiltersCount]);\n\n const getQueryKey = useCallback(() => queryKey, [queryKey]);\n\n // Preset management\n const presetMethods = useMemo(() => {\n if (!enablePresets) return undefined;\n\n return {\n savePreset: (name: string) => {\n const newPreset: FilterPreset = {\n id: Date.now().toString(),\n name,\n filters: filters as Record<string, any>,\n createdAt: new Date(),\n };\n setPresets((prev) => [...prev, newPreset]);\n\n try {\n const key = `filterPilot_presets_${fetchConfig.queryKey || 'default'}`;\n localStorage.setItem(key, JSON.stringify([...presets, newPreset]));\n } catch (error) {\n console.error('Error saving preset:', error);\n }\n },\n loadPreset: (preset: FilterPreset) => {\n setFilters(preset.filters as Partial<TFilters>);\n },\n deletePreset: (id: string) => {\n setPresets((prev) => prev.filter((p) => p.id !== id));\n\n try {\n const key = `filterPilot_presets_${fetchConfig.queryKey || 'default'}`;\n const updatedPresets = presets.filter((p) => p.id !== id);\n localStorage.setItem(key, JSON.stringify(updatedPresets));\n } catch (error) {\n console.error('Error deleting preset:', error);\n }\n },\n getPresets: () => presets,\n };\n }, [enablePresets, filters, presets, setFilters, fetchConfig.queryKey]);\n\n // Load presets from localStorage on mount\n useEffect(() => {\n if (enablePresets) {\n try {\n const key = `filterPilot_presets_${fetchConfig.queryKey || 'default'}`;\n const savedPresets = localStorage.getItem(key);\n if (savedPresets) {\n setPresets(JSON.parse(savedPresets));\n }\n } catch (error) {\n console.error('Error loading presets:', error);\n }\n }\n }, [enablePresets, fetchConfig.queryKey]);\n\n // Cleanup debounce timers\n useEffect(() => {\n return () => {\n Object.values(debounceTimers.current).forEach(clearTimeout);\n };\n }, []);\n\n const stableFilterHandlers = useMemo(\n () => ({\n setFilterValue,\n setFilters,\n resetFilters,\n resetFilter,\n }),\n [setFilterValue, setFilters, resetFilters, resetFilter]\n );\n\n return {\n // Filter state\n filters,\n ...stableFilterHandlers,\n\n // Pagination state\n pagination,\n setPage,\n setPageSize,\n nextPage,\n previousPage,\n\n // Sort state\n sort,\n setSort,\n toggleSort,\n clearSort,\n\n // Data & Query state\n data: query.data?.data,\n isLoading: query.isLoading,\n isError: query.isError,\n error: query.error || undefined,\n isFetching: query.isFetching,\n refetch: query.refetch,\n\n // Preset management\n presets: presetMethods,\n\n // Utilities\n getActiveFiltersCount,\n hasActiveFilters,\n getQueryKey,\n\n // Fetch control\n fetchControl: {\n isEnabled: shouldFetch,\n reason: fetchReason,\n retry: query.refetch,\n },\n };\n}\n"]}