@applica-software-guru/react-admin 1.5.237 → 1.5.240
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/.husky/pre-commit +2 -1
- package/dist/components/ActionsMenu.d.ts.map +1 -1
- package/dist/components/ra-buttons/Button.d.ts +17 -0
- package/dist/components/ra-buttons/Button.d.ts.map +1 -0
- package/dist/components/ra-buttons/CreateInDialogButton.d.ts +9 -2
- package/dist/components/ra-buttons/CreateInDialogButton.d.ts.map +1 -1
- package/dist/components/ra-buttons/EditInDialogButton.d.ts +19 -0
- package/dist/components/ra-buttons/EditInDialogButton.d.ts.map +1 -1
- package/dist/components/ra-buttons/index.d.ts +1 -0
- package/dist/components/ra-buttons/index.d.ts.map +1 -1
- package/dist/components/ra-forms/Toolbar.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/react-admin.cjs.js +54 -54
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +7619 -7689
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +52 -52
- package/dist/react-admin.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionsMenu.tsx +5 -0
- package/src/components/ra-buttons/Button.tsx +84 -0
- package/src/components/ra-buttons/CreateInDialogButton.tsx +43 -11
- package/src/components/ra-buttons/EditInDialogButton.tsx +65 -4
- package/src/components/ra-buttons/index.ts +1 -0
- package/src/components/ra-forms/Toolbar.tsx +2 -2
- package/src/index.ts +0 -1
- package/src/playground/components/ra-lists/CategoryList.jsx +5 -2
- package/src/playground/components/ra-lists/UserList.jsx +3 -3
package/package.json
CHANGED
|
@@ -21,6 +21,11 @@ const StyledMenuPopover = styled(MenuPopover, {
|
|
|
21
21
|
margin: 0,
|
|
22
22
|
'& .MuiButton-startIcon': {
|
|
23
23
|
marginRight: theme.spacing(0)
|
|
24
|
+
},
|
|
25
|
+
[theme.breakpoints.down('sm')]: {
|
|
26
|
+
'&>.MuiSvgIcon-root, & svg': {
|
|
27
|
+
marginRight: theme.spacing(0)
|
|
28
|
+
}
|
|
24
29
|
}
|
|
25
30
|
}
|
|
26
31
|
}));
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Button as MuiButton } from '@mui/material';
|
|
2
|
+
import { styled } from '@mui/material/styles';
|
|
3
|
+
import { LocationDescriptor, Button as RaButton, ButtonProps as RaButtonProps, useTranslate } from 'react-admin';
|
|
4
|
+
|
|
5
|
+
type ButtonProps = RaButtonProps & {
|
|
6
|
+
/**
|
|
7
|
+
* Disable icon only in small screens.
|
|
8
|
+
*/
|
|
9
|
+
disableIconOnly?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const PREFIX = 'RaButton';
|
|
13
|
+
function getLinkParams(locationDescriptor?: LocationDescriptor | string) {
|
|
14
|
+
// eslint-disable-next-line eqeqeq
|
|
15
|
+
if (locationDescriptor == undefined) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (typeof locationDescriptor === 'string') {
|
|
20
|
+
return { to: locationDescriptor };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { redirect, replace, state, ...to } = locationDescriptor;
|
|
24
|
+
return {
|
|
25
|
+
to,
|
|
26
|
+
redirect,
|
|
27
|
+
replace,
|
|
28
|
+
state
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const StyledButton = styled(MuiButton, {
|
|
32
|
+
name: PREFIX,
|
|
33
|
+
overridesResolver: (_props, styles) => styles.root
|
|
34
|
+
})({
|
|
35
|
+
'&.MuiButton-sizeSmall': {
|
|
36
|
+
// fix for icon misalignment on small buttons, see https://github.com/mui/material-ui/pull/30240
|
|
37
|
+
lineHeight: 1.5
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A button that can be displayed as a floating button on small screens.
|
|
43
|
+
* @param props The component props.
|
|
44
|
+
* @returns The component.
|
|
45
|
+
*/
|
|
46
|
+
function Button(props: ButtonProps): JSX.Element {
|
|
47
|
+
const {
|
|
48
|
+
disableIconOnly = false,
|
|
49
|
+
label,
|
|
50
|
+
children,
|
|
51
|
+
className,
|
|
52
|
+
color,
|
|
53
|
+
size,
|
|
54
|
+
disabled,
|
|
55
|
+
alignIcon,
|
|
56
|
+
to: locationDescriptor,
|
|
57
|
+
...rest
|
|
58
|
+
} = props;
|
|
59
|
+
const translate = useTranslate();
|
|
60
|
+
const linkParams = getLinkParams(locationDescriptor);
|
|
61
|
+
|
|
62
|
+
if (disableIconOnly) {
|
|
63
|
+
const translatedLabel = label ? translate(label, { _: label }) : undefined;
|
|
64
|
+
return (
|
|
65
|
+
<StyledButton
|
|
66
|
+
className={className}
|
|
67
|
+
color={color}
|
|
68
|
+
size={size}
|
|
69
|
+
aria-label={translatedLabel}
|
|
70
|
+
disabled={disabled}
|
|
71
|
+
startIcon={alignIcon === 'left' && children ? children : undefined}
|
|
72
|
+
endIcon={alignIcon === 'right' && children ? children : undefined}
|
|
73
|
+
{...linkParams}
|
|
74
|
+
{...rest}
|
|
75
|
+
>
|
|
76
|
+
{translatedLabel}
|
|
77
|
+
</StyledButton>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return <RaButton {...props} />;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { Button };
|
|
84
|
+
export type { ButtonProps };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { Button as RaButton } from './Button';
|
|
1
2
|
import { Toolbar } from '@/components/ra-forms';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { PlusCircleOutlined } from '@ant-design/icons';
|
|
4
|
+
import { Breakpoint, Button, Dialog } from '@mui/material';
|
|
5
|
+
import { CreateBase, UseCreateMutateParams, useResourceContext, useTranslate } from 'ra-core';
|
|
6
|
+
import { ButtonProps, CreateButton, CreateButtonProps, CreateProps, SaveButton } from 'ra-ui-materialui';
|
|
5
7
|
import React, { Children, PropsWithChildren, useCallback, useState } from 'react';
|
|
6
8
|
import { FieldValues, useFormContext } from 'react-hook-form';
|
|
7
9
|
import { useQueryClient } from 'react-query';
|
|
@@ -27,11 +29,14 @@ function setListQueryData(res: any, data: any) {
|
|
|
27
29
|
return res && res.data ? { ...res, data: updateColl(res.data, data), total: res.total + 1 } : res;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
type ResponsiveButtonProps = CreateButtonProps &
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
type ResponsiveButtonProps = CreateButtonProps &
|
|
33
|
+
ButtonProps & {
|
|
34
|
+
label?: string;
|
|
35
|
+
onClick?: () => void;
|
|
36
|
+
disableFloatingButton?: boolean;
|
|
37
|
+
};
|
|
34
38
|
function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
|
|
39
|
+
const { disableFloatingButton, startIcon = <PlusCircleOutlined />, ...rest } = props;
|
|
35
40
|
const handleClick = useCallback(
|
|
36
41
|
(event: any) => {
|
|
37
42
|
(event as Event).preventDefault();
|
|
@@ -40,7 +45,15 @@ function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
|
|
|
40
45
|
},
|
|
41
46
|
[props]
|
|
42
47
|
);
|
|
43
|
-
return
|
|
48
|
+
return disableFloatingButton ? (
|
|
49
|
+
<RaButton {...rest} onClick={handleClick}>
|
|
50
|
+
{startIcon as any}
|
|
51
|
+
</RaButton>
|
|
52
|
+
) : (
|
|
53
|
+
<CreateButton {...props} onClick={handleClick}>
|
|
54
|
+
{startIcon as any}
|
|
55
|
+
</CreateButton>
|
|
56
|
+
);
|
|
44
57
|
}
|
|
45
58
|
type CloseDialogFunction = () => void;
|
|
46
59
|
type SubmitFunction = (values: FieldValues, closeDialog: CloseDialogFunction) => void;
|
|
@@ -51,6 +64,7 @@ type SubmitButtonProps = {
|
|
|
51
64
|
function SubmitButton(props: SubmitButtonProps) {
|
|
52
65
|
const { onSubmit, closeDialog } = props;
|
|
53
66
|
const { handleSubmit } = useFormContext();
|
|
67
|
+
const translate = useTranslate();
|
|
54
68
|
const handleClick = useCallback(
|
|
55
69
|
(event: any) => {
|
|
56
70
|
(event as Event).preventDefault();
|
|
@@ -59,7 +73,11 @@ function SubmitButton(props: SubmitButtonProps) {
|
|
|
59
73
|
},
|
|
60
74
|
[handleSubmit, onSubmit, closeDialog]
|
|
61
75
|
);
|
|
62
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
<Button onClick={handleClick} color="primary" variant="contained" size="medium">
|
|
78
|
+
{translate('ra.action.save')}
|
|
79
|
+
</Button>
|
|
80
|
+
);
|
|
63
81
|
}
|
|
64
82
|
type CreateInDialogButtonProps = PropsWithChildren &
|
|
65
83
|
CreateProps &
|
|
@@ -67,6 +85,12 @@ type CreateInDialogButtonProps = PropsWithChildren &
|
|
|
67
85
|
maxWidth: Breakpoint;
|
|
68
86
|
fullWidth?: boolean;
|
|
69
87
|
fullScreen?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Indicates whether the floating button should be disabled.
|
|
90
|
+
* Default is false, this mean that the floating button will be displayed on small screens.
|
|
91
|
+
* **If you have multiple buttons on the same page, they will be displayed over each other! **
|
|
92
|
+
*/
|
|
93
|
+
disableFloatingButton?: boolean;
|
|
70
94
|
scroll: 'paper' | 'body' | undefined;
|
|
71
95
|
/**
|
|
72
96
|
* Custom handler for the submit event, in this case you are responsible for closing the dialog.
|
|
@@ -89,6 +113,7 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
|
|
|
89
113
|
const { children, maxWidth = 'md', fullWidth = true, fullScreen, onSubmit, mutationOptions, scroll, ...rest } = props;
|
|
90
114
|
const queryClient = useQueryClient();
|
|
91
115
|
const resource = useResourceContext();
|
|
116
|
+
const translate = useTranslate();
|
|
92
117
|
const Child = Children.only(children);
|
|
93
118
|
const [open, setOpen] = useState(false);
|
|
94
119
|
const handleOpen = useCallback(() => setOpen(true), []);
|
|
@@ -116,7 +141,7 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
|
|
|
116
141
|
|
|
117
142
|
return (
|
|
118
143
|
<>
|
|
119
|
-
<ResponsiveButton {...rest} onClick={handleOpen} />
|
|
144
|
+
<ResponsiveButton {...(rest as any)} onClick={handleOpen} />
|
|
120
145
|
<CreateBase
|
|
121
146
|
{...props}
|
|
122
147
|
mutationOptions={{
|
|
@@ -131,6 +156,11 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
|
|
|
131
156
|
maxWidth={maxWidth}
|
|
132
157
|
fullWidth={fullWidth}
|
|
133
158
|
fullScreen={fullScreen}
|
|
159
|
+
sx={{
|
|
160
|
+
'& .MuiToolbar-root': {
|
|
161
|
+
position: 'relative !important'
|
|
162
|
+
}
|
|
163
|
+
}}
|
|
134
164
|
>
|
|
135
165
|
{React.isValidElement(Child)
|
|
136
166
|
? React.cloneElement(Child, {
|
|
@@ -138,7 +168,9 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
|
|
|
138
168
|
modal: true,
|
|
139
169
|
toolbar: (
|
|
140
170
|
<Toolbar>
|
|
141
|
-
<Button variant="text" size="medium"
|
|
171
|
+
<Button variant="text" size="medium" onClick={handleClose}>
|
|
172
|
+
{translate('ra.action.cancel')}
|
|
173
|
+
</Button>
|
|
142
174
|
{onSubmit ? (
|
|
143
175
|
<SubmitButton onSubmit={onSubmit!} closeDialog={handleClose} />
|
|
144
176
|
) : (
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Button } from './Button';
|
|
1
2
|
import { Toolbar } from '@/components/ra-forms';
|
|
2
3
|
import { Breakpoint, Dialog } from '@mui/material';
|
|
3
4
|
import { EditBase, UseUpdateMutateParams, useRecordContext } from 'ra-core';
|
|
4
|
-
import {
|
|
5
|
+
import { EditButton, EditProps, SaveButton } from 'ra-ui-materialui';
|
|
5
6
|
import React, { Children, PropsWithChildren, useCallback, useState } from 'react';
|
|
7
|
+
import { FieldValues, useFormContext } from 'react-hook-form';
|
|
6
8
|
|
|
7
9
|
type ResponsiveButtonProps = {
|
|
8
10
|
label?: string;
|
|
@@ -21,6 +23,34 @@ function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
|
|
|
21
23
|
return <EditButton {...props} onClick={handleClick} />;
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
type CloseDialogFunction = () => void;
|
|
27
|
+
type SubmitFunction = (values: FieldValues, closeDialog: CloseDialogFunction) => void;
|
|
28
|
+
type SubmitButtonProps = {
|
|
29
|
+
onSubmit: SubmitFunction;
|
|
30
|
+
closeDialog: CloseDialogFunction;
|
|
31
|
+
};
|
|
32
|
+
function SubmitButton(props: SubmitButtonProps) {
|
|
33
|
+
const { onSubmit, closeDialog } = props;
|
|
34
|
+
const { handleSubmit } = useFormContext();
|
|
35
|
+
const handleClick = useCallback(
|
|
36
|
+
(event: any) => {
|
|
37
|
+
(event as Event).preventDefault();
|
|
38
|
+
(event as Event).stopPropagation();
|
|
39
|
+
handleSubmit((fieldValues) => onSubmit(fieldValues, closeDialog))();
|
|
40
|
+
},
|
|
41
|
+
[handleSubmit, onSubmit, closeDialog]
|
|
42
|
+
);
|
|
43
|
+
return (
|
|
44
|
+
<Button
|
|
45
|
+
disableIconOnly
|
|
46
|
+
onClick={handleClick}
|
|
47
|
+
color="primary"
|
|
48
|
+
variant="contained"
|
|
49
|
+
size="medium"
|
|
50
|
+
label="ra.action.save"
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
24
54
|
type EditInDialogButtonProps = PropsWithChildren &
|
|
25
55
|
EditProps &
|
|
26
56
|
ResponsiveButtonProps & {
|
|
@@ -28,9 +58,25 @@ type EditInDialogButtonProps = PropsWithChildren &
|
|
|
28
58
|
fullWidth?: boolean;
|
|
29
59
|
fullScreen?: boolean;
|
|
30
60
|
scroll: 'paper' | 'body' | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Custom handler for the submit event, in this case you are responsible for closing the dialog.
|
|
63
|
+
* @example
|
|
64
|
+
*
|
|
65
|
+
* const handleSubmit = (values, closeDialog) => {
|
|
66
|
+
* console.log(values); // { title: 'Hello World' }
|
|
67
|
+
* closeDialog();
|
|
68
|
+
* }
|
|
69
|
+
* <CreateInDialogButton onSubmit={handleSubmit}>
|
|
70
|
+
* <SimpleForm>
|
|
71
|
+
* <TextInput source="title" />
|
|
72
|
+
* </SimpleForm>
|
|
73
|
+
* </CreateInDialogButton>
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
onSubmit?: SubmitFunction;
|
|
31
77
|
};
|
|
32
78
|
function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
|
|
33
|
-
const { children, maxWidth = 'md', fullWidth = true, fullScreen, mutationOptions, scroll, ...rest } = props;
|
|
79
|
+
const { children, maxWidth = 'md', fullWidth = true, fullScreen, mutationOptions, onSubmit, scroll, ...rest } = props;
|
|
34
80
|
const [open, setOpen] = useState(false);
|
|
35
81
|
const Child = Children.only(children);
|
|
36
82
|
const handleOpen = useCallback(() => setOpen(true), []);
|
|
@@ -63,6 +109,11 @@ function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
|
|
|
63
109
|
maxWidth={maxWidth}
|
|
64
110
|
fullScreen={fullScreen}
|
|
65
111
|
keepMounted={false}
|
|
112
|
+
sx={{
|
|
113
|
+
'& .MuiToolbar-root': {
|
|
114
|
+
position: 'relative !important'
|
|
115
|
+
}
|
|
116
|
+
}}
|
|
66
117
|
>
|
|
67
118
|
{React.isValidElement(Child)
|
|
68
119
|
? React.cloneElement(Child, {
|
|
@@ -70,8 +121,18 @@ function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
|
|
|
70
121
|
modal: true,
|
|
71
122
|
toolbar: (
|
|
72
123
|
<Toolbar>
|
|
73
|
-
<Button
|
|
74
|
-
|
|
124
|
+
<Button
|
|
125
|
+
disableIconOnly
|
|
126
|
+
variant="text"
|
|
127
|
+
size="medium"
|
|
128
|
+
onClick={handleClose}
|
|
129
|
+
label="ra.action.cancel"
|
|
130
|
+
/>
|
|
131
|
+
{onSubmit ? (
|
|
132
|
+
<SubmitButton onSubmit={onSubmit!} closeDialog={handleClose} />
|
|
133
|
+
) : (
|
|
134
|
+
<SaveButton type="button" />
|
|
135
|
+
)}
|
|
75
136
|
</Toolbar>
|
|
76
137
|
)
|
|
77
138
|
})
|
|
@@ -6,6 +6,7 @@ const StyledToolbar = styled(RaToolbar, { slot: 'Root' })(({ theme }: { theme: a
|
|
|
6
6
|
...theme.mixins.toolbar,
|
|
7
7
|
backgroundColor: theme.palette.background.paper,
|
|
8
8
|
justifyContent: 'flex-end',
|
|
9
|
+
position: 'initial !important',
|
|
9
10
|
|
|
10
11
|
'& .RaToolbar-defaultToolbar': {
|
|
11
12
|
justifyContent: 'right',
|
|
@@ -20,8 +21,7 @@ const StyledToolbar = styled(RaToolbar, { slot: 'Root' })(({ theme }: { theme: a
|
|
|
20
21
|
}));
|
|
21
22
|
|
|
22
23
|
function Toolbar(props: ToolbarProps): JSX.Element {
|
|
23
|
-
|
|
24
|
-
return <StyledToolbar {...props} />;
|
|
24
|
+
return <StyledToolbar {...(props as any)} />;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export { Toolbar };
|
package/src/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
|
|
17
17
|
function CategoryAddButton() {
|
|
18
18
|
return (
|
|
19
|
-
<CreateInDialogButton maxWidth="sm" redirect="list" size="
|
|
19
|
+
<CreateInDialogButton maxWidth="sm" redirect="list" size="medium" variant="text">
|
|
20
20
|
<CategoryForm />
|
|
21
21
|
</CreateInDialogButton>
|
|
22
22
|
);
|
|
@@ -27,7 +27,7 @@ function CategorySubmitButton() {
|
|
|
27
27
|
console.log(values);
|
|
28
28
|
}
|
|
29
29
|
return (
|
|
30
|
-
<CreateInDialogButton onSubmit={handleSubmit} redirect="list" label="Submit">
|
|
30
|
+
<CreateInDialogButton onSubmit={handleSubmit} redirect="list" label="Submit" size="medium">
|
|
31
31
|
<SimpleForm>
|
|
32
32
|
<TextInput source="description" validate={required()} fullWidth />
|
|
33
33
|
</SimpleForm>
|
|
@@ -55,6 +55,9 @@ function CategoryList() {
|
|
|
55
55
|
<EditInDialogButton>
|
|
56
56
|
<CategoryForm />
|
|
57
57
|
</EditInDialogButton>
|
|
58
|
+
<EditInDialogButton label="Edit with Submit" onSubmit={console.log}>
|
|
59
|
+
<CategoryForm />
|
|
60
|
+
</EditInDialogButton>
|
|
58
61
|
</Datagrid>
|
|
59
62
|
</List>
|
|
60
63
|
);
|
|
@@ -41,15 +41,15 @@ function RolesInput({ record, source, roles, ...props }) {
|
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function ImageField(
|
|
44
|
+
function ImageField(record) {
|
|
45
45
|
return <CoverField source="image" record={record} width={50} height={50} circle />;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function NameField(
|
|
48
|
+
function NameField(record) {
|
|
49
49
|
return record.name;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function SecondaryField(
|
|
52
|
+
function SecondaryField(record) {
|
|
53
53
|
return record.email;
|
|
54
54
|
}
|
|
55
55
|
|