@applica-software-guru/react-admin 1.5.317 → 1.5.319

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
@@ -107,5 +107,5 @@
107
107
  "type": "module",
108
108
  "types": "dist/index.d.ts",
109
109
  "typings": "dist/index.d.ts",
110
- "version": "1.5.317"
110
+ "version": "1.5.319"
111
111
  }
@@ -1,10 +1,10 @@
1
1
  import { BulkActionsToolbar } from '@/components/ra-lists/BulkActionsToolbar';
2
2
  import { DatagridContextProvider } from '@/components/ra-lists/Datagrid/DatagridContextProvider';
3
- import { Table } from '@mui/material';
3
+ import { Table, Typography } from '@mui/material';
4
4
  import clsx from 'clsx';
5
5
  import difference from 'lodash/difference';
6
6
  import union from 'lodash/union';
7
- import { Identifier, sanitizeListRestProps, useListContext } from 'ra-core';
7
+ import { Identifier, sanitizeListRestProps, useListContext, useTranslate } from 'ra-core';
8
8
  import { FC, cloneElement, createElement, isValidElement, useCallback, useEffect, useMemo, useRef } from 'react';
9
9
  import * as React from 'react';
10
10
  import {
@@ -14,10 +14,10 @@ import {
14
14
  DatagridHeader,
15
15
  DatagridLoading,
16
16
  DatagridRoot,
17
- ListNoResults,
18
17
  PureDatagridBody,
19
18
  DatagridProps as RaDatagridProps
20
19
  } from 'react-admin';
20
+ import { Empty } from '@/components/ra-lists/Empty';
21
21
 
22
22
  const defaultBulkActionButtons = <BulkDeleteButton />;
23
23
 
@@ -106,7 +106,7 @@ const Datagrid = React.forwardRef((props, ref) => {
106
106
  header = DatagridHeader,
107
107
  children,
108
108
  className,
109
- empty = DefaultEmpty,
109
+ empty,
110
110
  expand,
111
111
  bulkActionsToolbar = false,
112
112
  bulkActionButtons = defaultBulkActionButtons,
@@ -123,6 +123,7 @@ const Datagrid = React.forwardRef((props, ref) => {
123
123
  ...rest
124
124
  } = props;
125
125
 
126
+ const translate = useTranslate();
126
127
  const { sort, data, isLoading, onSelect, onToggleItem, selectedIds, setSort, total } = useListContext(props);
127
128
  const hasBulkActions = !!bulkActionButtons !== false;
128
129
  const contextValue = useMemo(() => ({ isRowExpandable, expandSingle }), [isRowExpandable, expandSingle]);
@@ -165,6 +166,17 @@ const Datagrid = React.forwardRef((props, ref) => {
165
166
  [data, isRowSelectable, onSelect, onToggleItem, selectedIds]
166
167
  );
167
168
 
169
+ const DefaultEmpty = (
170
+ <Empty
171
+ sx={{ '& .ApplicaEmpty-icon': { fontSize: '7em' } }}
172
+ title={
173
+ <Typography variant="subtitle1" style={{ color: 'inherit' }} gutterBottom>
174
+ {translate('ra.navigation.no_results')}
175
+ </Typography>
176
+ }
177
+ />
178
+ );
179
+
168
180
  if (isLoading === true) {
169
181
  return (
170
182
  <DatagridLoading
@@ -183,11 +195,7 @@ const Datagrid = React.forwardRef((props, ref) => {
183
195
  * the Datagrid displays the empty component.
184
196
  */
185
197
  if (data == null || data.length === 0 || total === 0) {
186
- if (empty) {
187
- return empty;
188
- }
189
-
190
- return null;
198
+ return empty || DefaultEmpty;
191
199
  }
192
200
 
193
201
  /**
@@ -307,7 +315,5 @@ function sanitizeRestProps(props) {
307
315
  }
308
316
  Datagrid.displayName = 'Datagrid';
309
317
 
310
- const DefaultEmpty = <ListNoResults />;
311
-
312
318
  export { Datagrid };
313
319
  export type { DatagridProps };
@@ -1,9 +1,10 @@
1
1
  /* eslint-disable filenames/match-regex */
2
2
  import { DropboxOutlined } from '@ant-design/icons';
3
- import { Typography } from '@mui/material';
4
- import { styled } from '@mui/material/styles';
3
+ import { Box, SxProps, Typography, styled } from '@mui/material';
5
4
  import { useGetResourceLabel, useResourceContext, useResourceDefinition, useTranslate } from 'ra-core';
6
5
  import * as React from 'react';
6
+ import { CreateButton } from '@/components/ra-buttons';
7
+ import clsx from 'clsx';
7
8
 
8
9
  type EmptyProps = {
9
10
  /**
@@ -23,12 +24,67 @@ type EmptyProps = {
23
24
  **/
24
25
  className?: string;
25
26
  hasCreate?: boolean;
27
+ /**
28
+ * The icon of the empty page.
29
+ *
30
+ * @example <DropboxOutlined />
31
+ * @example <DropboxOutlined style={{ fontSize: '9em' }} />
32
+ **/
33
+ icon?: React.ReactNode;
34
+ /**
35
+ * The title of the empty page.
36
+ *
37
+ * @example 'No data available'
38
+ * @example translate('ra_text')
39
+ **/
40
+ title?: string | React.ReactNode;
41
+ /**
42
+ * The subtitle of the empty page.
43
+ *
44
+ * @example 'Please add some data'
45
+ * @example translate('ra_text')
46
+ **/
47
+ subtitle?: string | React.ReactNode;
48
+ sx?: SxProps;
26
49
  };
27
50
 
28
51
  const StyledToolbar = styled('div')(({ theme }) => ({
29
52
  padding: theme.spacing(2)
30
53
  }));
31
54
 
55
+ const PREFIX = 'ApplicaEmpty';
56
+
57
+ const EmptyClasses = {
58
+ message: `${PREFIX}-message`,
59
+ icon: `${PREFIX}-icon`,
60
+ toolbar: `${PREFIX}-toolbar`
61
+ };
62
+
63
+ const Root = styled('span', {
64
+ name: PREFIX,
65
+ slot: 'Root',
66
+ overridesResolver: (_, styles) => styles.root
67
+ })(({ theme }) => ({
68
+ flex: 1,
69
+ height: 'calc(100vh - 200px)',
70
+ [`& .${EmptyClasses.message}`]: {
71
+ textAlign: 'center',
72
+ opacity: theme.palette.mode === 'light' ? 0.5 : 0.8,
73
+ margin: '0 1em',
74
+ color: theme.palette.mode === 'light' ? 'inherit' : theme.palette.text.primary
75
+ },
76
+
77
+ [`& .${EmptyClasses.icon}`]: {
78
+ fontSize: '9em',
79
+ marginTop: '16px',
80
+ marginBottom: '16px'
81
+ },
82
+
83
+ [`& .${EmptyClasses.toolbar}`]: {
84
+ textAlign: 'center'
85
+ }
86
+ }));
87
+
32
88
  /**
33
89
  * The Empty component is used to display a message when the list is empty.
34
90
  * This component can be used only inside a List component.
@@ -36,7 +92,16 @@ const StyledToolbar = styled('div')(({ theme }) => ({
36
92
  * @example
37
93
  * <List empty={<Empty actions={<Button label="Add" onClick={add} />} />} />
38
94
  */
39
- function Empty({ actions, className, hasCreate: _hasCreate, ...props }: EmptyProps): JSX.Element {
95
+ function Empty({
96
+ actions,
97
+ className,
98
+ hasCreate: _hasCreate,
99
+ icon = <DropboxOutlined className={EmptyClasses.icon} />,
100
+ title,
101
+ subtitle,
102
+ sx,
103
+ ...props
104
+ }: EmptyProps): JSX.Element {
40
105
  const { hasCreate } = useResourceDefinition(props);
41
106
  const canCreate = _hasCreate ?? hasCreate;
42
107
  const resource = useResourceContext(props);
@@ -53,58 +118,30 @@ function Empty({ actions, className, hasCreate: _hasCreate, ...props }: EmptyPro
53
118
  const inviteMessage = translate('ra.page.invite');
54
119
 
55
120
  return (
56
- <Root className={className}>
57
- <div className={EmptyClasses.message}>
58
- <DropboxOutlined className={EmptyClasses.icon} />
121
+ <Root className={clsx(`${PREFIX}-root`, className)} sx={sx}>
122
+ <Box className={EmptyClasses.message}>
123
+ {icon}
59
124
  <Typography variant="h4" paragraph>
60
- {translate(`resources.${resource}.empty`, {
61
- _: emptyMessage
62
- })}
63
- </Typography>
64
- {canCreate ? (
65
- <Typography variant="body1">
66
- {translate(`resources.${resource}.invite`, {
67
- _: inviteMessage
125
+ {title ||
126
+ translate(`resources.${resource}.empty`, {
127
+ _: emptyMessage
68
128
  })}
69
- </Typography>
70
- ) : null}
71
- </div>
72
-
73
- <StyledToolbar className={EmptyClasses.toolbar}>{actions}</StyledToolbar>
129
+ </Typography>
130
+ {subtitle ||
131
+ (canCreate ? (
132
+ <Typography variant="body1">
133
+ {translate(`resources.${resource}.invite`, {
134
+ _: inviteMessage
135
+ })}
136
+ </Typography>
137
+ ) : null)}
138
+ </Box>
139
+ <StyledToolbar className={EmptyClasses.toolbar}>
140
+ {(canCreate ? <CreateButton disableFloatingButton /> : null) || actions}
141
+ </StyledToolbar>
74
142
  </Root>
75
143
  );
76
144
  }
77
145
 
78
- const PREFIX = 'ApplicaEmpty';
79
-
80
- const EmptyClasses = {
81
- message: `${PREFIX}-message`,
82
- icon: `${PREFIX}-icon`,
83
- toolbar: `${PREFIX}-toolbar`
84
- };
85
-
86
- const Root = styled('span', {
87
- name: PREFIX,
88
- overridesResolver: (_, styles) => styles.root
89
- })(({ theme }) => ({
90
- flex: 1,
91
- height: 'calc(100vh - 200px)',
92
- [`& .${EmptyClasses.message}`]: {
93
- textAlign: 'center',
94
- opacity: theme.palette.mode === 'light' ? 0.5 : 0.8,
95
- margin: '0 1em',
96
- color: theme.palette.mode === 'light' ? 'inherit' : theme.palette.text.primary
97
- },
98
-
99
- [`& .${EmptyClasses.icon}`]: {
100
- fontSize: '9em'
101
- },
102
-
103
- [`& .${EmptyClasses.toolbar}`]: {
104
- textAlign: 'center',
105
- marginTop: '2em'
106
- }
107
- }));
108
-
109
146
  export { Empty, EmptyClasses };
110
147
  export type { EmptyProps };
@@ -181,12 +181,19 @@ const StyledList = styled(RaList, { slot: 'root' })(({ theme }) => ({
181
181
  paddingTop: 0,
182
182
  paddingBottom: 0
183
183
  },
184
- // Resolve a defect related to the usage of AntDesin icons with Mantis and React-Admin.
184
+ // Resolve a defect related to the usage of AntDesign icons with Mantis and React-Admin.
185
185
  // These two lines are not needed if you are not using AntDesign icons.
186
186
  '& .icon span': {
187
187
  top: -1,
188
188
  left: -1
189
189
  }
190
+ },
191
+ '& .ApplicaEmpty-root': {
192
+ display: 'flex',
193
+ flexDirection: 'column',
194
+ justifyContent: 'center',
195
+ alignItems: 'center',
196
+ height: 'calc(100vh - 260px)'
190
197
  }
191
198
  },
192
199
 
@@ -1,13 +1,21 @@
1
- import { styled } from '@mui/material/styles';
2
- import { SimpleList as RaSimpleList } from 'react-admin';
1
+ import { SimpleList as RaSimpleList, SimpleListProps, useTranslate } from 'react-admin';
2
+ import { Empty } from '@/components/ra-lists/Empty';
3
+ import { Typography } from '@mui/material';
3
4
 
4
- const SimpleList = styled(RaSimpleList, {
5
- name: 'ApplicaSimpleList',
6
- slot: 'root'
7
- })(({ theme }) => ({
8
- padding: theme.spacing(1),
9
- paddingTop: 0,
10
- paddingBottom: 0
11
- }));
5
+ function SimpleList({ empty, ...props }: SimpleListProps): JSX.Element {
6
+ const translate = useTranslate();
7
+ const DefaultEmpty = (
8
+ <Empty
9
+ sx={{ '& .ApplicaEmpty-icon': { fontSize: '7em' } }}
10
+ title={
11
+ <Typography variant="subtitle1" style={{ color: 'inherit' }} gutterBottom>
12
+ {translate('ra.navigation.no_results')}
13
+ </Typography>
14
+ }
15
+ />
16
+ );
17
+
18
+ return <RaSimpleList {...props} empty={empty || DefaultEmpty} />;
19
+ }
12
20
 
13
21
  export { SimpleList };