muffin-admin 1.44.4 → 1.45.1
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/MuffinAdmin.d.ts +2 -0
- package/dist/MuffinAdmin.js +25 -0
- package/dist/MuffinDashboard.d.ts +2 -0
- package/dist/MuffinDashboard.js +16 -0
- package/dist/MuffinResource.d.ts +2 -0
- package/dist/MuffinResource.js +19 -0
- package/dist/MuffinResourceCreate.d.ts +4 -0
- package/dist/MuffinResourceCreate.js +11 -0
- package/dist/MuffinResourceEdit.d.ts +2 -0
- package/dist/MuffinResourceEdit.js +26 -0
- package/dist/MuffinResourceList.d.ts +2 -0
- package/dist/MuffinResourceList.js +16 -0
- package/dist/MuffinResourceShow.d.ts +2 -0
- package/dist/MuffinResourceShow.js +13 -0
- package/dist/actions/LinkAction.d.ts +4 -0
- package/dist/actions/LinkAction.js +10 -0
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/authprovider.d.ts +9 -0
- package/dist/authprovider.js +80 -0
- package/dist/buildRA.d.ts +2 -0
- package/dist/buildRA.js +63 -0
- package/dist/buttons/ActionButton.d.ts +7 -0
- package/dist/buttons/ActionButton.js +51 -0
- package/dist/buttons/LinkButton.d.ts +6 -0
- package/dist/buttons/LinkButton.js +12 -0
- package/dist/buttons/index.d.ts +2 -0
- package/dist/buttons/index.js +2 -0
- package/dist/dataprovider.d.ts +59 -0
- package/dist/dataprovider.js +106 -0
- package/dist/fields/AvatarField.d.ts +13 -0
- package/dist/fields/AvatarField.js +33 -0
- package/dist/fields/EditableBooleanField.d.ts +3 -0
- package/dist/fields/EditableBooleanField.js +5 -0
- package/dist/fields/FKField.d.ts +14 -0
- package/dist/fields/FKField.js +21 -0
- package/dist/fields/JsonField.d.ts +4 -0
- package/dist/fields/JsonField.js +11 -0
- package/dist/fields/index.d.ts +4 -0
- package/dist/fields/index.js +4 -0
- package/dist/hooks/useAction.d.ts +5 -0
- package/dist/hooks/useAction.js +6 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +35 -0
- package/dist/inputs/FKInput.d.ts +8 -0
- package/dist/inputs/FKInput.js +27 -0
- package/dist/inputs/JsonInput.d.ts +19 -0
- package/dist/inputs/JsonInput.js +69 -0
- package/dist/inputs/index.d.ts +2 -0
- package/dist/inputs/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +28 -0
- package/dist/utils.js +57 -0
- package/dist/web.d.ts +1 -0
- package/dist/web.js +3 -0
- package/package.json +31 -14
- package/src/MuffinAdmin.tsx +73 -0
- package/src/MuffinDashboard.tsx +52 -0
- package/src/MuffinResource.tsx +27 -0
- package/src/MuffinResourceCreate.tsx +24 -0
- package/src/MuffinResourceEdit.tsx +42 -0
- package/src/MuffinResourceList.tsx +46 -0
- package/src/MuffinResourceShow.tsx +39 -0
- package/src/actions/LinkAction.tsx +10 -0
- package/src/actions/index.ts +1 -0
- package/src/{authprovider.js → authprovider.ts} +27 -22
- package/src/{ui.jsx → buildRA.tsx} +30 -35
- package/src/buttons/{ActionButton.jsx → ActionButton.tsx} +18 -30
- package/src/buttons/{LinkButton.jsx → LinkButton.tsx} +11 -6
- package/src/buttons/index.ts +2 -0
- package/src/{dataprovider.js → dataprovider.ts} +8 -6
- package/src/fields/{AvatarField.jsx → AvatarField.tsx} +3 -7
- package/src/fields/EditableBooleanField.tsx +5 -0
- package/src/fields/{FKField.jsx → FKField.tsx} +2 -10
- package/src/fields/{JsonField.jsx → JsonField.tsx} +2 -3
- package/src/fields/index.ts +4 -0
- package/src/hooks/{useAction.js → useAction.ts} +2 -2
- package/src/index.tsx +25 -0
- package/src/inputs/FKInput.tsx +27 -0
- package/src/inputs/{JsonInput.jsx → JsonInput.tsx} +3 -4
- package/src/inputs/index.ts +2 -0
- package/src/types.ts +73 -0
- package/src/utils.tsx +69 -0
- package/src/web.ts +4 -0
- package/dist/cjs/admin.js +0 -80
- package/dist/cjs/authprovider.js +0 -214
- package/dist/cjs/buttons/ActionButton.js +0 -96
- package/dist/cjs/buttons/LinkButton.js +0 -34
- package/dist/cjs/dashboard.js +0 -63
- package/dist/cjs/dataprovider.js +0 -304
- package/dist/cjs/fields/AvatarField.js +0 -37
- package/dist/cjs/fields/EditableBooleanField.js +0 -25
- package/dist/cjs/fields/FKField.js +0 -35
- package/dist/cjs/fields/JsonField.js +0 -38
- package/dist/cjs/hooks/useAction.js +0 -14
- package/dist/cjs/index.js +0 -76
- package/dist/cjs/inputs/FKInput.js +0 -41
- package/dist/cjs/inputs/JsonInput.js +0 -70
- package/dist/cjs/resources.js +0 -52
- package/dist/cjs/ui.js +0 -76
- package/dist/cjs/utils.js +0 -49
- package/dist/cjs/views/create.js +0 -18
- package/dist/cjs/views/edit.js +0 -31
- package/dist/cjs/views/list.js +0 -67
- package/dist/cjs/views/show.js +0 -37
- package/dist/cjs/web.js +0 -4
- package/dist/esm/admin.js +0 -74
- package/dist/esm/authprovider.js +0 -206
- package/dist/esm/buttons/ActionButton.js +0 -83
- package/dist/esm/buttons/LinkButton.js +0 -23
- package/dist/esm/dashboard.js +0 -60
- package/dist/esm/dataprovider.js +0 -296
- package/dist/esm/fields/AvatarField.js +0 -29
- package/dist/esm/fields/EditableBooleanField.js +0 -17
- package/dist/esm/fields/FKField.js +0 -27
- package/dist/esm/fields/JsonField.js +0 -28
- package/dist/esm/hooks/useAction.js +0 -8
- package/dist/esm/index.js +0 -42
- package/dist/esm/inputs/FKInput.js +0 -33
- package/dist/esm/inputs/JsonInput.js +0 -63
- package/dist/esm/resources.js +0 -47
- package/dist/esm/ui.js +0 -70
- package/dist/esm/utils.js +0 -38
- package/dist/esm/views/create.js +0 -16
- package/dist/esm/views/edit.js +0 -29
- package/dist/esm/views/list.js +0 -64
- package/dist/esm/views/show.js +0 -35
- package/dist/esm/web.js +0 -2
- package/src/admin.jsx +0 -78
- package/src/dashboard.jsx +0 -74
- package/src/fields/EditableBooleanField.jsx +0 -11
- package/src/index.js +0 -16
- package/src/inputs/FKInput.jsx +0 -42
- package/src/resources.jsx +0 -39
- package/src/utils.js +0 -38
- package/src/views/create.jsx +0 -30
- package/src/views/edit.jsx +0 -48
- package/src/views/list.jsx +0 -86
- package/src/views/show.jsx +0 -51
- package/src/web.js +0 -3
|
@@ -1,48 +1,41 @@
|
|
|
1
|
-
import React from "react"
|
|
2
|
-
|
|
3
|
-
import { required } from "react-admin"
|
|
4
1
|
import {
|
|
2
|
+
ArrayField,
|
|
3
|
+
ArrayInput,
|
|
4
|
+
AutocompleteArrayInput,
|
|
5
|
+
AutocompleteInput,
|
|
5
6
|
BooleanField,
|
|
7
|
+
BooleanInput,
|
|
8
|
+
CheckboxGroupInput,
|
|
6
9
|
ChipField,
|
|
7
10
|
DateField,
|
|
8
|
-
EmailField,
|
|
9
|
-
ImageField,
|
|
10
|
-
FileField,
|
|
11
|
-
NumberField,
|
|
12
|
-
RichTextField,
|
|
13
|
-
TextField,
|
|
14
|
-
UrlField,
|
|
15
|
-
SelectField,
|
|
16
|
-
ArrayField,
|
|
17
|
-
ReferenceField,
|
|
18
|
-
ReferenceManyField,
|
|
19
|
-
ReferenceArrayField,
|
|
20
|
-
} from "react-admin"
|
|
21
|
-
import {
|
|
22
|
-
BooleanInput,
|
|
23
|
-
NullableBooleanInput,
|
|
24
11
|
DateInput,
|
|
25
12
|
DateTimeInput,
|
|
26
|
-
|
|
13
|
+
EmailField,
|
|
14
|
+
FileField,
|
|
27
15
|
FileInput,
|
|
16
|
+
ImageField,
|
|
17
|
+
ImageInput,
|
|
18
|
+
NullableBooleanInput,
|
|
19
|
+
NumberField,
|
|
28
20
|
NumberInput,
|
|
29
21
|
PasswordInput,
|
|
30
|
-
TextInput,
|
|
31
|
-
AutocompleteInput,
|
|
32
22
|
RadioButtonGroupInput,
|
|
33
|
-
|
|
34
|
-
ArrayInput,
|
|
35
|
-
AutocompleteArrayInput,
|
|
36
|
-
CheckboxGroupInput,
|
|
23
|
+
ReferenceArrayField,
|
|
37
24
|
ReferenceArrayInput,
|
|
25
|
+
ReferenceField,
|
|
38
26
|
ReferenceInput,
|
|
27
|
+
ReferenceManyField,
|
|
28
|
+
RichTextField,
|
|
29
|
+
SelectField,
|
|
30
|
+
SelectInput,
|
|
31
|
+
TextField,
|
|
32
|
+
TextInput,
|
|
33
|
+
UrlField,
|
|
34
|
+
required,
|
|
39
35
|
} from "react-admin"
|
|
40
36
|
|
|
41
|
-
import AvatarField from "./fields
|
|
42
|
-
import
|
|
43
|
-
import FKInput from "./inputs/FKInput"
|
|
44
|
-
import JsonField from "./fields/JsonField"
|
|
45
|
-
import JsonInput from "./inputs/JsonInput"
|
|
37
|
+
import { AvatarField, EditableBooleanField, FKField, JsonField } from "./fields"
|
|
38
|
+
import { FKInput, JsonInput } from "./inputs"
|
|
46
39
|
|
|
47
40
|
const UI = {
|
|
48
41
|
// Fields
|
|
@@ -62,8 +55,9 @@ const UI = {
|
|
|
62
55
|
ReferenceManyField,
|
|
63
56
|
ReferenceArrayField,
|
|
64
57
|
AvatarField,
|
|
65
|
-
|
|
58
|
+
EditableBooleanField,
|
|
66
59
|
FKField,
|
|
60
|
+
JsonField,
|
|
67
61
|
|
|
68
62
|
// Inputs
|
|
69
63
|
BooleanInput,
|
|
@@ -89,6 +83,7 @@ const UI = {
|
|
|
89
83
|
|
|
90
84
|
export function buildRAComponent(name, props) {
|
|
91
85
|
const Item = UI[name]
|
|
86
|
+
if (!Item) return null
|
|
92
87
|
|
|
93
88
|
if (props.required) {
|
|
94
89
|
props.validate = required()
|
|
@@ -97,11 +92,11 @@ export function buildRAComponent(name, props) {
|
|
|
97
92
|
|
|
98
93
|
props.fullWidth = props.fullWidth ?? true
|
|
99
94
|
|
|
100
|
-
if (props.children) props.children =
|
|
95
|
+
if (props.children) props.children = buildRA(props.children)[0]
|
|
101
96
|
|
|
102
97
|
return <Item key={props.source} {...props} />
|
|
103
98
|
}
|
|
104
99
|
|
|
105
|
-
export
|
|
106
|
-
return items.map((item) => buildRAComponent(
|
|
100
|
+
export function buildRA(items) {
|
|
101
|
+
return items.map((item) => buildRAComponent(item[0], item[1]))
|
|
107
102
|
}
|
|
@@ -1,32 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import * as icons from "@mui/icons-material"
|
|
3
2
|
import {
|
|
4
3
|
Button,
|
|
5
|
-
|
|
6
|
-
useUnselectAll,
|
|
4
|
+
useListContext,
|
|
7
5
|
useNotify,
|
|
8
6
|
useRecordContext,
|
|
7
|
+
useRefresh,
|
|
8
|
+
useResourceContext,
|
|
9
|
+
useUnselectAll,
|
|
9
10
|
} from "react-admin"
|
|
10
|
-
import * as icons from "@mui/icons-material"
|
|
11
11
|
|
|
12
|
-
import useAction from "../hooks/useAction"
|
|
12
|
+
import { useAction } from "../hooks/useAction"
|
|
13
|
+
import { buildIcon } from "../utils"
|
|
13
14
|
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
title,
|
|
18
|
-
action,
|
|
19
|
-
resource,
|
|
20
|
-
selectedIds,
|
|
21
|
-
}) => {
|
|
15
|
+
export function BulkActionButton({ label, icon, title, action }) {
|
|
16
|
+
const resource = useResourceContext()
|
|
17
|
+
const { selectedIds } = useListContext()
|
|
22
18
|
const refresh = useRefresh(),
|
|
23
19
|
unselectAll = useUnselectAll(resource),
|
|
24
|
-
notify = useNotify()
|
|
25
|
-
Icon = icons[icon]
|
|
20
|
+
notify = useNotify()
|
|
26
21
|
|
|
27
22
|
const mutation = useAction(resource, action)
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
const onClick = () => {
|
|
30
25
|
mutation.mutate(
|
|
31
26
|
{
|
|
32
27
|
action,
|
|
@@ -46,18 +41,13 @@ export const BulkActionButton = ({
|
|
|
46
41
|
}
|
|
47
42
|
|
|
48
43
|
return (
|
|
49
|
-
<Button
|
|
50
|
-
|
|
51
|
-
title={title}
|
|
52
|
-
onClick={onClick}
|
|
53
|
-
disabled={mutation.isLoading}
|
|
54
|
-
>
|
|
55
|
-
{Icon && <Icon />}
|
|
44
|
+
<Button label={label} title={title} onClick={onClick} disabled={mutation.isLoading}>
|
|
45
|
+
{buildIcon(icon)}
|
|
56
46
|
</Button>
|
|
57
47
|
)
|
|
58
48
|
}
|
|
59
49
|
|
|
60
|
-
export
|
|
50
|
+
export function ActionButton(props) {
|
|
61
51
|
const { icon, label, title, resource, action } = props
|
|
62
52
|
const record = useRecordContext()
|
|
63
53
|
const { mutate, isLoading } = useAction(resource, action)
|
|
@@ -66,7 +56,7 @@ export const ActionButton = (props) => {
|
|
|
66
56
|
notify = useNotify(),
|
|
67
57
|
Icon = icons[icon]
|
|
68
58
|
|
|
69
|
-
|
|
59
|
+
const onClick = () => {
|
|
70
60
|
mutate(
|
|
71
61
|
{ record },
|
|
72
62
|
{
|
|
@@ -75,8 +65,8 @@ export const ActionButton = (props) => {
|
|
|
75
65
|
if (data && data.redirectTo) window.location = data.redirectTo
|
|
76
66
|
if (data && data.message) notify(data.message, { type: "success" })
|
|
77
67
|
},
|
|
78
|
-
onError: (
|
|
79
|
-
notify(typeof
|
|
68
|
+
onError: (err) => {
|
|
69
|
+
notify(typeof err === "string" ? err : err.message, {
|
|
80
70
|
type: "error",
|
|
81
71
|
})
|
|
82
72
|
},
|
|
@@ -90,5 +80,3 @@ export const ActionButton = (props) => {
|
|
|
90
80
|
</Button>
|
|
91
81
|
)
|
|
92
82
|
}
|
|
93
|
-
|
|
94
|
-
export default ActionButton
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import React from "react"
|
|
2
1
|
import { Button } from "react-admin"
|
|
3
2
|
import { Link } from "react-router-dom"
|
|
4
|
-
import
|
|
3
|
+
import { AdminShowLink } from "../types"
|
|
4
|
+
import { buildIcon } from "../utils"
|
|
5
5
|
|
|
6
|
-
const LinkButton = ({
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const LinkButton = ({
|
|
7
|
+
filters,
|
|
8
|
+
icon,
|
|
9
|
+
label,
|
|
10
|
+
resource,
|
|
11
|
+
title,
|
|
12
|
+
}: AdminShowLink & { resource: string; filters: any }) => {
|
|
13
|
+
const linkParams = {
|
|
9
14
|
pathname: `/${resource}`,
|
|
10
15
|
search: filters ? `filter=${JSON.stringify(filters)}` : undefined,
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
return (
|
|
14
19
|
<Button label={label} title={title} component={Link} to={linkParams}>
|
|
15
|
-
{
|
|
20
|
+
{buildIcon(icon)}
|
|
16
21
|
</Button>
|
|
17
22
|
)
|
|
18
23
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AdminOpts } from "./types"
|
|
2
|
+
import { APIParams, makeRequest, setupAdmin } from "./utils"
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
+
export function MuffinDataprovider({ apiUrl }: AdminOpts) {
|
|
4
5
|
const methods = {
|
|
5
|
-
getList: async (resource
|
|
6
|
-
const
|
|
6
|
+
getList: async (resource: string, params: any) => {
|
|
7
|
+
const { filter, pagination, sort } = params
|
|
8
|
+
const query: APIParams["query"] = {}
|
|
7
9
|
if (filter) query.where = JSON.stringify(filter)
|
|
8
10
|
if (pagination) {
|
|
9
11
|
const { page, perPage: limit } = pagination
|
|
@@ -14,7 +16,6 @@ export default (apiUrl) => {
|
|
|
14
16
|
const { field, order } = sort
|
|
15
17
|
query.sort = order == "ASC" ? field : `-${field}`
|
|
16
18
|
}
|
|
17
|
-
|
|
18
19
|
const { headers, json } = await makeRequest(`${apiUrl}/${resource}`, {
|
|
19
20
|
query,
|
|
20
21
|
})
|
|
@@ -89,6 +90,7 @@ export default (apiUrl) => {
|
|
|
89
90
|
return { data: json }
|
|
90
91
|
},
|
|
91
92
|
}
|
|
92
|
-
|
|
93
93
|
return methods
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
setupAdmin(["dataprovider"], MuffinDataprovider)
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Avatar from "@mui/material/Avatar"
|
|
2
2
|
import get from "lodash/get"
|
|
3
3
|
import { useRecordContext } from "ra-core"
|
|
4
|
-
import Avatar from "@mui/material/Avatar"
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
export function AvatarField({ source, alt, style, nameProp, ...props }) {
|
|
7
6
|
const record = useRecordContext(props)
|
|
8
|
-
|
|
9
|
-
let value = get(record, source),
|
|
7
|
+
const value = get(record, source),
|
|
10
8
|
name = record[nameProp]
|
|
11
9
|
|
|
12
10
|
const letters = name
|
|
@@ -29,5 +27,3 @@ AvatarField.displayName = "AvatarField"
|
|
|
29
27
|
AvatarField.defaultProps = {
|
|
30
28
|
addLabel: true,
|
|
31
29
|
}
|
|
32
|
-
|
|
33
|
-
export default AvatarField
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import React from "react"
|
|
2
1
|
import { ReferenceField, TextField } from "react-admin"
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
export function FKField({ refSource, refID, link, reference, source, ...props }) {
|
|
5
4
|
return (
|
|
6
|
-
<ReferenceField
|
|
7
|
-
link={link || "show"}
|
|
8
|
-
reference={reference}
|
|
9
|
-
source={source}
|
|
10
|
-
{...props}
|
|
11
|
-
>
|
|
5
|
+
<ReferenceField link={link || "show"} reference={reference} source={source} {...props}>
|
|
12
6
|
<>
|
|
13
7
|
<TextField source={refSource} />
|
|
14
8
|
{" (#"}
|
|
@@ -23,5 +17,3 @@ FKField.displayName = "FKField"
|
|
|
23
17
|
FKField.defaultProps = {
|
|
24
18
|
addLabel: true,
|
|
25
19
|
}
|
|
26
|
-
|
|
27
|
-
export default FKField
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import get from "lodash/get"
|
|
2
|
-
|
|
3
|
-
import React, { useState } from "react"
|
|
2
|
+
import { useState } from "react"
|
|
4
3
|
import { Button, FunctionField, useRecordContext } from "react-admin"
|
|
5
4
|
|
|
6
|
-
export
|
|
5
|
+
export function JsonField({ label, source }) {
|
|
7
6
|
const [expand, setExpand] = useState(false)
|
|
8
7
|
const record = useRecordContext()
|
|
9
8
|
const src = JSON.stringify(get(record, source), null, 2)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useDataProvider } from "react-admin"
|
|
2
2
|
import { useMutation } from "react-query"
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export function useAction(resource, action) {
|
|
5
5
|
const dataProvider = useDataProvider()
|
|
6
|
-
return useMutation((params) =>
|
|
6
|
+
return useMutation<{ data: any }, { message: string } | string, any>((params: any) =>
|
|
7
7
|
dataProvider.runAction(resource, action, params)
|
|
8
8
|
)
|
|
9
9
|
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createRoot } from "react-dom/client"
|
|
2
|
+
import { buildAdmin } from "./utils"
|
|
3
|
+
|
|
4
|
+
export * from "./MuffinAdmin"
|
|
5
|
+
export * from "./MuffinResource"
|
|
6
|
+
export * from "./MuffinResourceCreate"
|
|
7
|
+
export * from "./MuffinResourceEdit"
|
|
8
|
+
export * from "./MuffinResourceList"
|
|
9
|
+
export * from "./MuffinResourceShow"
|
|
10
|
+
export * from "./authprovider"
|
|
11
|
+
export * from "./buildRA"
|
|
12
|
+
export * from "./buttons"
|
|
13
|
+
export * from "./dataprovider"
|
|
14
|
+
export * from "./fields"
|
|
15
|
+
export * from "./types"
|
|
16
|
+
export * from "./utils"
|
|
17
|
+
|
|
18
|
+
export async function initAdmin(prefix = "", containerId: string = "root") {
|
|
19
|
+
const response = await fetch(`${prefix}/ra.json`)
|
|
20
|
+
const props = await response.json()
|
|
21
|
+
const container = document.getElementById(containerId)
|
|
22
|
+
if (!container) throw new Error(`Container #${containerId} not found`)
|
|
23
|
+
const root = createRoot(container)
|
|
24
|
+
root.render(buildAdmin(["admin"], props))
|
|
25
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AutocompleteInput, ReferenceInput } from "react-admin"
|
|
2
|
+
|
|
3
|
+
export function FKInput({ refProp, refSource, fullWidth, reference, source, ...props }) {
|
|
4
|
+
const filterToQuery = (search) => {
|
|
5
|
+
const filters = {}
|
|
6
|
+
filters[refProp] = search
|
|
7
|
+
return filters
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
refSource = refSource || "id"
|
|
11
|
+
|
|
12
|
+
const renderText = (record) => {
|
|
13
|
+
const pk = record[refSource]
|
|
14
|
+
return (pk && `${record[refProp]} (#${pk})`) || ""
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<ReferenceInput reference={reference} source={source} filterToQuery={filterToQuery} {...props}>
|
|
19
|
+
<AutocompleteInput
|
|
20
|
+
source={refSource}
|
|
21
|
+
optionText={renderText}
|
|
22
|
+
fullWidth={fullWidth}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
</ReferenceInput>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react"
|
|
2
1
|
import { TextInput } from "react-admin"
|
|
3
2
|
import isJSON from "validator/lib/isJSON"
|
|
4
3
|
|
|
@@ -9,6 +8,7 @@ const parseFunction = (json) => {
|
|
|
9
8
|
try {
|
|
10
9
|
retval = JSON.parse(json)
|
|
11
10
|
} finally {
|
|
11
|
+
// eslint-disable-next-line no-unsafe-finally
|
|
12
12
|
return retval
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -31,7 +31,7 @@ const parseFunction = (json) => {
|
|
|
31
31
|
* @example
|
|
32
32
|
* <JsonInput source='config' label='JSON Config' parse={false}/>
|
|
33
33
|
*/
|
|
34
|
-
export
|
|
34
|
+
export function JsonInput(props) {
|
|
35
35
|
const {
|
|
36
36
|
validate = [],
|
|
37
37
|
errortext = DEFAULT_ERRORTEXT,
|
|
@@ -50,8 +50,7 @@ export default function JsonInput(props) {
|
|
|
50
50
|
|
|
51
51
|
const formatJSON = (json) => {
|
|
52
52
|
let retval = json
|
|
53
|
-
if (retval && typeof retval === "object")
|
|
54
|
-
retval = JSON.stringify(retval, null, 2)
|
|
53
|
+
if (retval && typeof retval === "object") retval = JSON.stringify(retval, null, 2)
|
|
55
54
|
return retval
|
|
56
55
|
}
|
|
57
56
|
rest.format = formatJSON
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export type TProps = {
|
|
2
|
+
[key: string]: any
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type AdminAction = {
|
|
6
|
+
view: string
|
|
7
|
+
icon: string
|
|
8
|
+
action: string
|
|
9
|
+
title: string
|
|
10
|
+
label: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type AdminField = [string, { source: string }]
|
|
14
|
+
export type AdminInput = [string, { required: boolean; source: string }]
|
|
15
|
+
|
|
16
|
+
export type AdminShowLink = {
|
|
17
|
+
label: string
|
|
18
|
+
title?: string
|
|
19
|
+
icon?: string
|
|
20
|
+
}
|
|
21
|
+
export type AdminShowProps = {
|
|
22
|
+
actions: AdminAction[]
|
|
23
|
+
fields: AdminField[]
|
|
24
|
+
links: Record<string, AdminShowLink>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type AdminResourceProps = {
|
|
28
|
+
name: string
|
|
29
|
+
icon?: string
|
|
30
|
+
label: string
|
|
31
|
+
create: AdminInput[]
|
|
32
|
+
edit: {
|
|
33
|
+
actions: AdminAction[]
|
|
34
|
+
inputs: AdminInput[]
|
|
35
|
+
}
|
|
36
|
+
list: {
|
|
37
|
+
limit: number
|
|
38
|
+
limitMax: number
|
|
39
|
+
actions: AdminAction[]
|
|
40
|
+
fields: AdminField[]
|
|
41
|
+
filters: AdminInput[]
|
|
42
|
+
show: boolean
|
|
43
|
+
edit?: boolean
|
|
44
|
+
}
|
|
45
|
+
show: AdminShowProps
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type AdminDashboardBlock = {
|
|
49
|
+
title: string
|
|
50
|
+
value: any
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type AdminOpts = {
|
|
54
|
+
adminProps: {
|
|
55
|
+
title: string
|
|
56
|
+
disableTelemetry?: boolean
|
|
57
|
+
mutationMode?: "optimistic" | "pessimistic" | "undoable"
|
|
58
|
+
}
|
|
59
|
+
apiUrl: string
|
|
60
|
+
appBarLinks: [{ ulr: string; title: string; icon?: string }]
|
|
61
|
+
auth: {
|
|
62
|
+
identityURL: string
|
|
63
|
+
authorizeURL: string
|
|
64
|
+
loginURL?: string
|
|
65
|
+
logoutURL?: string
|
|
66
|
+
required: boolean
|
|
67
|
+
storage: "localstorage" | "cookie"
|
|
68
|
+
storageName: string
|
|
69
|
+
}
|
|
70
|
+
dashboard: AdminDashboardBlock[] | AdminDashboardBlock
|
|
71
|
+
resources: AdminResourceProps[]
|
|
72
|
+
version: string
|
|
73
|
+
}
|
package/src/utils.tsx
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as icons from "@mui/icons-material"
|
|
2
|
+
import { stringify } from "query-string"
|
|
3
|
+
import { fetchUtils } from "ra-core"
|
|
4
|
+
import { createContext } from "react"
|
|
5
|
+
import { AdminOpts } from "./types"
|
|
6
|
+
|
|
7
|
+
const builders = new Map<string, (props) => any>()
|
|
8
|
+
|
|
9
|
+
export function setupAdmin<T>(adminType: string[], fc: (props) => T) {
|
|
10
|
+
const key = adminType.join("/")
|
|
11
|
+
builders.set(key, fc)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildAdmin(adminType: string[], props = {}) {
|
|
15
|
+
if (process.env.NODE_ENV == "development") console.log(adminType, props)
|
|
16
|
+
const builder = findBuilder(adminType)
|
|
17
|
+
if (builder) return builder(props)
|
|
18
|
+
|
|
19
|
+
console.warn(`No admin renderer found for ${adminType.join("/")}`)
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function findBuilder(adminType: string[]) {
|
|
24
|
+
const key = [...adminType]
|
|
25
|
+
while (key.length) {
|
|
26
|
+
const render = builders.get(key.join("/"))
|
|
27
|
+
if (render) return render
|
|
28
|
+
key.pop()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const AdminPropsContext = createContext<AdminOpts | null>(null)
|
|
33
|
+
|
|
34
|
+
export type APIParams = {
|
|
35
|
+
method?: string
|
|
36
|
+
query?: {
|
|
37
|
+
where?: string
|
|
38
|
+
limit?: number
|
|
39
|
+
offset?: number
|
|
40
|
+
sort?: string
|
|
41
|
+
ids?: string[]
|
|
42
|
+
}
|
|
43
|
+
data?: any
|
|
44
|
+
headers?: any
|
|
45
|
+
body?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const requestHeaders = {}
|
|
49
|
+
|
|
50
|
+
export function makeRequest(url: string, params: APIParams = {}) {
|
|
51
|
+
const { data, query, ...opts } = params || {}
|
|
52
|
+
|
|
53
|
+
if (data) opts.body = JSON.stringify(data)
|
|
54
|
+
if (query) url = `${url}?${stringify(query)}`
|
|
55
|
+
|
|
56
|
+
return fetchUtils.fetchJson(url, {
|
|
57
|
+
...opts,
|
|
58
|
+
headers: new Headers({ ...requestHeaders, ...opts.headers }),
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function findIcon(icon?: string) {
|
|
63
|
+
return icon ? icons[icon] : undefined
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function buildIcon(icon?: string) {
|
|
67
|
+
const Icon = findIcon(icon)
|
|
68
|
+
if (Icon) return <Icon />
|
|
69
|
+
}
|
package/src/web.ts
ADDED
package/dist/cjs/admin.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
-
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
6
|
-
var _react = _interopRequireDefault(require("react"));
|
|
7
|
-
var _reactAdmin = require("react-admin");
|
|
8
|
-
var _material = require("@mui/material");
|
|
9
|
-
var icons = _interopRequireWildcard(require("@mui/icons-material"));
|
|
10
|
-
var _authprovider = _interopRequireDefault(require("./authprovider"));
|
|
11
|
-
var _dataprovider = _interopRequireDefault(require("./dataprovider"));
|
|
12
|
-
var _utils = require("./utils");
|
|
13
|
-
require("./dashboard");
|
|
14
|
-
require("./resources");
|
|
15
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
16
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
-
var darkTheme = (0, _material.createTheme)({
|
|
18
|
-
palette: {
|
|
19
|
-
mode: "dark"
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// Initialize the admin
|
|
24
|
-
(0, _utils.setupAdmin)("admin", function (props) {
|
|
25
|
-
var apiUrl = props.apiUrl,
|
|
26
|
-
auth = props.auth,
|
|
27
|
-
adminProps = props.adminProps,
|
|
28
|
-
appBarLinks = props.appBarLinks,
|
|
29
|
-
dashboard = props.dashboard,
|
|
30
|
-
resources = props.resources;
|
|
31
|
-
var appBar = function appBar(props) {
|
|
32
|
-
return /*#__PURE__*/_react["default"].createElement(_reactAdmin.AppBar, props, /*#__PURE__*/_react["default"].createElement(_material.Typography, {
|
|
33
|
-
variant: "h6",
|
|
34
|
-
color: "inherit",
|
|
35
|
-
id: "react-admin-title",
|
|
36
|
-
style: {
|
|
37
|
-
flex: 1,
|
|
38
|
-
textOverflow: "ellipsis",
|
|
39
|
-
whiteSpace: "nowrap",
|
|
40
|
-
overflow: "hidden"
|
|
41
|
-
}
|
|
42
|
-
}), /*#__PURE__*/_react["default"].createElement(_reactAdmin.ToggleThemeButton, {
|
|
43
|
-
lightTheme: _reactAdmin.defaultTheme,
|
|
44
|
-
darkTheme: darkTheme
|
|
45
|
-
}), appBarLinks.map(function (info) {
|
|
46
|
-
return /*#__PURE__*/_react["default"].createElement(_material.Tooltip, {
|
|
47
|
-
key: info.url,
|
|
48
|
-
title: info.title
|
|
49
|
-
}, /*#__PURE__*/_react["default"].createElement(_material.IconButton, {
|
|
50
|
-
color: "inherit",
|
|
51
|
-
href: info.url
|
|
52
|
-
}, /*#__PURE__*/_react["default"].createElement(_material.SvgIcon, {
|
|
53
|
-
component: icons[info.icon]
|
|
54
|
-
})));
|
|
55
|
-
}));
|
|
56
|
-
};
|
|
57
|
-
return /*#__PURE__*/_react["default"].createElement(_reactAdmin.Admin, (0, _extends2["default"])({
|
|
58
|
-
authProvider: (0, _utils.processAdmin)("auth", auth),
|
|
59
|
-
dataProvider: (0, _utils.processAdmin)("data", apiUrl),
|
|
60
|
-
dashboard: (0, _utils.processAdmin)("dashboard", dashboard),
|
|
61
|
-
loginPage: (0, _utils.processAdmin)("login", auth),
|
|
62
|
-
layout: function layout(props) {
|
|
63
|
-
return /*#__PURE__*/_react["default"].createElement(_reactAdmin.Layout, (0, _extends2["default"])({
|
|
64
|
-
appBar: appBar
|
|
65
|
-
}, props));
|
|
66
|
-
}
|
|
67
|
-
}, adminProps), (0, _utils.processAdmin)("resources", {
|
|
68
|
-
resources: resources,
|
|
69
|
-
adminProps: adminProps
|
|
70
|
-
}));
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Initialize authentication and data providers
|
|
74
|
-
(0, _utils.setupAdmin)("auth", _authprovider["default"]);
|
|
75
|
-
(0, _utils.setupAdmin)("data", _dataprovider["default"]);
|
|
76
|
-
|
|
77
|
-
// Initialize login page
|
|
78
|
-
(0, _utils.setupAdmin)("login", function () {
|
|
79
|
-
return _reactAdmin.Login;
|
|
80
|
-
});
|