saveload.ts
1 import { CrudFilter, CrudSort } from "@refinedev/core"; 2 import { useEffect, useState } from "react"; 3 import { isLocalStorageAvailable } from "./support"; 4 interface Pagination { 5 currentPage: number; 6 pageSize: number; 7 } 8 9 export interface TableState { 10 sorters: CrudSort[]; 11 filters: CrudFilter[]; 12 pagination: Pagination; 13 showColumns?: string[]; 14 } 15 16 export function useInitialTableState(tableId: string): TableState { 17 const [initialState] = useState(() => { 18 const savedSorters = hasHashProperty("sorters") 19 ? getHashProperty("sorters") 20 : isLocalStorageAvailable 21 ? localStorage.getItem(`${tableId}-sorters`) 22 : null; 23 const savedFilters = hasHashProperty("filters") 24 ? getHashProperty("filters") 25 : isLocalStorageAvailable 26 ? localStorage.getItem(`${tableId}-filters`) 27 : null; 28 const savedPagination = hasHashProperty("pagination") 29 ? getHashProperty("pagination") 30 : isLocalStorageAvailable 31 ? localStorage.getItem(`${tableId}-pagination`) 32 : null; 33 const savedShowColumns = isLocalStorageAvailable ? localStorage.getItem(`${tableId}-showColumns`) : null; 34 35 const sorters = savedSorters ? JSON.parse(savedSorters) : [{ field: "id", order: "asc" }]; 36 const filters = savedFilters ? JSON.parse(savedFilters) : []; 37 const pagination = savedPagination ? JSON.parse(savedPagination) : { page: 1, pageSize: 20 }; 38 const showColumns = savedShowColumns ? JSON.parse(savedShowColumns) : undefined; 39 return { sorters, filters, pagination, showColumns }; 40 }); 41 return initialState; 42 } 43 44 export function useStoreInitialState(tableId: string, state: TableState) { 45 useEffect(() => { 46 if (state.sorters.length > 0 && JSON.stringify(state.sorters) != JSON.stringify([{ field: "id", order: "asc" }])) { 47 if (isLocalStorageAvailable) { 48 localStorage.setItem(`${tableId}-sorters`, JSON.stringify(state.sorters)); 49 } 50 setURLHash(`sorters`, JSON.stringify(state.sorters)); 51 } else { 52 localStorage.removeItem(`${tableId}-sorters`); 53 removeURLHash("sorters"); 54 } 55 }, [tableId, state.sorters]); 56 57 useEffect(() => { 58 const filters = state.filters.filter((f) => f.value.length != 0); 59 if (filters.length > 0) { 60 if (isLocalStorageAvailable) { 61 localStorage.setItem(`${tableId}-filters`, JSON.stringify(filters)); 62 setURLHash("filters", JSON.stringify(filters)); 63 } 64 } else { 65 localStorage.removeItem(`${tableId}-filters`); 66 removeURLHash(`filters`); 67 } 68 }, [tableId, state.filters]); 69 70 useEffect(() => { 71 if (JSON.stringify(state.pagination) != JSON.stringify({ current: 1, pageSize: 20 })) { 72 if (isLocalStorageAvailable) { 73 localStorage.setItem(`${tableId}-pagination`, JSON.stringify(state.pagination)); 74 } 75 setURLHash(`pagination`, JSON.stringify(state.pagination)); 76 } else { 77 localStorage.removeItem(`${tableId}-pagination`); 78 removeURLHash(`pagination`); 79 } 80 }, [tableId, state.pagination]); 81 82 useEffect(() => { 83 if (isLocalStorageAvailable) { 84 if (state.showColumns === undefined) { 85 localStorage.removeItem(`${tableId}-showColumns`); 86 } else { 87 localStorage.setItem(`${tableId}-showColumns`, JSON.stringify(state.showColumns)); 88 } 89 } 90 }, [tableId, state.showColumns]); 91 } 92 93 export function useSavedState<T>(id: string, defaultValue: T) { 94 const [state, setState] = useState<T>(() => { 95 const savedState = isLocalStorageAvailable ? localStorage.getItem(`savedStates-${id}`) : null; 96 return savedState ? JSON.parse(savedState) : defaultValue; 97 }); 98 99 useEffect(() => { 100 if (isLocalStorageAvailable) { 101 localStorage.setItem(`savedStates-${id}`, JSON.stringify(state)); 102 } 103 }, [id, state]); 104 105 return [state, setState] as const; 106 } 107 108 function setURLHash(Id: string, value: string) { 109 const params = new URLSearchParams(window.location.hash.substring(1)); 110 if (!params.has(Id)) { 111 params.append(Id, value); 112 } 113 params.set(Id, value); 114 window.location.hash = params.toString(); 115 } 116 function removeURLHash(Id: string) { 117 const params = new URLSearchParams(window.location.hash.substring(1)); 118 if (params.has(Id)) { 119 params.delete(Id); 120 } 121 window.location.hash = params.toString(); 122 } 123 124 function getHashProperty(Id: string) { 125 const hash = new URLSearchParams(window.location.hash.substring(1)); 126 return hash.get(Id); 127 } 128 129 function hasHashProperty(property: string): boolean { 130 const hash = new URLSearchParams(window.location.hash.substring(1)); 131 return hash.has(property); 132 }