@applica-software-guru/react-admin 1.5.356 → 1.5.358

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -108,5 +108,5 @@
108
108
  "type": "module",
109
109
  "types": "dist/index.d.ts",
110
110
  "typings": "dist/index.d.ts",
111
- "version": "1.5.356"
111
+ "version": "1.5.358"
112
112
  }
@@ -5,6 +5,7 @@ import { ReactElement, useCallback, useEffect, useMemo, useRef } from 'react';
5
5
  import { useListViewContext } from './ListViewProvider';
6
6
  import { useSessionStorage } from '@/hooks';
7
7
  import { useSearchParams } from 'react-router-dom';
8
+ import _ from 'lodash';
8
9
 
9
10
  type ListTabToolbarConfig = {
10
11
  label: string;
@@ -18,37 +19,61 @@ interface ListTabsToolbarProps {
18
19
  tabs?: ListTabToolbarConfig[];
19
20
  }
20
21
 
21
- function ListTabsToolbar(props: ListTabsToolbarProps) {
22
- const { tabs = [] } = props;
23
- const { setFilters, filterValues } = useListContext();
24
- const defaultTabIndex = useMemo(() => tabs.findIndex((tab) => tab.default) ?? 0, [tabs]);
22
+ function ListTabsToolbar({ tabs = [] }: ListTabsToolbarProps) {
23
+ const { setFilters, filterValues, displayedFilters } = useListContext();
25
24
  const { setCurrentTabKey } = useListViewContext();
26
25
  const resource = useResourceContext();
27
26
  const theme = useTheme();
28
-
29
27
  const [searchParams, setSearchParams] = useSearchParams();
30
28
 
31
29
  if (tabs.length > 0 && tabs.some((tab) => !tab.key)) {
32
30
  throw new Error('ListTabsToolbar: Each tab must have a unique key.');
33
31
  }
34
32
 
35
- const tabGroupKey = useMemo(() => `${resource.replace(/^entities\//, '')}-tab-group`, [resource]);
33
+ const defaultTabIndex = useMemo(() => tabs.findIndex((tab) => tab.default) ?? 0, [tabs]);
34
+ const resourceKey = useMemo(() => resource.replace(/^entities\//, ''), [resource]);
35
+ const tabGroupKey = useMemo(() => `${resourceKey}-tab-group`, [resourceKey]);
36
+ const tabFiltersKey = useMemo(() => `${resourceKey}-tab-filters`, [resourceKey]);
36
37
 
37
38
  const [currentTab, setCurrentTab] = useSessionStorage(tabGroupKey, defaultTabIndex);
39
+ const [tabFilterStates, setTabFilterStates] = useSessionStorage(tabFiltersKey, {});
38
40
  const initialized = useRef(false);
39
41
 
42
+ const saveCurrentTabFilters = useMemo(
43
+ () =>
44
+ _.debounce((tabKey: string, filters: any, displayed: any) => {
45
+ setTabFilterStates((prev: any) => ({
46
+ ...prev,
47
+ [tabKey]: {
48
+ filterValues: { ...filters },
49
+ displayedFilters: { ...displayed }
50
+ }
51
+ }));
52
+ }, 500),
53
+ [setTabFilterStates]
54
+ );
55
+
56
+ const restoreTabFilters = useCallback(
57
+ (tabKey: string, tabFilter: Record<string, any>, debounce: boolean) => {
58
+ const savedState = (tabFilterStates as any)?.[tabKey];
59
+
60
+ if (savedState) {
61
+ setFilters(savedState.filterValues, savedState.displayedFilters || {}, debounce);
62
+ } else {
63
+ setFilters(tabFilter, {}, debounce);
64
+ }
65
+ },
66
+ [tabFilterStates, setFilters]
67
+ );
68
+
40
69
  const buildFilters = useCallback(
41
70
  (index: number, debounce: boolean) => {
42
- if (setCurrentTabKey) {
43
- setCurrentTabKey(tabs[index].key);
44
- }
45
- const newFilters = {
46
- ...filterValues,
47
- ...tabs[index].filter
48
- };
49
- setFilters(newFilters, {}, debounce);
71
+ const newTabKey = tabs[index].key;
72
+
73
+ setCurrentTabKey?.(newTabKey);
74
+ restoreTabFilters(newTabKey, tabs[index].filter, debounce);
50
75
  },
51
- [filterValues, setFilters, setCurrentTabKey, tabs]
76
+ [tabs, setCurrentTabKey, restoreTabFilters]
52
77
  );
53
78
 
54
79
  const updateUrlParam = useCallback(
@@ -60,9 +85,26 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
60
85
  [searchParams, setSearchParams, tabGroupKey]
61
86
  );
62
87
 
88
+ const handleChange = useCallback(
89
+ (_: any, newIndex: number) => {
90
+ setCurrentTab(newIndex);
91
+ buildFilters(newIndex, true);
92
+ },
93
+ [buildFilters, setCurrentTab]
94
+ );
95
+
96
+ useEffect(() => {
97
+ if (initialized.current && tabs.length > 0) {
98
+ const currentTabKey = tabs[Number(currentTab)]?.key;
99
+ if (currentTabKey) {
100
+ saveCurrentTabFilters(currentTabKey, filterValues, displayedFilters);
101
+ }
102
+ }
103
+ }, [filterValues, displayedFilters, currentTab, tabs, saveCurrentTabFilters]);
104
+
63
105
  useEffect(() => {
64
106
  const param = searchParams.get(tabGroupKey);
65
- if (String(param) !== String(currentTab)) {
107
+ if (param !== String(currentTab)) {
66
108
  updateUrlParam(Number(currentTab));
67
109
  }
68
110
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -73,7 +115,7 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
73
115
  const param = searchParams.get(tabGroupKey);
74
116
  const initialIndex = param != null ? Number(param) : Number(currentTab);
75
117
 
76
- if (param != null && String(initialIndex) !== String(currentTab)) {
118
+ if (param != null && initialIndex !== Number(currentTab)) {
77
119
  setCurrentTab(initialIndex);
78
120
  }
79
121
 
@@ -81,15 +123,7 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
81
123
  initialized.current = true;
82
124
  }
83
125
  // eslint-disable-next-line react-hooks/exhaustive-deps
84
- }, [searchParams, setSearchParams, tabGroupKey, currentTab, setCurrentTab, buildFilters]);
85
-
86
- const handleChange = useCallback(
87
- (_: any, newIndex: number) => {
88
- setCurrentTab(newIndex);
89
- buildFilters(newIndex, true);
90
- },
91
- [buildFilters, setCurrentTab]
92
- );
126
+ }, []);
93
127
 
94
128
  return (
95
129
  <Box sx={{ width: '100%' }}>