muffin-admin 11.8.0 → 12.0.0
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/MuffinResourceEdit.js +35 -3
- package/dist/MuffinResourceList.js +8 -2
- package/dist/MuffinResourceShow.d.ts +1 -1
- package/dist/MuffinResourceShow.js +42 -5
- package/dist/buttons/LinkButton.js +8 -2
- package/dist/common/AdminModal.d.ts +4 -2
- package/dist/common/AdminModal.js +2 -2
- package/dist/fields/FKField.js +11 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/MuffinResourceEdit.tsx +72 -11
- package/src/MuffinResourceList.tsx +15 -1
- package/src/MuffinResourceShow.tsx +92 -14
- package/src/buttons/LinkButton.tsx +10 -2
- package/src/common/AdminModal.tsx +6 -3
- package/src/fields/FKField.tsx +13 -1
- package/src/index.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Box, Typography } from "@mui/material"
|
|
1
2
|
import { PropsWithChildren } from "react"
|
|
2
3
|
import {
|
|
3
4
|
DeleteButton,
|
|
@@ -8,10 +9,14 @@ import {
|
|
|
8
9
|
SimpleForm,
|
|
9
10
|
Toolbar,
|
|
10
11
|
TopToolbar,
|
|
12
|
+
useRecordContext,
|
|
11
13
|
useResourceContext,
|
|
14
|
+
useTranslate,
|
|
12
15
|
} from "react-admin"
|
|
16
|
+
import { useLocation, useNavigate } from "react-router-dom"
|
|
13
17
|
import { buildRA } from "./buildRA"
|
|
14
18
|
import { ActionButton } from "./buttons"
|
|
19
|
+
import { AdminModal } from "./common"
|
|
15
20
|
import { useMuffinAdminOpts, useMuffinResourceOpts } from "./hooks"
|
|
16
21
|
import { findBuilder, setupAdmin } from "./utils"
|
|
17
22
|
|
|
@@ -21,18 +26,64 @@ export function MuffinEdit({ children }: PropsWithChildren) {
|
|
|
21
26
|
} = useMuffinAdminOpts()
|
|
22
27
|
|
|
23
28
|
const { edit, name, key } = useMuffinResourceOpts()
|
|
29
|
+
const location = useLocation()
|
|
30
|
+
const navigate = useNavigate()
|
|
31
|
+
const returnTo = new URLSearchParams(location.search).get("returnTo")
|
|
24
32
|
if (!edit) return null
|
|
25
33
|
|
|
34
|
+
const handleClose = () => {
|
|
35
|
+
if (returnTo) {
|
|
36
|
+
navigate(returnTo)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (window.history.length > 1) {
|
|
41
|
+
navigate(-1)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
navigate(`/${name}`)
|
|
46
|
+
}
|
|
47
|
+
|
|
26
48
|
const Actions = findBuilder(["edit-toolbar", name])
|
|
27
49
|
const Inputs = findBuilder(["edit-inputs", name])
|
|
28
50
|
const FormToolbar = findBuilder(["edit-form-toolbar", name])
|
|
29
51
|
|
|
30
52
|
return (
|
|
31
|
-
<Edit
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
53
|
+
<Edit
|
|
54
|
+
actions={false}
|
|
55
|
+
title={false}
|
|
56
|
+
component="div"
|
|
57
|
+
mutationMode={mutationMode}
|
|
58
|
+
queryOptions={{ meta: { key } }}
|
|
59
|
+
sx={{
|
|
60
|
+
"& .RaEdit-main": {
|
|
61
|
+
padding: 0,
|
|
62
|
+
},
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<AdminModal
|
|
66
|
+
open={true}
|
|
67
|
+
onClose={handleClose}
|
|
68
|
+
title={<Actions />}
|
|
69
|
+
maxWidth="xl"
|
|
70
|
+
contentSx={{
|
|
71
|
+
paddingTop: "8px !important",
|
|
72
|
+
paddingBottom: "12px !important",
|
|
73
|
+
paddingLeft: "16px !important",
|
|
74
|
+
paddingRight: "16px !important",
|
|
75
|
+
}}
|
|
76
|
+
sx={{
|
|
77
|
+
"& .MuiDialog-paper": {
|
|
78
|
+
width: "min(1400px, 96vw)",
|
|
79
|
+
},
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
{children}
|
|
83
|
+
<SimpleForm toolbar={<FormToolbar />}>
|
|
84
|
+
<Inputs />
|
|
85
|
+
</SimpleForm>
|
|
86
|
+
</AdminModal>
|
|
36
87
|
</Edit>
|
|
37
88
|
)
|
|
38
89
|
}
|
|
@@ -66,14 +117,24 @@ setupAdmin(["edit-inputs"], MuffinEditInputs)
|
|
|
66
117
|
|
|
67
118
|
export function MuffinEditToolbar({ children }: PropsWithChildren) {
|
|
68
119
|
const resource = useResourceContext()
|
|
120
|
+
const record = useRecordContext()
|
|
121
|
+
const translate = useTranslate()
|
|
69
122
|
const Actions = findBuilder(["edit-actions", resource])
|
|
70
123
|
return (
|
|
71
|
-
<
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
124
|
+
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
|
125
|
+
<TopToolbar sx={{ pl: 0, pr: 0, width: "100%", justifyContent: "space-between" }}>
|
|
126
|
+
<Typography variant="h6" sx={{ mr: 2 }}>
|
|
127
|
+
{translate(`resources.${resource}.name`, { smart_count: 1, _: resource })}
|
|
128
|
+
{record?.id ? ` #${record.id}` : ""}
|
|
129
|
+
</Typography>
|
|
130
|
+
<Box sx={{ display: "flex", alignItems: "center" }}>
|
|
131
|
+
<Actions />
|
|
132
|
+
{children}
|
|
133
|
+
<ShowButton />
|
|
134
|
+
<ListButton />
|
|
135
|
+
</Box>
|
|
136
|
+
</TopToolbar>
|
|
137
|
+
</Box>
|
|
77
138
|
)
|
|
78
139
|
}
|
|
79
140
|
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Pagination,
|
|
15
15
|
SelectColumnsButton,
|
|
16
16
|
TopToolbar,
|
|
17
|
+
useTranslate,
|
|
17
18
|
} from "react-admin"
|
|
18
19
|
import { buildRA, buildRAComponent } from "./buildRA"
|
|
19
20
|
import { BulkActionButton, ListActionButton } from "./buttons"
|
|
@@ -76,6 +77,7 @@ function MuffinListDatagrid() {
|
|
|
76
77
|
const { name, list } = useMuffinResourceOpts()
|
|
77
78
|
const { fields, edit, show } = list
|
|
78
79
|
const BulkActions = findBuilder(["list-actions", name])
|
|
80
|
+
|
|
79
81
|
return (
|
|
80
82
|
<DatagridConfigurable
|
|
81
83
|
rowClick={show ? "show" : edit ? "edit" : false}
|
|
@@ -91,9 +93,21 @@ setupAdmin(["list-grid"], MuffinListDatagrid)
|
|
|
91
93
|
|
|
92
94
|
function MuffinListGridButtons() {
|
|
93
95
|
const { list } = useMuffinResourceOpts()
|
|
96
|
+
const translate = useTranslate()
|
|
94
97
|
const { edit } = list
|
|
95
98
|
if (!edit) return null
|
|
96
|
-
return
|
|
99
|
+
return (
|
|
100
|
+
<EditButton
|
|
101
|
+
label=""
|
|
102
|
+
title={translate("ra.action.edit", { _: "Edit" })}
|
|
103
|
+
sx={{
|
|
104
|
+
minWidth: "auto",
|
|
105
|
+
width: "100%",
|
|
106
|
+
justifyContent: "flex-end",
|
|
107
|
+
"& .MuiButton-startIcon": { margin: 0 },
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
setupAdmin(["list-grid-buttons"], MuffinListGridButtons)
|
|
@@ -1,19 +1,86 @@
|
|
|
1
|
+
import { Box, Typography } from "@mui/material"
|
|
1
2
|
import { PropsWithChildren } from "react"
|
|
2
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
EditButton,
|
|
5
|
+
ListButton,
|
|
6
|
+
Show,
|
|
7
|
+
SimpleShowLayout,
|
|
8
|
+
TopToolbar,
|
|
9
|
+
useRecordContext,
|
|
10
|
+
useTranslate,
|
|
11
|
+
} from "react-admin"
|
|
12
|
+
import { useLocation, useNavigate } from "react-router-dom"
|
|
3
13
|
import { LinkAction } from "./actions"
|
|
4
14
|
import { buildRA } from "./buildRA"
|
|
5
15
|
import { ActionButton } from "./buttons"
|
|
16
|
+
import { AdminModal } from "./common"
|
|
6
17
|
import { useMuffinResourceOpts } from "./hooks"
|
|
7
18
|
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
8
19
|
|
|
9
20
|
export function MuffinShow({ children }: PropsWithChildren) {
|
|
10
21
|
const { show, name, key } = useMuffinResourceOpts()
|
|
22
|
+
const location = useLocation()
|
|
23
|
+
const navigate = useNavigate()
|
|
11
24
|
const ShowToolbar = findBuilder(["show-toolbar", name])
|
|
25
|
+
const returnTo = new URLSearchParams(location.search).get("returnTo")
|
|
26
|
+
|
|
27
|
+
const handleClose = () => {
|
|
28
|
+
if (returnTo) {
|
|
29
|
+
navigate(returnTo)
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (window.history.length > 1) {
|
|
34
|
+
navigate(-1)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
navigate(`/${name}`)
|
|
39
|
+
}
|
|
12
40
|
|
|
13
41
|
return (
|
|
14
|
-
<Show
|
|
15
|
-
|
|
16
|
-
{
|
|
42
|
+
<Show
|
|
43
|
+
actions={false}
|
|
44
|
+
title={false}
|
|
45
|
+
component="div"
|
|
46
|
+
queryOptions={{ meta: { key } }}
|
|
47
|
+
sx={{
|
|
48
|
+
"& .RaShow-main": {
|
|
49
|
+
padding: 0,
|
|
50
|
+
},
|
|
51
|
+
}}
|
|
52
|
+
>
|
|
53
|
+
<AdminModal
|
|
54
|
+
open={true}
|
|
55
|
+
onClose={handleClose}
|
|
56
|
+
title={<ShowToolbar />}
|
|
57
|
+
maxWidth="xl"
|
|
58
|
+
hideBackdrop
|
|
59
|
+
disableScrollLock
|
|
60
|
+
contentSx={{
|
|
61
|
+
paddingTop: "8px !important",
|
|
62
|
+
paddingBottom: "12px !important",
|
|
63
|
+
paddingLeft: "16px !important",
|
|
64
|
+
paddingRight: "16px !important",
|
|
65
|
+
}}
|
|
66
|
+
sx={{
|
|
67
|
+
"& .MuiDialog-paper": {
|
|
68
|
+
width: "min(1400px, 96vw)",
|
|
69
|
+
},
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<SimpleShowLayout
|
|
73
|
+
sx={{
|
|
74
|
+
padding: 0,
|
|
75
|
+
"& .RaSimpleShowLayout-stack": {
|
|
76
|
+
rowGap: 1,
|
|
77
|
+
},
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
{buildAdmin(["show-fields", name], show)}
|
|
81
|
+
</SimpleShowLayout>
|
|
82
|
+
{children}
|
|
83
|
+
</AdminModal>
|
|
17
84
|
</Show>
|
|
18
85
|
)
|
|
19
86
|
}
|
|
@@ -21,21 +88,32 @@ export function MuffinShow({ children }: PropsWithChildren) {
|
|
|
21
88
|
setupAdmin(["show"], MuffinShow)
|
|
22
89
|
setupAdmin(["show-fields"], ({ fields }) => buildRA(fields))
|
|
23
90
|
|
|
24
|
-
export function MuffinShowToolbar(
|
|
91
|
+
export function MuffinShowToolbar() {
|
|
25
92
|
const { show, name } = useMuffinResourceOpts()
|
|
93
|
+
const record = useRecordContext()
|
|
94
|
+
const translate = useTranslate()
|
|
26
95
|
const { edit } = show
|
|
27
96
|
|
|
28
97
|
const Links = findBuilder(["show-links", name])
|
|
29
98
|
const Actions = findBuilder(["show-actions", name])
|
|
30
99
|
|
|
31
100
|
return (
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
101
|
+
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
|
102
|
+
<TopToolbar sx={{ pl: 0, pr: 0, width: "100%", justifyContent: "space-between" }}>
|
|
103
|
+
<Typography variant="h6" sx={{ mr: 2 }}>
|
|
104
|
+
{translate(`resources.${name}.name`, { smart_count: 1, _: name })}
|
|
105
|
+
{record?.id ? ` #${record.id}` : ""}
|
|
106
|
+
</Typography>
|
|
107
|
+
<Box sx={{ display: "flex", alignItems: "center" }}>
|
|
108
|
+
<Actions />
|
|
109
|
+
{edit && <EditButton />}
|
|
110
|
+
<ListButton />
|
|
111
|
+
</Box>
|
|
112
|
+
</TopToolbar>
|
|
113
|
+
<Box sx={{ mt: 0.5 }}>
|
|
114
|
+
<Links />
|
|
115
|
+
</Box>
|
|
116
|
+
</Box>
|
|
39
117
|
)
|
|
40
118
|
}
|
|
41
119
|
|
|
@@ -60,12 +138,12 @@ export function MuffinShowLinks({ children }: PropsWithChildren) {
|
|
|
60
138
|
const { show } = useMuffinResourceOpts()
|
|
61
139
|
const { links } = show
|
|
62
140
|
return (
|
|
63
|
-
<
|
|
141
|
+
<Box sx={{ display: "flex", flexWrap: "wrap", gap: 1 }}>
|
|
64
142
|
{links.map(([key, props]) => (
|
|
65
143
|
<LinkAction key={key} resource={key} {...props} />
|
|
66
144
|
))}
|
|
67
145
|
{children}
|
|
68
|
-
</
|
|
146
|
+
</Box>
|
|
69
147
|
)
|
|
70
148
|
}
|
|
71
149
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Button } from "react-admin"
|
|
2
|
-
import { Link } from "react-router-dom"
|
|
2
|
+
import { Link, useLocation } from "react-router-dom"
|
|
3
3
|
import { AdminShowLink } from "../types"
|
|
4
4
|
import { buildIcon } from "../utils"
|
|
5
5
|
|
|
@@ -11,9 +11,17 @@ const LinkButton = ({
|
|
|
11
11
|
id,
|
|
12
12
|
title,
|
|
13
13
|
}: AdminShowLink & { resource: string; filters?: any; id?: string }) => {
|
|
14
|
+
const location = useLocation()
|
|
15
|
+
const searchParams = new URLSearchParams()
|
|
16
|
+
searchParams.set("returnTo", `${location.pathname}${location.search}`)
|
|
17
|
+
|
|
18
|
+
if (filters) {
|
|
19
|
+
searchParams.set("filter", JSON.stringify(filters))
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
const linkParams = {
|
|
15
23
|
pathname: `/${resource}`,
|
|
16
|
-
search:
|
|
24
|
+
search: `?${searchParams.toString()}`,
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
if (id) linkParams.pathname += `/${id}/show`
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Dialog, DialogActions, DialogContent, DialogProps, DialogTitle } from "@mui/material"
|
|
2
2
|
import { PropsWithChildren } from "react"
|
|
3
|
+
import { SxProps, Theme } from "@mui/material/styles"
|
|
3
4
|
|
|
4
|
-
interface IProps {
|
|
5
|
+
interface IProps extends Omit<DialogProps, "title" | "open" | "onClose"> {
|
|
5
6
|
open: boolean
|
|
6
7
|
onClose: () => void
|
|
7
8
|
title?: React.ReactNode
|
|
8
9
|
actions?: React.ReactNode
|
|
10
|
+
contentSx?: SxProps<Theme>
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export function AdminModal({
|
|
@@ -14,12 +16,13 @@ export function AdminModal({
|
|
|
14
16
|
children,
|
|
15
17
|
title,
|
|
16
18
|
actions,
|
|
19
|
+
contentSx,
|
|
17
20
|
...props
|
|
18
|
-
}: PropsWithChildren<IProps
|
|
21
|
+
}: PropsWithChildren<IProps>) {
|
|
19
22
|
return (
|
|
20
23
|
<Dialog open={open} onClose={onClose} fullWidth maxWidth="md" {...props}>
|
|
21
24
|
{title && <DialogTitle>{title}</DialogTitle>}
|
|
22
|
-
<DialogContent>{children}</DialogContent>
|
|
25
|
+
<DialogContent sx={contentSx}>{children}</DialogContent>
|
|
23
26
|
{actions && <DialogActions>{actions}</DialogActions>}
|
|
24
27
|
</Dialog>
|
|
25
28
|
)
|
package/src/fields/FKField.tsx
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { ReferenceField, TextField, useFieldValue, UseFieldValueOptions } from "react-admin"
|
|
2
|
+
import { useLocation } from "react-router-dom"
|
|
2
3
|
|
|
3
4
|
export function FKField({ reference, refSource, refKey, link, source, ...props }) {
|
|
5
|
+
const location = useLocation()
|
|
4
6
|
refKey = refKey || "id"
|
|
7
|
+
const returnTo = `${location.pathname}${location.search}`
|
|
8
|
+
|
|
9
|
+
const resolveLink =
|
|
10
|
+
link ||
|
|
11
|
+
((record) => {
|
|
12
|
+
const id = record?.[refKey]
|
|
13
|
+
if (id === undefined || id === null) return false
|
|
14
|
+
return `/${reference}/${id}/show?returnTo=${encodeURIComponent(returnTo)}`
|
|
15
|
+
})
|
|
16
|
+
|
|
5
17
|
return (
|
|
6
18
|
<ReferenceField
|
|
7
19
|
source={source}
|
|
8
|
-
link={
|
|
20
|
+
link={resolveLink}
|
|
9
21
|
reference={reference}
|
|
10
22
|
queryOptions={{ meta: { key: refKey } }}
|
|
11
23
|
{...props}
|
package/src/index.tsx
CHANGED