UNPKG

@matthew.ngo/react-filter-pilot

Version:

Powerful filtering, pagination, and sorting for React with TanStack Query integration

3 lines 7.72 kB
'use strict';var react=require('react'),reactQuery=require('@tanstack/react-query'),utils=require('../utils'),useUrlHandler=require('./useUrlHandler'),useAdvancedFetchControl=require('./useAdvancedFetchControl'),normalize=require('../utils/normalize');/* @matthew.ngo/react-filter-pilot - MIT License */ var Fe=Object.defineProperty;var b=(C,l)=>Fe(C,"name",{value:l,configurable:true});function He(C){const{filterConfigs:l,paginationConfig:i={},sortConfig:u={},fetchConfig:n,urlHandler:J,initialFiltersProvider:V,enablePresets:D=false}=C,Y=useUrlHandler.useDefaultUrlHandler(),z=react.useMemo(()=>J||Y,[J]),f=react.useMemo(()=>utils.getDefaultFilters(l),[l]),v=react.useMemo(()=>({page:i.initialPage||1,pageSize:i.initialPageSize||10,totalPages:0,totalRecords:0,hasNextPage:false,hasPreviousPage:false}),[i.initialPage,i.initialPageSize]),Z=react.useMemo(()=>u.initialSortField?{field:u.initialSortField,direction:u.initialSortDirection||"asc"}:void 0,[u.initialSortField,u.initialSortDirection]),[S,E]=react.useState(f),[d,F]=react.useState(v),[p,W]=react.useState(Z),[K,k]=react.useState([]),[m,O]=react.useState(f),T=react.useRef({}),I=react.useRef(false),L=react.useMemo(()=>{const e=new Set;return l.forEach(t=>{if(t.syncWithUrl!==false){const r=t.urlKey||t.name;e.add(r);}}),i.syncWithUrl!==false&&(e.add("page"),e.add("pageSize")),u.syncWithUrl!==false&&(e.add("sortBy"),e.add("sortOrder")),e},[l,i.syncWithUrl,u.syncWithUrl]);react.useEffect(()=>{if(I.current)return;b(async()=>{const t=z.getParams(),r=utils.parseUrlParams(t,l);let s=f;if(V)try{const g=await V();s=utils.mergeFilters(g,f);}catch{}const h=utils.mergeFilters(r,s);if(E(h),O(h),i.syncWithUrl!==false){const g=parseInt(t.get("page")||"1",10),y=parseInt(t.get("pageSize")||String(v.pageSize),10);F(G=>({...G,page:g,pageSize:y}));}if(u.syncWithUrl!==false){const g=t.get("sortBy"),y=t.get("sortOrder");g&&W({field:g,direction:y||"asc"});}I.current=true;},"initializeFromUrl")();},[]);const o=react.useCallback((e,t,r)=>{if(!I.current)return;const s=z.getParams(),h=e!==void 0?e:m,g=t?{...d,...t}:d,y=r!==void 0?r:p;L.forEach(A=>{s.delete(A);}),utils.buildSyncableUrlParams(h,l).forEach((A,fe)=>{s.set(fe,A);}),i.syncWithUrl!==false&&(s.set("page",String(g.page)),s.set("pageSize",String(g.pageSize))),u.syncWithUrl!==false&&y&&(s.set("sortBy",y.field),s.set("sortOrder",y.direction)),z.setParams(s);},[l,i.syncWithUrl,u.syncWithUrl,z,d,p,m,L]),$=react.useCallback((e,t)=>{const r=l.find(s=>s.name===e);r?.debounceMs?(T.current[e]&&clearTimeout(T.current[e]),T.current[e]=setTimeout(()=>{O(s=>({...s,[e]:t})),i.resetOnFilterChange!==false&&(!i.resetPageOnFilterChange||i.resetPageOnFilterChange(e))&&F(s=>({...s,page:1}));},r.debounceMs)):(O(s=>({...s,[e]:t})),i.resetOnFilterChange!==false&&(!i.resetPageOnFilterChange||i.resetPageOnFilterChange(e))&&F(s=>({...s,page:1})));},[l,i.resetOnFilterChange,i.resetPageOnFilterChange]),q=react.useMemo(()=>{const e=normalize.normalizeQueryKey(n.queryKey),t=JSON.stringify(m),r=JSON.stringify({page:d.page,pageSize:d.pageSize}),s=JSON.stringify(p);return [...e,"filters",t,"pagination",r,"sort",s]},[n.queryKey,m,d.page,d.pageSize,p]),{shouldFetch:x,fetchReason:ee,controlledFetch:B}=useAdvancedFetchControl.useFetchControl(m,C.fetchControl),te=react.useCallback(async()=>{const e={filters:m,pagination:{page:d.page,pageSize:d.pageSize},sort:p},t={...e};return t.filters={},Object.entries(e.filters).forEach(([r,s])=>{const h=l.find(y=>y.name===r),g=utils.transformFilterValue(s,h?.transformForApi);t.filters[r]=g;}),B(()=>n.fetchFn(t))},[m,d.page,d.pageSize,p,l,n.fetchFn,B]),a=reactQuery.useQuery({queryKey:q,queryFn:te,enabled:n.enabled!==false&&x&&I.current,staleTime:n.staleTime,gcTime:n.gcTime||n.cacheTime,refetchOnWindowFocus:n.refetchOnWindowFocus,refetchInterval:n.refetchInterval,refetchIntervalInBackground:n.refetchIntervalInBackground,select:n.select,placeholderData:n.placeholderData,initialData:n.initialData,initialDataUpdatedAt:n.initialDataUpdatedAt,retry:n.retry,retryDelay:n.retryDelay,networkMode:n.networkMode,meta:n.meta,queryKeyHashFn:n.queryKeyHashFn,structuralSharing:n.structuralSharing}),j=react.useRef();react.useEffect(()=>{a.isSuccess&&a.data&&j.current!==a.data.totalRecords&&(j.current=a.data.totalRecords,F(e=>({...e,totalRecords:a.data.totalRecords,totalPages:Math.ceil(a.data.totalRecords/e.pageSize),hasNextPage:e.page<Math.ceil(a.data.totalRecords/e.pageSize),hasPreviousPage:e.page>1})),n.onSuccess?.(a.data));},[a.isSuccess,a.data?.totalRecords,n.onSuccess]),react.useEffect(()=>{a.isError&&a.error&&n.onError?.(a.error);},[a.isError,a.error,n.onError]);const w=react.useCallback((e,t)=>{const r=l.find(h=>h.name===String(e)),s={...S,[e]:t};E(s),r?.syncWithUrl!==false&&(r?.debounceMs?(T.current[`url_${String(e)}`]&&clearTimeout(T.current[`url_${String(e)}`]),T.current[`url_${String(e)}`]=setTimeout(()=>{o(s);},r.debounceMs)):o(s)),$(String(e),t);},[o,$,l]),M=react.useCallback(e=>{const t={...S,...e};E(t),o(t),O(t),i.resetOnFilterChange!==false&&(!i.resetPageOnFilterChange||Object.keys(e).some(s=>i.resetPageOnFilterChange&&i.resetPageOnFilterChange(s)))&&F(s=>({...s,page:1}));},[S,o,i.resetOnFilterChange,i.resetPageOnFilterChange]),N=react.useCallback(()=>{E(f),O(f),o(f),F(e=>({...e,page:1}));},[f,o]),Q=react.useCallback(e=>{const t=f[e];w(e,t);},[f,w]),re=react.useCallback(e=>{F(t=>({...t,page:e})),o(void 0,{page:e});},[o]),se=react.useCallback(e=>{const t={pageSize:e,page:1};F(r=>({...r,...t})),o(void 0,t);},[o]),ne=react.useCallback(()=>{F(e=>{if(e.hasNextPage){const t=e.page+1;return o(void 0,{page:t}),{...e,page:t}}return e});},[o]),ie=react.useCallback(()=>{F(e=>{if(e.hasPreviousPage){const t=e.page-1;return o(void 0,{page:t}),{...e,page:t}}return e});},[o]),ae=react.useCallback((e,t="asc")=>{const r={field:e,direction:t};W(r),o(void 0,void 0,r);},[o]),oe=react.useCallback(e=>{W(t=>{let r;return !t||t.field!==e?r={field:e,direction:"asc"}:t.direction==="asc"?r={field:e,direction:"desc"}:r=void 0,o(void 0,void 0,r),r});},[o]),le=react.useCallback(()=>{W(void 0),o(void 0,void 0,void 0);},[o]),_=react.useCallback(()=>Object.entries(S).reduce((e,[t,r])=>{const s=l.find(h=>h.name===t);return utils.isFilterActive(r,s?.defaultValue)?e+1:e},0),[S,l]),ce=react.useCallback(()=>_()>0,[_]),de=react.useCallback(()=>q,[q]),ge=react.useMemo(()=>{if(D)return {savePreset:b(e=>{const t={id:Date.now().toString(),name:e,filters:S,createdAt:new Date};k(r=>[...r,t]);try{const r=`filterPilot_presets_${n.queryKey||"default"}`;localStorage.setItem(r,JSON.stringify([...K,t]));}catch{}},"savePreset"),loadPreset:b(e=>{M(e.filters);},"loadPreset"),deletePreset:b(e=>{k(t=>t.filter(r=>r.id!==e));try{const t=`filterPilot_presets_${n.queryKey||"default"}`,r=K.filter(s=>s.id!==e);localStorage.setItem(t,JSON.stringify(r));}catch{}},"deletePreset"),getPresets:b(()=>K,"getPresets")}},[D,S,K,M,n.queryKey]);react.useEffect(()=>{if(D)try{const e=`filterPilot_presets_${n.queryKey||"default"}`,t=localStorage.getItem(e);t&&k(JSON.parse(t));}catch{}},[D,n.queryKey]),react.useEffect(()=>()=>{Object.values(T.current).forEach(clearTimeout);},[]);const ue=react.useMemo(()=>({setFilterValue:w,setFilters:M,resetFilters:N,resetFilter:Q}),[w,M,N,Q]);return {filters:S,...ue,pagination:d,setPage:re,setPageSize:se,nextPage:ne,previousPage:ie,sort:p,setSort:ae,toggleSort:oe,clearSort:le,data:a.data?.data,isLoading:a.isLoading,isError:a.isError,error:a.error||void 0,isFetching:a.isFetching,refetch:a.refetch,presets:ge,getActiveFiltersCount:_,hasActiveFilters:ce,getQueryKey:de,fetchControl:{isEnabled:x,reason:ee,retry:a.refetch}}}b(He,"useFilterPilot");exports.useFilterPilot=He;//# sourceMappingURL=useFilterPilot.cjs.map //# sourceMappingURL=useFilterPilot.cjs.map