@applica-software-guru/react-admin 1.5.314 → 1.5.316
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/dist/components/Layout/Provider.d.ts.map +1 -1
- package/dist/components/ra-lists/Empty.d.ts +2 -1
- package/dist/components/ra-lists/Empty.d.ts.map +1 -1
- package/dist/components/ra-lists/List.d.ts.map +1 -1
- package/dist/components/ra-lists/ListView.d.ts.map +1 -1
- package/dist/react-admin.cjs.js +43 -43
- package/dist/react-admin.cjs.js.gz +0 -0
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +4214 -4202
- package/dist/react-admin.es.js.gz +0 -0
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +39 -39
- package/dist/react-admin.umd.js.gz +0 -0
- package/dist/react-admin.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Layout/Provider.tsx +4 -1
- package/src/components/ra-lists/Empty.tsx +8 -6
- package/src/components/ra-lists/List.tsx +2 -22
- package/src/components/ra-lists/ListView.tsx +39 -7
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import { Dialog, useMediaQuery, useTheme } from '@mui/material';
|
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
import { UseGetIdentityResult, useAuthProvider, useGetIdentity } from 'ra-core';
|
|
8
8
|
import { createContext, forwardRef, useCallback, useContext, useEffect, useMemo, useReducer, useState } from 'react';
|
|
9
|
+
import { useLoading } from 'react-admin';
|
|
9
10
|
|
|
10
11
|
enum LayoutActionType {
|
|
11
12
|
UPDATE_MEDIA = 'updateMedia',
|
|
@@ -154,6 +155,7 @@ function LayoutProvider(props: ILayoutProviderProps) {
|
|
|
154
155
|
const handlePasswordChange = useCallback(() => setNeedToChangePassword(false), []);
|
|
155
156
|
const value = useMemo(() => ({ state, dispatch }), [state, dispatch]);
|
|
156
157
|
const { logoIcon, logoMain, enableNotification, notification } = props;
|
|
158
|
+
const isLayoutLoading = useLoading();
|
|
157
159
|
|
|
158
160
|
useEffect(() => {
|
|
159
161
|
dispatch({
|
|
@@ -216,6 +218,7 @@ function LayoutProvider(props: ILayoutProviderProps) {
|
|
|
216
218
|
}, [theme.palette.mode]);
|
|
217
219
|
|
|
218
220
|
useEffect(() => {
|
|
221
|
+
if (isLayoutLoading) return;
|
|
219
222
|
// Check if authProvider contains a method called isImpersonating
|
|
220
223
|
if (!authProvider.isImpersonating) {
|
|
221
224
|
// eslint-disable-next-line no-console
|
|
@@ -225,7 +228,7 @@ function LayoutProvider(props: ILayoutProviderProps) {
|
|
|
225
228
|
authProvider?.isImpersonating().then((isImpersonating: boolean) => {
|
|
226
229
|
setNeedToChangePassword(!isImpersonating && identity?.data?.needToChangePassword === true);
|
|
227
230
|
});
|
|
228
|
-
}, [identity?.data?.needToChangePassword, authProvider]);
|
|
231
|
+
}, [identity?.data?.needToChangePassword, authProvider, isLayoutLoading]);
|
|
229
232
|
|
|
230
233
|
return (
|
|
231
234
|
<LayoutContext.Provider value={value}>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable filenames/match-regex */
|
|
2
|
-
import {
|
|
2
|
+
import { DropboxOutlined } from '@ant-design/icons';
|
|
3
3
|
import { Typography } from '@mui/material';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { useGetResourceLabel, useResourceContext, useResourceDefinition, useTranslate } from 'ra-core';
|
|
@@ -22,6 +22,7 @@ type EmptyProps = {
|
|
|
22
22
|
* @example 'my-custom-empty my-custom-empty--full-width'
|
|
23
23
|
**/
|
|
24
24
|
className?: string;
|
|
25
|
+
hasCreate?: boolean;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
const StyledToolbar = styled('div')(({ theme }) => ({
|
|
@@ -35,8 +36,9 @@ const StyledToolbar = styled('div')(({ theme }) => ({
|
|
|
35
36
|
* @example
|
|
36
37
|
* <List empty={<Empty actions={<Button label="Add" onClick={add} />} />} />
|
|
37
38
|
*/
|
|
38
|
-
function Empty({ actions, className, ...props }: EmptyProps): JSX.Element {
|
|
39
|
+
function Empty({ actions, className, hasCreate: _hasCreate, ...props }: EmptyProps): JSX.Element {
|
|
39
40
|
const { hasCreate } = useResourceDefinition(props);
|
|
41
|
+
const canCreate = _hasCreate ?? hasCreate;
|
|
40
42
|
const resource = useResourceContext(props);
|
|
41
43
|
|
|
42
44
|
const translate = useTranslate();
|
|
@@ -53,13 +55,13 @@ function Empty({ actions, className, ...props }: EmptyProps): JSX.Element {
|
|
|
53
55
|
return (
|
|
54
56
|
<Root className={className}>
|
|
55
57
|
<div className={EmptyClasses.message}>
|
|
56
|
-
<
|
|
58
|
+
<DropboxOutlined className={EmptyClasses.icon} />
|
|
57
59
|
<Typography variant="h4" paragraph>
|
|
58
60
|
{translate(`resources.${resource}.empty`, {
|
|
59
61
|
_: emptyMessage
|
|
60
62
|
})}
|
|
61
63
|
</Typography>
|
|
62
|
-
{
|
|
64
|
+
{canCreate ? (
|
|
63
65
|
<Typography variant="body1">
|
|
64
66
|
{translate(`resources.${resource}.invite`, {
|
|
65
67
|
_: inviteMessage
|
|
@@ -86,6 +88,7 @@ const Root = styled('span', {
|
|
|
86
88
|
overridesResolver: (_, styles) => styles.root
|
|
87
89
|
})(({ theme }) => ({
|
|
88
90
|
flex: 1,
|
|
91
|
+
height: 'calc(100vh - 200px)',
|
|
89
92
|
[`& .${EmptyClasses.message}`]: {
|
|
90
93
|
textAlign: 'center',
|
|
91
94
|
opacity: theme.palette.mode === 'light' ? 0.5 : 0.8,
|
|
@@ -94,8 +97,7 @@ const Root = styled('span', {
|
|
|
94
97
|
},
|
|
95
98
|
|
|
96
99
|
[`& .${EmptyClasses.icon}`]: {
|
|
97
|
-
|
|
98
|
-
height: '9em'
|
|
100
|
+
fontSize: '9em'
|
|
99
101
|
},
|
|
100
102
|
|
|
101
103
|
[`& .${EmptyClasses.toolbar}`]: {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { MainCard } from '@/components/MainCard';
|
|
2
1
|
import { ListView } from '@/components/ra-lists/ListView';
|
|
3
2
|
import { styled } from '@mui/system';
|
|
4
3
|
import { ListBase, RaRecord } from 'ra-core';
|
|
5
|
-
import
|
|
4
|
+
import { ReactElement } from 'react';
|
|
6
5
|
import { ListProps } from 'react-admin';
|
|
7
6
|
import { Pagination } from '@/components/Pagination/Pagination';
|
|
8
|
-
import { FilterSidebar } from './FilterSidebar';
|
|
9
7
|
import { ListViewProvider } from './ListViewProvider';
|
|
10
8
|
|
|
11
9
|
/**
|
|
@@ -198,25 +196,7 @@ const StyledList = styled(RaList, { slot: 'root' })(({ theme }) => ({
|
|
|
198
196
|
}));
|
|
199
197
|
|
|
200
198
|
function List(props: ListProps): ReactElement {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
// Check if 'aside' is a valid React element
|
|
204
|
-
const isAsideValid = isValidElement(aside);
|
|
205
|
-
|
|
206
|
-
// Determine if 'aside' is a FilterSidebar component
|
|
207
|
-
const isFilterSidebar = isAsideValid && aside?.type === FilterSidebar;
|
|
208
|
-
|
|
209
|
-
// Use React.Fragment if there's a generic 'aside', otherwise use MainCard
|
|
210
|
-
const ListWrapper = isAsideValid && !isFilterSidebar ? React.Fragment : MainCard;
|
|
211
|
-
|
|
212
|
-
// Define props for the ListWrapper based on the presence of 'aside'
|
|
213
|
-
const listWrapperProps = !aside || isFilterSidebar ? { content: false } : undefined;
|
|
214
|
-
|
|
215
|
-
return (
|
|
216
|
-
<ListWrapper {...listWrapperProps}>
|
|
217
|
-
<StyledList {...props} pagination={<Pagination />} />
|
|
218
|
-
</ListWrapper>
|
|
219
|
-
);
|
|
199
|
+
return <StyledList {...props} pagination={<Pagination />} />;
|
|
220
200
|
}
|
|
221
201
|
|
|
222
202
|
export { List };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable filenames/match-regex */
|
|
2
2
|
import { Error } from '@/components/Layout/Error';
|
|
3
|
-
import { Card, CardContent } from '@mui/material';
|
|
3
|
+
import { Card, CardContent, CircularProgress } from '@mui/material';
|
|
4
4
|
import { styled, useTheme } from '@mui/material/styles';
|
|
5
5
|
import { SxProps } from '@mui/system';
|
|
6
6
|
import clsx from 'clsx';
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
} from 'react-admin';
|
|
17
17
|
import { ListToolbar } from './ListToolbar';
|
|
18
18
|
import { FilterSidebar } from './FilterSidebar';
|
|
19
|
+
import { MainCard } from '@/components/MainCard';
|
|
20
|
+
|
|
19
21
|
const defaultActions = <DefaultActions />;
|
|
20
22
|
const defaultPagination = <DefaultPagination />;
|
|
21
23
|
const defaultEmpty = <Empty />;
|
|
@@ -73,10 +75,7 @@ function ListView<RecordType extends RaRecord = any>(props: ListViewProps): Reac
|
|
|
73
75
|
{!error && (
|
|
74
76
|
<Content className={ListClasses.content}>
|
|
75
77
|
{bulkActionButtons && children && React.isValidElement<any>(children)
|
|
76
|
-
?
|
|
77
|
-
cloneElement(children, {
|
|
78
|
-
bulkActionButtons
|
|
79
|
-
})
|
|
78
|
+
? cloneElement(children, { bulkActionButtons })
|
|
80
79
|
: children}
|
|
81
80
|
</Content>
|
|
82
81
|
)}
|
|
@@ -101,10 +100,38 @@ function ListView<RecordType extends RaRecord = any>(props: ListViewProps): Reac
|
|
|
101
100
|
const shouldRenderEmptyPage =
|
|
102
101
|
!isLoading && data?.length === 0 && !Object.keys(filterValues).length && empty !== false;
|
|
103
102
|
|
|
103
|
+
// Check if 'aside' is a valid React element
|
|
104
|
+
const isAsideValid = React.isValidElement(aside);
|
|
105
|
+
|
|
106
|
+
// Determine if 'aside' is a FilterSidebar component
|
|
107
|
+
const isFilterSidebar = isAsideValid && aside?.type === FilterSidebar;
|
|
108
|
+
|
|
109
|
+
// Use React.Fragment if there's a generic 'aside', otherwise use MainCard
|
|
110
|
+
const Wrapper = isLoading || shouldRenderEmptyPage || (isAsideValid && !isFilterSidebar) ? React.Fragment : MainCard;
|
|
111
|
+
|
|
112
|
+
// Define props for the ListWrapper based on the presence of 'aside'
|
|
113
|
+
const wrapperProps =
|
|
114
|
+
!isLoading && !shouldRenderEmptyPage && (!aside || isFilterSidebar) ? { content: false } : undefined;
|
|
104
115
|
return (
|
|
105
116
|
<Root className={clsx('list-page', className)} {...rest}>
|
|
106
117
|
<Title title={title} defaultTitle={defaultTitle} preferenceKey={`${resource}.list.title`} />
|
|
107
|
-
{
|
|
118
|
+
<Wrapper {...wrapperProps}>
|
|
119
|
+
{isLoading ? (
|
|
120
|
+
<CircularProgress
|
|
121
|
+
sx={{
|
|
122
|
+
position: 'absolute',
|
|
123
|
+
top: '50%',
|
|
124
|
+
left: '50%',
|
|
125
|
+
marginTop: '-20px',
|
|
126
|
+
marginLeft: '-20px'
|
|
127
|
+
}}
|
|
128
|
+
/>
|
|
129
|
+
) : shouldRenderEmptyPage ? (
|
|
130
|
+
renderEmpty()
|
|
131
|
+
) : (
|
|
132
|
+
renderList()
|
|
133
|
+
)}
|
|
134
|
+
</Wrapper>
|
|
108
135
|
{hasAsideSidebar ? <AsideCard aside={aside} /> : null}
|
|
109
136
|
{/* @ts-ignore */}
|
|
110
137
|
{hasFilterSidebar ? React.cloneElement(aside, { filters }) : null}
|
|
@@ -399,6 +426,9 @@ const Root = styled('div', {
|
|
|
399
426
|
})(({ theme }) => ({
|
|
400
427
|
display: 'flex',
|
|
401
428
|
|
|
429
|
+
'& >.MuiPaper-root': {
|
|
430
|
+
flex: 1
|
|
431
|
+
},
|
|
402
432
|
[`& .${ListClasses.main}`]: {
|
|
403
433
|
flex: '1 1 auto',
|
|
404
434
|
display: 'flex',
|
|
@@ -415,7 +445,9 @@ const Root = styled('div', {
|
|
|
415
445
|
|
|
416
446
|
[`& .${ListClasses.actions}`]: {},
|
|
417
447
|
|
|
418
|
-
[`& .${ListClasses.noResults}`]: {
|
|
448
|
+
[`& .${ListClasses.noResults}`]: {
|
|
449
|
+
alignContent: 'center'
|
|
450
|
+
},
|
|
419
451
|
|
|
420
452
|
[`& .${ListClasses.asideCard}`]: {
|
|
421
453
|
[theme.breakpoints.down('md')]: {
|