@applica-software-guru/react-admin 1.5.357 → 1.5.359

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.357"
111
+ "version": "1.5.359"
112
112
  }
@@ -2,7 +2,7 @@ import { useAppConfig } from '@/components/AppStateProvider';
2
2
  import { useTheme } from '@emotion/react';
3
3
  import { FormHelperText, InputLabel, Stack, SxProps } from '@mui/material';
4
4
  import React, { PropsWithChildren } from 'react';
5
- import { FieldTitle } from 'react-admin';
5
+ import { FieldTitle, useTranslate } from 'react-admin';
6
6
  import { useFormContext } from 'react-hook-form';
7
7
 
8
8
  /**
@@ -20,6 +20,7 @@ function LabeledArrayInput({
20
20
  ...props
21
21
  }: LabeledArrayInputProps): React.ReactElement {
22
22
  const theme = useTheme() as any;
23
+ const translate = useTranslate();
23
24
  const { getCurrentDialog } = useAppConfig();
24
25
  const { source, resource, isRequired } = props;
25
26
  const { getFieldState, formState } = useFormContext();
@@ -73,7 +74,11 @@ function LabeledArrayInput({
73
74
  }}
74
75
  error={!!error}
75
76
  >
76
- {helperText}
77
+ {React.isValidElement(helperText)
78
+ ? helperText
79
+ : typeof helperText === 'string'
80
+ ? translate(helperText, { _: helperText })
81
+ : helperText}
77
82
  </FormHelperText>
78
83
  ) : null}
79
84
  </Stack>
@@ -2,7 +2,7 @@ import { useAppConfig } from '@/components/AppStateProvider';
2
2
  import { FormHelperText, InputLabel, Stack } from '@mui/material';
3
3
  import { useTheme } from '@mui/material/styles';
4
4
  import React, { PropsWithChildren, ReactElement } from 'react';
5
- import { CommonInputProps, FieldTitle, useInput } from 'react-admin';
5
+ import { CommonInputProps, FieldTitle, useInput, useTranslate } from 'react-admin';
6
6
 
7
7
  function LabeledInput({
8
8
  label,
@@ -15,6 +15,7 @@ function LabeledInput({
15
15
  ...props
16
16
  }: LabeledInputProps): JSX.Element {
17
17
  const theme = useTheme();
18
+ const translate = useTranslate();
18
19
  const { getCurrentDialog } = useAppConfig();
19
20
  const { source, resource, isRequired, chip } = props;
20
21
  const {
@@ -73,7 +74,11 @@ function LabeledInput({
73
74
  }}
74
75
  error={invalid === true}
75
76
  >
76
- {helperText}
77
+ {React.isValidElement(helperText)
78
+ ? helperText
79
+ : typeof helperText === 'string'
80
+ ? translate(helperText, { _: helperText })
81
+ : helperText}
77
82
  </FormHelperText>
78
83
  ) : null}
79
84
  </Stack>
@@ -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,40 +19,38 @@ interface ListTabsToolbarProps {
18
19
  tabs?: ListTabToolbarConfig[];
19
20
  }
20
21
 
21
- function ListTabsToolbar(props: ListTabsToolbarProps) {
22
- const { tabs = [] } = props;
22
+ function ListTabsToolbar({ tabs = [] }: ListTabsToolbarProps) {
23
23
  const { setFilters, filterValues, displayedFilters } = useListContext();
24
- const defaultTabIndex = useMemo(() => tabs.findIndex((tab) => tab.default) ?? 0, [tabs]);
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]);
36
- const tabFiltersKey = useMemo(() => `${resource.replace(/^entities\//, '')}-tab-filters`, [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]);
37
37
 
38
38
  const [currentTab, setCurrentTab] = useSessionStorage(tabGroupKey, defaultTabIndex);
39
39
  const [tabFilterStates, setTabFilterStates] = useSessionStorage(tabFiltersKey, {});
40
40
  const initialized = useRef(false);
41
41
 
42
- const saveCurrentTabFilters = useCallback(
43
- (tabKey: string) => {
44
- const currentState = {
45
- filterValues: { ...filterValues },
46
- displayedFilters: { ...displayedFilters }
47
- };
48
-
49
- setTabFilterStates((prev: any) => ({
50
- ...prev,
51
- [tabKey]: currentState
52
- }));
53
- },
54
- [filterValues, displayedFilters, setTabFilterStates]
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]
55
54
  );
56
55
 
57
56
  const restoreTabFilters = useCallback(
@@ -61,31 +60,20 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
61
60
  if (savedState) {
62
61
  setFilters(savedState.filterValues, savedState.displayedFilters || {}, debounce);
63
62
  } else {
64
- const defaultFilters = {
65
- ...tabFilter
66
- };
67
- setFilters(defaultFilters, {}, debounce);
63
+ setFilters(tabFilter, {}, debounce);
68
64
  }
69
65
  },
70
66
  [tabFilterStates, setFilters]
71
67
  );
72
68
 
73
69
  const buildFilters = useCallback(
74
- (index: number, debounce: boolean, saveCurrentFilters: boolean = true) => {
75
- const currentTabKey = tabs[Number(currentTab)]?.key;
70
+ (index: number, debounce: boolean) => {
76
71
  const newTabKey = tabs[index].key;
77
72
 
78
- if (saveCurrentFilters && currentTabKey && currentTabKey !== newTabKey) {
79
- saveCurrentTabFilters(currentTabKey);
80
- }
81
-
82
- if (setCurrentTabKey) {
83
- setCurrentTabKey(newTabKey);
84
- }
85
-
73
+ setCurrentTabKey?.(newTabKey);
86
74
  restoreTabFilters(newTabKey, tabs[index].filter, debounce);
87
75
  },
88
- [tabs, currentTab, saveCurrentTabFilters, setCurrentTabKey, restoreTabFilters]
76
+ [tabs, setCurrentTabKey, restoreTabFilters]
89
77
  );
90
78
 
91
79
  const updateUrlParam = useCallback(
@@ -97,9 +85,26 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
97
85
  [searchParams, setSearchParams, tabGroupKey]
98
86
  );
99
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
+
100
105
  useEffect(() => {
101
106
  const param = searchParams.get(tabGroupKey);
102
- if (String(param) !== String(currentTab)) {
107
+ if (param !== String(currentTab)) {
103
108
  updateUrlParam(Number(currentTab));
104
109
  }
105
110
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -110,23 +115,15 @@ function ListTabsToolbar(props: ListTabsToolbarProps) {
110
115
  const param = searchParams.get(tabGroupKey);
111
116
  const initialIndex = param != null ? Number(param) : Number(currentTab);
112
117
 
113
- if (param != null && String(initialIndex) !== String(currentTab)) {
118
+ if (param != null && initialIndex !== Number(currentTab)) {
114
119
  setCurrentTab(initialIndex);
115
120
  }
116
121
 
117
- buildFilters(initialIndex, false, false);
122
+ buildFilters(initialIndex, false);
118
123
  initialized.current = true;
119
124
  }
120
125
  // eslint-disable-next-line react-hooks/exhaustive-deps
121
- }, [searchParams, setSearchParams, tabGroupKey, currentTab, setCurrentTab, buildFilters]);
122
-
123
- const handleChange = useCallback(
124
- (_: any, newIndex: number) => {
125
- setCurrentTab(newIndex);
126
- buildFilters(newIndex, true, true);
127
- },
128
- [buildFilters, setCurrentTab]
129
- );
126
+ }, []);
130
127
 
131
128
  return (
132
129
  <Box sx={{ width: '100%' }}>