@applica-software-guru/react-admin 1.0.46 → 1.0.51
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/bitbucket-pipelines.yml +2 -1
- package/dist/AdminContext.d.ts +5 -10
- package/dist/AdminContext.d.ts.map +1 -1
- package/dist/ApplicaAdmin.d.ts +51 -17
- package/dist/ApplicaAdmin.d.ts.map +1 -1
- package/dist/components/@extended/Breadcrumbs.d.ts +1 -0
- package/dist/components/@extended/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Layout/Drawer/DrawerHeader/DrawerHeaderStyled.d.ts +1 -1
- package/dist/components/MainCard.d.ts +70 -1
- package/dist/components/MainCard.d.ts.map +1 -1
- package/dist/components/Notification.d.ts +2 -2
- package/dist/components/ra-forms/TabbedForm.d.ts +2 -2
- package/dist/components/ra-lists/Datagrid.d.ts +25 -12
- package/dist/components/ra-lists/Datagrid.d.ts.map +1 -1
- package/dist/components/ra-lists/Empty.d.ts +42 -17
- package/dist/components/ra-lists/Empty.d.ts.map +1 -1
- package/dist/components/ra-lists/List.d.ts +8 -6
- package/dist/components/ra-lists/List.d.ts.map +1 -1
- package/dist/components/ra-lists/index.d.ts +1 -1
- package/dist/components/ra-lists/index.d.ts.map +1 -1
- package/dist/contexts/MenuConfigContext.d.ts +34 -12
- package/dist/contexts/MenuConfigContext.d.ts.map +1 -1
- package/dist/contexts/MenuPropTypes.d.ts +1 -0
- package/dist/contexts/MenuPropTypes.d.ts.map +1 -1
- package/dist/dev/index.d.ts +1 -2
- package/dist/dev/index.d.ts.map +1 -1
- package/dist/dev/useCliErrorCatcher.d.ts +57 -29
- package/dist/dev/useCliErrorCatcher.d.ts.map +1 -1
- package/dist/i18n/useI18nCatcher.d.ts +26 -13
- package/dist/i18n/useI18nCatcher.d.ts.map +1 -1
- package/dist/react-admin.cjs.js +44 -44
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +3893 -3886
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +44 -44
- package/dist/react-admin.umd.js.map +1 -1
- package/dist/types.d.ts +54 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/AdminContext.tsx +19 -0
- package/src/{ApplicaAdmin.jsx → ApplicaAdmin.tsx} +115 -50
- package/src/components/{MainCard.jsx → MainCard.tsx} +74 -3
- package/src/components/ra-lists/{Datagrid.jsx → Datagrid.tsx} +14 -3
- package/src/components/ra-lists/{Empty.jsx → Empty.tsx} +31 -2
- package/src/components/ra-lists/{List.jsx → List.tsx} +3 -2
- package/src/contexts/MenuConfigContext.tsx +117 -0
- package/src/contexts/MenuPropTypes.jsx +2 -1
- package/src/dev/useCliErrorCatcher.ts +142 -0
- package/src/i18n/{useI18nCatcher.jsx → useI18nCatcher.ts} +49 -11
- package/src/types.ts +55 -0
- package/src/AdminContext.jsx +0 -24
- package/src/contexts/MenuConfigContext.jsx +0 -93
- package/src/dev/useCliErrorCatcher.jsx +0 -86
- /package/src/components/ra-lists/{index.jsx → index.ts} +0 -0
- /package/src/dev/{index.jsx → index.ts} +0 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Definisce le proprietà di un elemento del menu.
|
|
4
|
+
*/
|
|
5
|
+
export type MenuItemProps = {
|
|
6
|
+
id: string;
|
|
7
|
+
/**
|
|
8
|
+
* Titolo da attribure all'elemento del menu.
|
|
9
|
+
* Il titolo deve essere una stringa localizzata: es. ra.menu.item.foo
|
|
10
|
+
*/
|
|
11
|
+
title: string;
|
|
12
|
+
/**
|
|
13
|
+
* Icona da attribuire all'elemento del menu.
|
|
14
|
+
*/
|
|
15
|
+
icon: React.ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Tipo di elemento del menu.
|
|
18
|
+
* - item: elemento di menu normale
|
|
19
|
+
* - group: gruppo di elementi di menu
|
|
20
|
+
* - collapse: gruppo di elementi di menu con collapse
|
|
21
|
+
*/
|
|
22
|
+
type: 'item' | 'group' | 'collapse';
|
|
23
|
+
/**
|
|
24
|
+
* URL da attribuire all'elemento del menu.
|
|
25
|
+
* Può puntare ad una risorsa o ad una pagina personalizzata purché la stessa sia stata registrata nell'appliazione.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* /entities/user
|
|
29
|
+
* /pages/foo
|
|
30
|
+
*/
|
|
31
|
+
url: string;
|
|
32
|
+
/**
|
|
33
|
+
* Indica se l'elemento del menu è una risorsa.
|
|
34
|
+
*/
|
|
35
|
+
resource: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Elenco dei ruoli che possono accedere all'elemento del menu.
|
|
38
|
+
* Se l'utente collegato non contiene almeno uno dei ruoli specificati l'elemento del menu non viene visualizzato.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ["ROLE_ADMIN", "ROLE_USER"]
|
|
42
|
+
*/
|
|
43
|
+
roles: string[];
|
|
44
|
+
/**
|
|
45
|
+
* Elenco dei figli dell'elemento del menu.
|
|
46
|
+
* Valido solo per i tipi "group" e "collapse".
|
|
47
|
+
*/
|
|
48
|
+
children?: MenuItemProps[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Indica come deve essere configurato il menu dell'applicazione.
|
|
52
|
+
*/
|
|
53
|
+
export type MenuProps = MenuItemProps[];
|
|
54
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CoreAdminContext, CoreAdminContextProps } from 'react-admin';
|
|
2
|
+
|
|
3
|
+
import { ScrollTop } from './components';
|
|
4
|
+
import { ThemeCustomization } from './themes';
|
|
5
|
+
|
|
6
|
+
const AdminContext = ({ children, theme, ...props }: CoreAdminContextProps) => (
|
|
7
|
+
<CoreAdminContext {...props}>
|
|
8
|
+
<ThemeCustomization themeOverrides={theme}>
|
|
9
|
+
<ScrollTop>
|
|
10
|
+
{/** @ts-ignore */}
|
|
11
|
+
{children}
|
|
12
|
+
</ScrollTop>
|
|
13
|
+
</ThemeCustomization>
|
|
14
|
+
</CoreAdminContext>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
AdminContext.displayName = 'ApplicaAdminContext';
|
|
18
|
+
|
|
19
|
+
export default AdminContext;
|
|
@@ -4,13 +4,16 @@ import { Layout, MainIcon, Notification, SmallIcon } from './components';
|
|
|
4
4
|
import { createI18nProvider, useI18nCatcher, useI18nLanguages } from './i18n';
|
|
5
5
|
|
|
6
6
|
import Admin from './Admin';
|
|
7
|
+
import { AdminProps } from 'react-admin';
|
|
8
|
+
import { I18nCatcherBodyBuilderResultProps } from './i18n/useI18nCatcher';
|
|
9
|
+
import { MenuProps } from 'src/types';
|
|
7
10
|
import PropTypes from 'prop-types';
|
|
8
11
|
import { QueryClient } from 'react-query';
|
|
9
12
|
import { useMemo } from 'react';
|
|
10
13
|
|
|
11
|
-
const languageResponseMapper = (response) =>
|
|
14
|
+
const languageResponseMapper = (response: any) =>
|
|
12
15
|
response.reduce(
|
|
13
|
-
(messages, message) => ({
|
|
16
|
+
(messages: any, message: any) => ({
|
|
14
17
|
...messages,
|
|
15
18
|
[message.lang]: {
|
|
16
19
|
...(messages[message.lang] || {}),
|
|
@@ -20,8 +23,8 @@ const languageResponseMapper = (response) =>
|
|
|
20
23
|
{}
|
|
21
24
|
);
|
|
22
25
|
|
|
23
|
-
const i18nBodyRequestMapper = (
|
|
24
|
-
lang
|
|
26
|
+
const i18nBodyRequestMapper = (lang: string, message: string): I18nCatcherBodyBuilderResultProps => ({
|
|
27
|
+
lang,
|
|
25
28
|
code: message,
|
|
26
29
|
text: message
|
|
27
30
|
});
|
|
@@ -34,22 +37,125 @@ const queryClient = new QueryClient({
|
|
|
34
37
|
}
|
|
35
38
|
});
|
|
36
39
|
|
|
40
|
+
export type ApplicaAdminProps = AdminProps & {
|
|
41
|
+
theme: any;
|
|
42
|
+
apiUrl: string;
|
|
43
|
+
defaultLocale: string;
|
|
44
|
+
development: boolean;
|
|
45
|
+
logoMain: any;
|
|
46
|
+
logoIcon: any;
|
|
47
|
+
menu: MenuProps;
|
|
48
|
+
name: string;
|
|
49
|
+
version: string;
|
|
50
|
+
dataProvider: any;
|
|
51
|
+
authProvider: any;
|
|
52
|
+
notification: string;
|
|
53
|
+
disableNotification: boolean;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Definisce un'applicazione super figa basata su React Admi, Mantis Theme ed il nostro stile.
|
|
58
|
+
* Ogni applicazione che crei dovrebbe partire con un 'C'era una volta un ApplicaAdmin'.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Esempio di utilizzo
|
|
62
|
+
* import { ApplicaAdmin } from '@applica-software-guru/react-admin';
|
|
63
|
+
* import { createAuthProvider } from '@applica-software-guru/iam-client';
|
|
64
|
+
* import { createDataProvider } from '@applica-software-guru/crud-client';
|
|
65
|
+
* import * as entities from './entities';
|
|
66
|
+
*
|
|
67
|
+
* const apiUrl = "https://bimbobruno.applica.guru/api";
|
|
68
|
+
* const authProvider = createAuthProvider({ apiUrl });
|
|
69
|
+
* const getToken = async () => await authProvider.getToken();
|
|
70
|
+
* const getHeaders = async () => await authProvider.getHeaders();
|
|
71
|
+
*
|
|
72
|
+
* const dataProvider = createDataProvider({ apiUrl, getToken, getHeaders });
|
|
73
|
+
*
|
|
74
|
+
* const App = () => (
|
|
75
|
+
* <ApplicaAdmin
|
|
76
|
+
* apiUrl="https://api.applica.software-guru.it"
|
|
77
|
+
* dataProvider={dataProvider}
|
|
78
|
+
* authProvider={authProvider}
|
|
79
|
+
* menu={menu}
|
|
80
|
+
* name="Applica Admin"
|
|
81
|
+
* version="1.0.0">
|
|
82
|
+
* <Resource name="entities/user" {...entities.user} />
|
|
83
|
+
* </ApplicaAdmin>
|
|
84
|
+
*
|
|
85
|
+
* @param {ApplicaAdminProps}
|
|
86
|
+
* @returns {React.ReactElement}
|
|
87
|
+
*/
|
|
37
88
|
const ApplicaAdmin = ({
|
|
89
|
+
/**
|
|
90
|
+
* Eventuali configurazioni aggiuntive da passare al tema.
|
|
91
|
+
* @remarks Questo tema è basato su Mantis Theme (https://mantisdashboard.io/)
|
|
92
|
+
*
|
|
93
|
+
* @see https://marmelab.com/react-admin/Theming.html
|
|
94
|
+
* @see https://material-ui.com/customization/theming/
|
|
95
|
+
*/
|
|
38
96
|
theme,
|
|
97
|
+
/**
|
|
98
|
+
* URL dell'API da utilizzare nell'applicazione.
|
|
99
|
+
* Sebbene venga già definito un dataProvider ed authProvider di default, è possibile che l'app
|
|
100
|
+
* utilizzi l'apiUrl specificato per ulteriori operazioni (es. getstione delle notifiche).
|
|
101
|
+
*/
|
|
39
102
|
apiUrl,
|
|
103
|
+
/**
|
|
104
|
+
* La lingua di default da utilizzare nell'applicazione.
|
|
105
|
+
*/
|
|
40
106
|
defaultLocale,
|
|
107
|
+
/**
|
|
108
|
+
* Se impostato a true, l'applicazione lavora in modalità sviluppo.
|
|
109
|
+
* La modalità sviluppo è utile per effettuare test e debug ed esegue attività che non sono
|
|
110
|
+
* consigliate in produzione (es. cattura e inoltro dei messaggi non localizzati).
|
|
111
|
+
*/
|
|
41
112
|
development,
|
|
113
|
+
/**
|
|
114
|
+
* Il logo da visualizzare nella barra laterale quando il menu è espanso lateralmente.
|
|
115
|
+
*/
|
|
42
116
|
logoMain,
|
|
117
|
+
/**
|
|
118
|
+
* Eventuale logo da visualizzare nella barra laterale quando il menu è ridotto lateralmente.
|
|
119
|
+
*/
|
|
43
120
|
logoIcon,
|
|
121
|
+
/**
|
|
122
|
+
* Configurazione del menu da visualizzare nell'applicazione.
|
|
123
|
+
*/
|
|
44
124
|
menu,
|
|
125
|
+
/**
|
|
126
|
+
* Nome dell'applicazione da mostrare nell'header.
|
|
127
|
+
*/
|
|
45
128
|
name,
|
|
129
|
+
/**
|
|
130
|
+
* Versione dell'applicazione da mostrare nel footer.
|
|
131
|
+
*/
|
|
46
132
|
version,
|
|
133
|
+
/**
|
|
134
|
+
* Il provider di autenticazione da utilizzare nell'applicazione.
|
|
135
|
+
*/
|
|
47
136
|
dataProvider,
|
|
137
|
+
/**
|
|
138
|
+
* Il provider di dati da utilizzare nell'applicazione.
|
|
139
|
+
*/
|
|
48
140
|
authProvider,
|
|
141
|
+
/**
|
|
142
|
+
* Indica il nome della risorsa REST da utilizzare per la gestione delle notifiche.
|
|
143
|
+
* @example
|
|
144
|
+
* // In questo caso, le notifiche verranno gestite tramite la risorsa "entities/notification"
|
|
145
|
+
* <ApplicaAdmin notification="entities/notification" />
|
|
146
|
+
*/
|
|
49
147
|
notification,
|
|
148
|
+
/**
|
|
149
|
+
* Indica se le notifiche devono essere disabilitate.
|
|
150
|
+
* Se le notifiche sono abilitate comparirà automaticamente un'icona in alto a destra nell'header.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* // In questo caso, le notifiche verranno disabilitate
|
|
154
|
+
* <ApplicaAdmin disableNotification />
|
|
155
|
+
*/
|
|
50
156
|
disableNotification,
|
|
51
157
|
...props
|
|
52
|
-
}) => {
|
|
158
|
+
}: ApplicaAdminProps) => {
|
|
53
159
|
const languages = useI18nLanguages({
|
|
54
160
|
apiUrl,
|
|
55
161
|
endpoint: '/i18n/messages',
|
|
@@ -66,9 +172,9 @@ const ApplicaAdmin = ({
|
|
|
66
172
|
useCliErrorCatcher({
|
|
67
173
|
apiUrl,
|
|
68
174
|
endpoint: '/cli/error',
|
|
69
|
-
catcherFn: (error) => {
|
|
70
|
-
|
|
71
|
-
|
|
175
|
+
catcherFn: (error: any): CatchResult => {
|
|
176
|
+
const errorMessage = error?.toString();
|
|
177
|
+
const knownErrors = [
|
|
72
178
|
// @see https://github.com/marmelab/react-admin/pull/8884
|
|
73
179
|
'Invalid prop `file` of type `string` supplied to `FileInputPreview`, expected `object`.',
|
|
74
180
|
'Failed prop type: Invalid prop `checked` of type `string` supplied to `ForwardRef(Switch)`, expected `boolean`.',
|
|
@@ -87,7 +193,7 @@ const ApplicaAdmin = ({
|
|
|
87
193
|
});
|
|
88
194
|
|
|
89
195
|
const layout = useMemo(
|
|
90
|
-
() => (props) => {
|
|
196
|
+
() => (props: any) => {
|
|
91
197
|
const _logoMain = name ? <MainIcon title={name} /> : logoMain;
|
|
92
198
|
const _logoIcon = name ? <SmallIcon title={name} /> : logoIcon;
|
|
93
199
|
return (
|
|
@@ -146,59 +252,18 @@ ApplicaAdmin.defaultProps = {
|
|
|
146
252
|
|
|
147
253
|
ApplicaAdmin.propTypes = {
|
|
148
254
|
...Admin.propTypes,
|
|
149
|
-
/**
|
|
150
|
-
* Eventuali configurazioni aggiuntive da passare al tema.
|
|
151
|
-
*/
|
|
152
255
|
theme: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
|
153
|
-
/**
|
|
154
|
-
* URL dell'API da utilizzare nell'applicazione.
|
|
155
|
-
*/
|
|
156
256
|
apiUrl: PropTypes.string.isRequired,
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* La lingua di default da utilizzare nell'applicazione.
|
|
160
|
-
*/
|
|
161
257
|
defaultLocale: PropTypes.string,
|
|
162
|
-
/**
|
|
163
|
-
* Se impostato a true, l'applicazione lavora in modalità sviluppo.
|
|
164
|
-
* In questa modalità, per esempio, l'applicazione è in grando di catturare ed inoltrare al server eventuali messaggi non localizzati.
|
|
165
|
-
*/
|
|
166
258
|
development: PropTypes.bool,
|
|
167
|
-
/**
|
|
168
|
-
* Il logo da visualizzare nella barra laterale quando il menu è espanso lateralmente.
|
|
169
|
-
*/
|
|
170
259
|
logoMain: PropTypes.node,
|
|
171
|
-
/**
|
|
172
|
-
* Eventuale logo da visualizzare nella barra laterale quando il menu è ridotto lateralmente.
|
|
173
|
-
*/
|
|
174
260
|
logoIcon: PropTypes.node,
|
|
175
|
-
/**
|
|
176
|
-
* Configurazione del menu da visualizzare nell'applicazione.
|
|
177
|
-
*/
|
|
178
261
|
menu: PropTypes.arrayOf(MenuPropTypes),
|
|
179
|
-
/**
|
|
180
|
-
* Nome dell'applicazione.
|
|
181
|
-
*/
|
|
182
262
|
name: PropTypes.string,
|
|
183
|
-
/**
|
|
184
|
-
* Versione dell'applicazione.
|
|
185
|
-
*/
|
|
186
263
|
version: PropTypes.string,
|
|
187
|
-
/**
|
|
188
|
-
* Il provider di autenticazione da utilizzare nell'applicazione.
|
|
189
|
-
*/
|
|
190
264
|
authProvider: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
191
|
-
/**
|
|
192
|
-
* Il provider di dati da utilizzare nell'applicazione.
|
|
193
|
-
*/
|
|
194
265
|
dataProvider: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
195
|
-
/**
|
|
196
|
-
* Indica il nome della risorsa REST da utilizzare per la gestione delle notifiche.
|
|
197
|
-
*/
|
|
198
266
|
notification: PropTypes.string,
|
|
199
|
-
/**
|
|
200
|
-
* Indica se le notifiche devono essere disabilitate.
|
|
201
|
-
*/
|
|
202
267
|
disableNotification: PropTypes.bool
|
|
203
268
|
};
|
|
204
269
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Card, CardContent, CardHeader, Divider, Typography } from '@mui/material';
|
|
2
|
-
import { lighten, useTheme } from '@mui/material/styles';
|
|
2
|
+
import { SxProps, lighten, useTheme } from '@mui/material/styles';
|
|
3
3
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { forwardRef } from 'react';
|
|
@@ -9,6 +9,74 @@ const headerSX = {
|
|
|
9
9
|
'& .MuiCardHeader-action': { m: '0px auto', alignSelf: 'center' }
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
export type MainCardProps = {
|
|
13
|
+
/**
|
|
14
|
+
* Indicates if the card must be rendered with a border.
|
|
15
|
+
*/
|
|
16
|
+
border?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Indicates if the card must be rendered with a box shadow.
|
|
19
|
+
*/
|
|
20
|
+
boxShadow?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The content of the card.
|
|
23
|
+
*/
|
|
24
|
+
children?: React.ReactNode | React.ReactNode[];
|
|
25
|
+
/**
|
|
26
|
+
* The subheader of the card.
|
|
27
|
+
*/
|
|
28
|
+
subheader?: React.ReactNode | string;
|
|
29
|
+
/**
|
|
30
|
+
* Indicates if the card must be rendered with a content.
|
|
31
|
+
*/
|
|
32
|
+
content?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The class name of the content.
|
|
35
|
+
*/
|
|
36
|
+
contentClass?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The style of the content.
|
|
39
|
+
*/
|
|
40
|
+
contentSX?: SxProps | any;
|
|
41
|
+
/**
|
|
42
|
+
* Indicates if the title of the card must be rendered with a dark color.
|
|
43
|
+
*/
|
|
44
|
+
darkTitle?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Indicates if the card must be rendered with a divider.
|
|
47
|
+
*/
|
|
48
|
+
divider?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* The elevation of the card.
|
|
51
|
+
*/
|
|
52
|
+
elevation?: number;
|
|
53
|
+
/**
|
|
54
|
+
* The secondary content of the card.
|
|
55
|
+
*/
|
|
56
|
+
secondary?: React.ReactNode | string | object;
|
|
57
|
+
/**
|
|
58
|
+
* The shadow of the card.
|
|
59
|
+
* @example '0px 0px 0px 0px rgba(0,0,0,0.2)'
|
|
60
|
+
*/
|
|
61
|
+
shadow?: string;
|
|
62
|
+
/**
|
|
63
|
+
* The style of the card.
|
|
64
|
+
*/
|
|
65
|
+
sx?: SxProps | any;
|
|
66
|
+
/**
|
|
67
|
+
* The title of the card.
|
|
68
|
+
*/
|
|
69
|
+
title?: React.ReactNode | string | object;
|
|
70
|
+
/**
|
|
71
|
+
* Indicates if the card must be rendered as a modal.
|
|
72
|
+
*/
|
|
73
|
+
modal?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* The color of the card.
|
|
76
|
+
*/
|
|
77
|
+
color?: 'default' | 'primary' | 'secondary';
|
|
78
|
+
};
|
|
79
|
+
|
|
12
80
|
const MainCard = forwardRef(
|
|
13
81
|
(
|
|
14
82
|
{
|
|
@@ -28,14 +96,15 @@ const MainCard = forwardRef(
|
|
|
28
96
|
modal = false,
|
|
29
97
|
color = 'default',
|
|
30
98
|
...others
|
|
31
|
-
},
|
|
99
|
+
}: MainCardProps,
|
|
32
100
|
ref
|
|
33
101
|
) => {
|
|
34
|
-
const theme = useTheme();
|
|
102
|
+
const theme = useTheme() as any;
|
|
35
103
|
boxShadow = theme.palette.mode === 'dark' ? boxShadow || true : boxShadow;
|
|
36
104
|
return (
|
|
37
105
|
<Card
|
|
38
106
|
elevation={elevation || 0}
|
|
107
|
+
// @ts-ignore
|
|
39
108
|
ref={ref}
|
|
40
109
|
{...others}
|
|
41
110
|
sx={{
|
|
@@ -69,6 +138,7 @@ const MainCard = forwardRef(
|
|
|
69
138
|
}}
|
|
70
139
|
>
|
|
71
140
|
{!darkTitle && title && (
|
|
141
|
+
/** @ts-ignore */
|
|
72
142
|
<CardHeader
|
|
73
143
|
sx={headerSX}
|
|
74
144
|
titleTypographyProps={{ variant: 'subtitle1' }}
|
|
@@ -77,6 +147,7 @@ const MainCard = forwardRef(
|
|
|
77
147
|
subheader={subheader}
|
|
78
148
|
/>
|
|
79
149
|
)}
|
|
150
|
+
{/** @ts-ignore */}
|
|
80
151
|
{darkTitle && title && <CardHeader sx={headerSX} title={<Typography variant="h4">{title}</Typography>} action={secondary} />}
|
|
81
152
|
{title && divider && <Divider />}
|
|
82
153
|
{content && <CardContent sx={contentSX}>{children}</CardContent>}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Datagrid as RaDatagrid } from 'react-admin';
|
|
1
|
+
import { DatagridProps, Datagrid as RaDatagrid } from 'react-admin';
|
|
2
|
+
|
|
2
3
|
import { styled } from '@mui/material/styles';
|
|
3
4
|
|
|
4
5
|
const ApplicaStyledDatagrid = styled(RaDatagrid, {
|
|
5
|
-
name: '
|
|
6
|
+
name: 'ApplicaDatagrid',
|
|
6
7
|
slot: 'root'
|
|
7
8
|
})(() => ({
|
|
8
9
|
// Resolve an issue related to the visualization of the bulk actions toolbar.
|
|
@@ -29,7 +30,17 @@ const ApplicaStyledDatagrid = styled(RaDatagrid, {
|
|
|
29
30
|
}
|
|
30
31
|
}));
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
/**
|
|
34
|
+
* This component is a wrapper of the React-Admin Datagrid component.
|
|
35
|
+
* It is used to customize the Datagrid component.
|
|
36
|
+
* It is used by the List component.
|
|
37
|
+
* It is not meant to be used directly.
|
|
38
|
+
* Thsi version is designed by Applica for Mantis and expose few overrides on css styles based on this theme.
|
|
39
|
+
*
|
|
40
|
+
* @param {DatagridProps} props
|
|
41
|
+
* @returns {JSX.Element}
|
|
42
|
+
*/
|
|
43
|
+
const Datagrid = (props: DatagridProps): JSX.Element => <ApplicaStyledDatagrid {...props} />;
|
|
33
44
|
|
|
34
45
|
Datagrid.propTypes = {
|
|
35
46
|
...RaDatagrid.propTypes
|
|
@@ -8,11 +8,40 @@ import PropTypes from 'prop-types';
|
|
|
8
8
|
import { Typography } from '@mui/material';
|
|
9
9
|
import { styled } from '@mui/material/styles';
|
|
10
10
|
|
|
11
|
+
export type EmptyProps = {
|
|
12
|
+
/**
|
|
13
|
+
* The actions of the empty page.
|
|
14
|
+
*
|
|
15
|
+
* @example <Button label="Refresh" onClick={refresh} />
|
|
16
|
+
* @example <Button label="Add" onClick={add} />
|
|
17
|
+
* @example <Button label="Export" onClick={export} />
|
|
18
|
+
* @example <Button label="Import" onClick={import} />
|
|
19
|
+
**/
|
|
20
|
+
actions?: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* The class name of the empty page.
|
|
23
|
+
*
|
|
24
|
+
* @example 'my-custom-empty'
|
|
25
|
+
* @example 'my-custom-empty my-custom-empty--full-width'
|
|
26
|
+
**/
|
|
27
|
+
className?: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
11
30
|
const StyledToolbar = styled('div')(({ theme }) => ({
|
|
12
31
|
padding: theme.spacing(2)
|
|
13
32
|
}));
|
|
14
33
|
|
|
15
|
-
|
|
34
|
+
/**
|
|
35
|
+
* The Empty component is used to display a message when the list is empty.
|
|
36
|
+
* This component can be used only inside a List component.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* <List empty={<Empty actions={<Button label="Add" onClick={add} />} />} />
|
|
40
|
+
*
|
|
41
|
+
* @param {EmptyProps}
|
|
42
|
+
* @returns {JSX.Element}
|
|
43
|
+
*/
|
|
44
|
+
const Empty = ({ actions, className, ...props }: EmptyProps): JSX.Element => {
|
|
16
45
|
const { hasCreate } = useResourceDefinition(props);
|
|
17
46
|
const resource = useResourceContext(props);
|
|
18
47
|
|
|
@@ -50,7 +79,7 @@ const Empty = ({ actions, className, ...props }) => {
|
|
|
50
79
|
);
|
|
51
80
|
};
|
|
52
81
|
|
|
53
|
-
const PREFIX = '
|
|
82
|
+
const PREFIX = 'ApplicaEmpty';
|
|
54
83
|
|
|
55
84
|
export const EmptyClasses = {
|
|
56
85
|
message: `${PREFIX}-message`,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ListProps, List as RaList } from 'react-admin';
|
|
2
|
+
|
|
1
3
|
import MainCard from '../MainCard';
|
|
2
|
-
import { List as RaList } from 'react-admin';
|
|
3
4
|
import { styled } from '@mui/system';
|
|
4
5
|
|
|
5
6
|
const ApplicaStyledList = styled(RaList, {
|
|
@@ -63,7 +64,7 @@ const ApplicaStyledList = styled(RaList, {
|
|
|
63
64
|
}
|
|
64
65
|
}));
|
|
65
66
|
|
|
66
|
-
const List = (props) => {
|
|
67
|
+
const List = (props: ListProps): JSX.Element => {
|
|
67
68
|
return (
|
|
68
69
|
<MainCard content={false}>
|
|
69
70
|
<ApplicaStyledList {...RaList.defaultProps} {...props} />
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import MenuPropTypes from './MenuPropTypes';
|
|
2
|
+
import { MenuProps } from '../types';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { createContext } from 'react';
|
|
5
|
+
import { useLocalStorage } from '../hooks';
|
|
6
|
+
|
|
7
|
+
export type MenuConfigContextProps = {
|
|
8
|
+
openItem: string[];
|
|
9
|
+
openComponent: string;
|
|
10
|
+
selectedID: string | null;
|
|
11
|
+
drawerOpen: boolean;
|
|
12
|
+
componentDrawerOpen: boolean;
|
|
13
|
+
menuDashboard: any;
|
|
14
|
+
error: any;
|
|
15
|
+
groups: MenuProps;
|
|
16
|
+
activeItem: (openItem: string[]) => void;
|
|
17
|
+
activeComponent: (openComponent: string) => void;
|
|
18
|
+
openDrawer: (drawerOpen: boolean) => void;
|
|
19
|
+
openComponentDrawer: (componentDrawerOpen: boolean) => void;
|
|
20
|
+
activeID: (selectedID: string | null) => void;
|
|
21
|
+
getMenuSuccess: (menuDashboard: any) => void;
|
|
22
|
+
hasError: (error: any) => void;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const initialState = {
|
|
26
|
+
openItem: ['dashboard'],
|
|
27
|
+
openComponent: 'buttons',
|
|
28
|
+
selectedID: null,
|
|
29
|
+
drawerOpen: false,
|
|
30
|
+
componentDrawerOpen: true,
|
|
31
|
+
menuDashboard: {},
|
|
32
|
+
error: null
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const MenuConfigContext = createContext(initialState);
|
|
36
|
+
|
|
37
|
+
export type MenuConfigProviderProps = {
|
|
38
|
+
menu: MenuProps;
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const MenuConfigProvider = ({ menu: groups, children }: MenuConfigProviderProps) => {
|
|
43
|
+
const [menu, setMenu] = useLocalStorage('menu-config', { ...initialState });
|
|
44
|
+
|
|
45
|
+
const activeItem = (openItem: string) => {
|
|
46
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
47
|
+
...menu,
|
|
48
|
+
openItem
|
|
49
|
+
}));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const activeID = (selectedID: string) => {
|
|
53
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
54
|
+
...menu,
|
|
55
|
+
selectedID
|
|
56
|
+
}));
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const activeComponent = (openComponent: string) => {
|
|
60
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
61
|
+
...menu,
|
|
62
|
+
openComponent
|
|
63
|
+
}));
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const openDrawer = (drawerOpen: boolean) => {
|
|
67
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
68
|
+
...menu,
|
|
69
|
+
drawerOpen
|
|
70
|
+
}));
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const openComponentDrawer = (componentDrawerOpen: boolean) => {
|
|
74
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
75
|
+
...menu,
|
|
76
|
+
componentDrawerOpen
|
|
77
|
+
}));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const getMenuSuccess = (menuDashboard: any) => {
|
|
81
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
82
|
+
...menu,
|
|
83
|
+
menuDashboard
|
|
84
|
+
}));
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const hasError = (error: any) => {
|
|
88
|
+
setMenu((menu: MenuConfigContextProps) => ({
|
|
89
|
+
...menu,
|
|
90
|
+
error
|
|
91
|
+
}));
|
|
92
|
+
};
|
|
93
|
+
return (
|
|
94
|
+
<MenuConfigContext.Provider
|
|
95
|
+
value={{
|
|
96
|
+
...menu,
|
|
97
|
+
groups,
|
|
98
|
+
activeItem,
|
|
99
|
+
activeComponent,
|
|
100
|
+
openDrawer,
|
|
101
|
+
openComponentDrawer,
|
|
102
|
+
activeID,
|
|
103
|
+
getMenuSuccess,
|
|
104
|
+
hasError
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
{children}
|
|
108
|
+
</MenuConfigContext.Provider>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
MenuConfigProvider.propTypes = {
|
|
113
|
+
children: PropTypes.node,
|
|
114
|
+
menu: PropTypes.arrayOf(MenuPropTypes)
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export { MenuConfigContext, MenuConfigProvider };
|
|
@@ -13,7 +13,8 @@ const MenuPropTypes = PropTypes.shape({
|
|
|
13
13
|
icon: PropTypes.elementType,
|
|
14
14
|
url: PropTypes.string,
|
|
15
15
|
parent: PropTypes.shape(lazy(() => MenuPropTypes)),
|
|
16
|
-
children: PropTypes.arrayOf(lazy(() => MenuPropTypes))
|
|
16
|
+
children: PropTypes.arrayOf(lazy(() => MenuPropTypes)),
|
|
17
|
+
resource: PropTypes.bool
|
|
17
18
|
});
|
|
18
19
|
|
|
19
20
|
export default MenuPropTypes;
|