/ client / src / utils / saveload.ts
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  }