muffin-admin 2.7.2 → 2.8.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/MuffinAdmin.d.ts +4 -3
- package/dist/MuffinAdmin.js +20 -9
- package/dist/MuffinDashboard.d.ts +1 -4
- package/dist/MuffinDashboard.js +5 -3
- package/dist/MuffinResource.d.ts +2 -2
- package/dist/MuffinResource.js +8 -3
- package/dist/MuffinResourceCreate.d.ts +1 -4
- package/dist/MuffinResourceCreate.js +10 -6
- package/dist/MuffinResourceEdit.d.ts +1 -2
- package/dist/MuffinResourceEdit.js +16 -12
- package/dist/MuffinResourceList.d.ts +1 -2
- package/dist/MuffinResourceList.js +13 -8
- package/dist/MuffinResourceShow.d.ts +1 -2
- package/dist/MuffinResourceShow.js +5 -4
- package/dist/actions/LinkAction.js +3 -4
- package/dist/authprovider.js +3 -3
- package/dist/buildRA.d.ts +2 -3
- package/dist/buildRA.js +4 -1
- package/dist/context.d.ts +3 -0
- package/dist/context.js +2 -0
- package/dist/dataprovider.d.ts +1 -2
- package/dist/dataprovider.js +1 -1
- package/dist/hooks/index.d.ts +3 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/useMuffinAdminOpts.d.ts +1 -0
- package/dist/hooks/useMuffinAdminOpts.js +5 -0
- package/dist/hooks/useMuffinResourceOpts.d.ts +1 -0
- package/dist/hooks/useMuffinResourceOpts.js +7 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils.d.ts +1 -4
- package/dist/utils.js +7 -7
- package/package.json +1 -1
- package/src/MuffinAdmin.tsx +48 -30
- package/src/MuffinDashboard.tsx +7 -5
- package/src/MuffinResource.tsx +13 -17
- package/src/MuffinResourceCreate.tsx +11 -8
- package/src/MuffinResourceEdit.tsx +28 -26
- package/src/MuffinResourceList.tsx +27 -21
- package/src/MuffinResourceShow.tsx +6 -5
- package/src/actions/LinkAction.tsx +3 -4
- package/src/authprovider.ts +3 -3
- package/src/buildRA.tsx +6 -2
- package/src/context.ts +4 -0
- package/src/dataprovider.ts +1 -2
- package/src/hooks/index.ts +3 -1
- package/src/hooks/useMuffinAdminOpts.ts +6 -0
- package/src/hooks/useMuffinResourceOpts.ts +8 -0
- package/src/index.tsx +11 -4
- package/src/utils.tsx +6 -9
package/dist/utils.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import { AdminOpts } from "./types";
|
|
3
|
-
export declare function setupAdmin<T>(adminType: string[], fc: (opts: any, props?: any) => T): void;
|
|
1
|
+
export declare function setupAdmin<T>(adminType: string[], fc: (props: any) => T): void;
|
|
4
2
|
export declare function buildAdmin(adminType: string[], props?: {}): any;
|
|
5
3
|
export declare function findBuilder(adminType: string[]): (props: any) => any;
|
|
6
|
-
export declare const AdminPropsContext: import("react").Context<AdminOpts>;
|
|
7
4
|
export type APIParams = {
|
|
8
5
|
method?: string;
|
|
9
6
|
query?: {
|
package/dist/utils.js
CHANGED
|
@@ -13,31 +13,31 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
13
13
|
import * as icons from "@mui/icons-material";
|
|
14
14
|
import { stringify } from "query-string";
|
|
15
15
|
import { fetchUtils } from "ra-core";
|
|
16
|
-
import { createContext } from "react";
|
|
17
16
|
const builders = new Map();
|
|
18
17
|
export function setupAdmin(adminType, fc) {
|
|
19
18
|
const key = adminType.join("/");
|
|
20
19
|
builders.set(key, fc);
|
|
21
20
|
}
|
|
22
21
|
export function buildAdmin(adminType, props = {}) {
|
|
23
|
-
if (process.env.NODE_ENV == "development")
|
|
24
|
-
console.log(adminType, props);
|
|
25
22
|
const builder = findBuilder(adminType);
|
|
23
|
+
if (process.env.NODE_ENV == "development")
|
|
24
|
+
console.log(props);
|
|
26
25
|
if (builder)
|
|
27
26
|
return builder(props);
|
|
28
27
|
console.warn(`No admin renderer found for ${adminType.join("/")}`);
|
|
29
28
|
return null;
|
|
30
29
|
}
|
|
31
30
|
export function findBuilder(adminType) {
|
|
31
|
+
if (process.env.NODE_ENV == "development")
|
|
32
|
+
console.log(adminType);
|
|
32
33
|
const key = [...adminType];
|
|
33
34
|
while (key.length) {
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
35
|
+
const builder = builders.get(key.join("/"));
|
|
36
|
+
if (builder)
|
|
37
|
+
return builder;
|
|
37
38
|
key.pop();
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
|
-
export const AdminPropsContext = createContext(null);
|
|
41
41
|
export const requestHeaders = {};
|
|
42
42
|
export function makeRequest(url, params = {}) {
|
|
43
43
|
const _a = params || {}, { data, query } = _a, opts = __rest(_a, ["data", "query"]);
|
package/package.json
CHANGED
package/src/MuffinAdmin.tsx
CHANGED
|
@@ -2,21 +2,56 @@ import IconButton from "@mui/material/IconButton"
|
|
|
2
2
|
import SvgIcon from "@mui/material/SvgIcon"
|
|
3
3
|
import Tooltip from "@mui/material/Tooltip"
|
|
4
4
|
import Typography from "@mui/material/Typography"
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
import {
|
|
6
|
+
Admin,
|
|
7
|
+
AdminProps,
|
|
8
|
+
AppBar,
|
|
9
|
+
AppBarProps,
|
|
10
|
+
AuthProvider,
|
|
11
|
+
DataProvider,
|
|
12
|
+
Layout,
|
|
13
|
+
LayoutProps,
|
|
14
|
+
Login,
|
|
15
|
+
} from "react-admin"
|
|
16
|
+
|
|
17
|
+
import { useMuffinAdminOpts } from "./hooks"
|
|
18
|
+
import { buildAdmin, findBuilder, findIcon, setupAdmin } from "./utils"
|
|
19
|
+
|
|
20
|
+
export function MuffinAdmin(props: AdminProps) {
|
|
21
|
+
const opts = useMuffinAdminOpts()
|
|
22
|
+
const { resources = [], auth, adminProps, apiUrl } = opts
|
|
23
|
+
|
|
24
|
+
document.title = adminProps?.title || "Muffin Admin"
|
|
25
|
+
const authProvider = findBuilder(["authprovider"])(auth) as AuthProvider
|
|
26
|
+
const dataProvider = findBuilder(["dataprovider"])(apiUrl) as DataProvider
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Admin
|
|
30
|
+
requireAuth={auth.required}
|
|
31
|
+
authProvider={authProvider}
|
|
32
|
+
dataProvider={dataProvider}
|
|
33
|
+
layout={findBuilder(["layout"])}
|
|
34
|
+
loginPage={findBuilder(["loginpage"])}
|
|
35
|
+
dashboard={findBuilder(["dashboard"])}
|
|
36
|
+
darkTheme={{ palette: { mode: "dark" } }}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
{resources?.map(({ name }) => buildAdmin(["resource", name], { name }))}
|
|
40
|
+
</Admin>
|
|
15
41
|
)
|
|
42
|
+
}
|
|
16
43
|
|
|
17
|
-
|
|
44
|
+
setupAdmin(["admin"], MuffinAdmin)
|
|
18
45
|
|
|
19
|
-
|
|
46
|
+
export function MuffinAdminLayout(props: LayoutProps) {
|
|
47
|
+
return <Layout {...props} appBar={findBuilder(["appbar"])} />
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setupAdmin(["layout"], MuffinAdminLayout)
|
|
51
|
+
|
|
52
|
+
export function MuffinAppBar(props: AppBarProps) {
|
|
53
|
+
const { appBarLinks } = useMuffinAdminOpts()
|
|
54
|
+
return (
|
|
20
55
|
<AppBar {...props}>
|
|
21
56
|
<Typography
|
|
22
57
|
variant="h6"
|
|
@@ -38,26 +73,9 @@ export function MuffinAdmin(opts: AdminOpts, props: AdminProps) {
|
|
|
38
73
|
))}
|
|
39
74
|
</AppBar>
|
|
40
75
|
)
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<AdminPropsContext.Provider value={opts}>
|
|
44
|
-
<Admin
|
|
45
|
-
authProvider={buildAdmin(["authprovider"], auth)}
|
|
46
|
-
dataProvider={buildAdmin(["dataprovider"], opts) as unknown as DataProvider}
|
|
47
|
-
layout={(props) => <Layout {...props} appBar={appBar} />}
|
|
48
|
-
loginPage={findBuilder(["loginpage"])}
|
|
49
|
-
dashboard={dashboard ? buildAdmin(["dashboard"], dashboard) : null}
|
|
50
|
-
requireAuth={auth.required}
|
|
51
|
-
darkTheme={{ palette: { mode: "dark" } }}
|
|
52
|
-
{...props}
|
|
53
|
-
>
|
|
54
|
-
{children}
|
|
55
|
-
</Admin>
|
|
56
|
-
</AdminPropsContext.Provider>
|
|
57
|
-
)
|
|
58
76
|
}
|
|
59
77
|
|
|
60
|
-
setupAdmin(["
|
|
78
|
+
setupAdmin(["appbar"], MuffinAppBar)
|
|
61
79
|
|
|
62
80
|
// Initialize login page
|
|
63
81
|
setupAdmin(["loginpage"], Login)
|
package/src/MuffinDashboard.tsx
CHANGED
|
@@ -6,17 +6,21 @@ import TableBody from "@mui/material/TableBody"
|
|
|
6
6
|
import TableCell from "@mui/material/TableCell"
|
|
7
7
|
import TableRow from "@mui/material/TableRow"
|
|
8
8
|
import Typography from "@mui/material/Typography"
|
|
9
|
-
import {
|
|
9
|
+
import { useMuffinAdminOpts } from "./hooks"
|
|
10
|
+
import { AdminDashboardBlock } from "./types"
|
|
10
11
|
import { setupAdmin } from "./utils"
|
|
11
12
|
|
|
12
|
-
export function MuffinDashboard(
|
|
13
|
+
export function MuffinDashboard() {
|
|
14
|
+
const { dashboard } = useMuffinAdminOpts()
|
|
13
15
|
return (
|
|
14
16
|
<Grid container spacing={1}>
|
|
15
|
-
<AdminCards src={
|
|
17
|
+
<AdminCards src={dashboard} />
|
|
16
18
|
</Grid>
|
|
17
19
|
)
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
setupAdmin(["dashboard"], MuffinDashboard)
|
|
23
|
+
|
|
20
24
|
function AdminCards({ src }: { src: AdminDashboardBlock | AdminDashboardBlock[] }) {
|
|
21
25
|
if (Array.isArray(src))
|
|
22
26
|
return (
|
|
@@ -60,5 +64,3 @@ const AdminTableView = ({ src }) => (
|
|
|
60
64
|
</TableBody>
|
|
61
65
|
</Table>
|
|
62
66
|
)
|
|
63
|
-
|
|
64
|
-
setupAdmin(["dashboard"], (dashboard) => () => <MuffinDashboard src={dashboard} />)
|
package/src/MuffinResource.tsx
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
import { Resource } from "react-admin"
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Resource, ResourceProps } from "react-admin"
|
|
2
|
+
import { useMuffinAdminOpts } from "./hooks"
|
|
3
|
+
import { findBuilder, findIcon, setupAdmin } from "./utils"
|
|
4
|
+
|
|
5
|
+
export function MuffinResource({ name, ...props }: ResourceProps) {
|
|
6
|
+
const adminOpts = useMuffinAdminOpts()
|
|
7
|
+
const opts = adminOpts?.resources.find((r) => r.name == name)
|
|
8
|
+
if (!opts) return null
|
|
4
9
|
|
|
5
|
-
export function MuffinResource({
|
|
6
|
-
name,
|
|
7
|
-
create: createProps,
|
|
8
|
-
edit: editProps,
|
|
9
|
-
list: listProps,
|
|
10
|
-
show: showProps,
|
|
11
|
-
icon,
|
|
12
|
-
...props
|
|
13
|
-
}: AdminResourceProps) {
|
|
14
10
|
return (
|
|
15
11
|
<Resource
|
|
16
12
|
key={name}
|
|
17
13
|
name={name}
|
|
18
|
-
icon={findIcon(icon)}
|
|
19
|
-
create={
|
|
20
|
-
edit={
|
|
21
|
-
list={
|
|
22
|
-
show={
|
|
14
|
+
icon={findIcon(opts.icon)}
|
|
15
|
+
create={findBuilder(["create", name])}
|
|
16
|
+
edit={findBuilder(["edit", name])}
|
|
17
|
+
list={findBuilder(["list", name])}
|
|
18
|
+
show={findBuilder(["show", name])}
|
|
23
19
|
{...props}
|
|
24
20
|
/>
|
|
25
21
|
)
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { Create, ListButton, SimpleForm, TopToolbar
|
|
1
|
+
import { Create, ListButton, SimpleForm, TopToolbar } from "react-admin"
|
|
2
2
|
import { buildRA } from "./buildRA"
|
|
3
|
-
import {
|
|
4
|
-
import { buildAdmin, setupAdmin } from "./utils"
|
|
3
|
+
import { useMuffinResourceOpts } from "./hooks"
|
|
4
|
+
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
5
5
|
|
|
6
|
-
export function MuffinResourceCreate(
|
|
7
|
-
const
|
|
6
|
+
export function MuffinResourceCreate() {
|
|
7
|
+
const { name, create } = useMuffinResourceOpts()
|
|
8
|
+
if (!create) return null
|
|
9
|
+
|
|
10
|
+
const Actions = findBuilder(["create-actions", name])
|
|
8
11
|
|
|
9
12
|
return (
|
|
10
|
-
<Create actions={
|
|
11
|
-
<SimpleForm>{buildAdmin(["create-inputs",
|
|
13
|
+
<Create actions={<Actions />}>
|
|
14
|
+
<SimpleForm>{buildAdmin(["create-inputs", name], create)}</SimpleForm>
|
|
12
15
|
</Create>
|
|
13
16
|
)
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
setupAdmin(["create"],
|
|
19
|
+
setupAdmin(["create"], MuffinResourceCreate)
|
|
17
20
|
|
|
18
21
|
setupAdmin(["create-actions"], () => (
|
|
19
22
|
<TopToolbar>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useContext } from "react"
|
|
2
1
|
import {
|
|
3
2
|
DeleteButton,
|
|
4
3
|
Edit,
|
|
@@ -8,28 +7,25 @@ import {
|
|
|
8
7
|
SimpleForm,
|
|
9
8
|
Toolbar,
|
|
10
9
|
TopToolbar,
|
|
11
|
-
useResourceContext,
|
|
12
10
|
} from "react-admin"
|
|
13
11
|
import { buildRA } from "./buildRA"
|
|
14
12
|
import { ActionButton } from "./buttons"
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
13
|
+
import { useMuffinAdminOpts, useMuffinResourceOpts } from "./hooks"
|
|
14
|
+
import { AdminAction } from "./types"
|
|
15
|
+
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
17
16
|
|
|
18
|
-
export function MuffinResourceEdit(
|
|
19
|
-
const resourceName = useResourceContext()
|
|
17
|
+
export function MuffinResourceEdit() {
|
|
20
18
|
const {
|
|
21
|
-
adminProps: { mutationMode },
|
|
22
|
-
} =
|
|
19
|
+
adminProps: { mutationMode = "optimistic" },
|
|
20
|
+
} = useMuffinAdminOpts()
|
|
21
|
+
const { edit, name } = useMuffinResourceOpts()
|
|
22
|
+
if (!edit) return null
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
const
|
|
24
|
+
const { actions, inputs, remove, ...opts } = edit
|
|
25
|
+
const Actions = findBuilder(["edit-actions", name])
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
|
-
<Edit
|
|
29
|
-
actions={buildAdmin(["edit-actions", resourceName], actions)}
|
|
30
|
-
mutationMode={mutationMode || "optimistic"}
|
|
31
|
-
{...opts}
|
|
32
|
-
>
|
|
28
|
+
<Edit actions={<Actions actions={actions} />} mutationMode={mutationMode} {...opts}>
|
|
33
29
|
<SimpleForm
|
|
34
30
|
toolbar={
|
|
35
31
|
<Toolbar>
|
|
@@ -44,20 +40,26 @@ export function MuffinResourceEdit(props: AdminResourceProps["edit"]) {
|
|
|
44
40
|
</Toolbar>
|
|
45
41
|
}
|
|
46
42
|
>
|
|
47
|
-
{buildAdmin(["edit-inputs",
|
|
43
|
+
{buildAdmin(["edit-inputs", name], inputs)}
|
|
48
44
|
</SimpleForm>
|
|
49
45
|
</Edit>
|
|
50
46
|
)
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
setupAdmin(["edit"],
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
49
|
+
setupAdmin(["edit"], MuffinResourceEdit)
|
|
50
|
+
|
|
51
|
+
function MuffinResourceEditActions({ actions }: { actions: AdminAction[] }) {
|
|
52
|
+
return (
|
|
53
|
+
<TopToolbar>
|
|
54
|
+
{actions.map((props, idx) => (
|
|
55
|
+
<ActionButton key={idx} {...props} />
|
|
56
|
+
))}
|
|
57
|
+
<ListButton />
|
|
58
|
+
<ShowButton />
|
|
59
|
+
</TopToolbar>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
setupAdmin(["edit-actions"], MuffinResourceEditActions)
|
|
64
|
+
|
|
63
65
|
setupAdmin(["edit-inputs"], buildRA)
|
|
@@ -1,45 +1,49 @@
|
|
|
1
1
|
import sortBy from "lodash/sortBy"
|
|
2
2
|
import uniq from "lodash/uniq"
|
|
3
|
-
import {
|
|
4
|
-
BulkDeleteButton,
|
|
5
|
-
Datagrid,
|
|
6
|
-
EditButton,
|
|
7
|
-
List,
|
|
8
|
-
Pagination,
|
|
9
|
-
useResourceContext,
|
|
10
|
-
} from "react-admin"
|
|
3
|
+
import { BulkDeleteButton, Datagrid, EditButton, List, Pagination } from "react-admin"
|
|
11
4
|
import { buildRA } from "./buildRA"
|
|
12
5
|
import { BulkActionButton } from "./buttons"
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
6
|
+
import { useMuffinResourceOpts } from "./hooks"
|
|
7
|
+
import { AdminAction } from "./types"
|
|
8
|
+
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
9
|
+
|
|
10
|
+
export function MuffinResourceList() {
|
|
11
|
+
const { name, list } = useMuffinResourceOpts()
|
|
12
|
+
const { fields, edit, show, limit, limitMax, filters, actions, remove, sort } = list
|
|
13
|
+
|
|
14
|
+
const Actions = findBuilder(["list-actions", name])
|
|
15
15
|
|
|
16
|
-
export function MuffinResourceList(props: AdminResourceProps["list"]) {
|
|
17
|
-
const resourceName = useResourceContext()
|
|
18
|
-
const { fields, edit, show, limit, limitMax, filters, actions, remove, sort } = props
|
|
19
16
|
return (
|
|
20
17
|
<List
|
|
21
18
|
sort={sort}
|
|
22
19
|
perPage={limit}
|
|
23
|
-
filters={buildAdmin(["list-filters",
|
|
24
|
-
bulkActionButtons={
|
|
20
|
+
filters={buildAdmin(["list-filters", name], filters)}
|
|
21
|
+
bulkActionButtons={<Actions actions={actions} remove={remove} />}
|
|
25
22
|
pagination={
|
|
26
23
|
<Pagination rowsPerPageOptions={sortBy(uniq([10, 25, 50, 100, limit, limitMax]))} />
|
|
27
24
|
}
|
|
28
25
|
>
|
|
29
26
|
<Datagrid rowClick={show ? "show" : edit ? "edit" : false}>
|
|
30
|
-
{buildAdmin(["list-fields",
|
|
27
|
+
{buildAdmin(["list-fields", name], fields)}
|
|
31
28
|
{edit && <EditButton />}
|
|
32
29
|
</Datagrid>
|
|
33
30
|
</List>
|
|
34
31
|
)
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
setupAdmin(["list"],
|
|
34
|
+
setupAdmin(["list"], MuffinResourceList)
|
|
38
35
|
setupAdmin(["list-fields"], buildRA)
|
|
36
|
+
|
|
39
37
|
setupAdmin(["list-filters"], buildRA)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
|
|
39
|
+
function MuffinResourceListActions({
|
|
40
|
+
actions,
|
|
41
|
+
remove,
|
|
42
|
+
}: {
|
|
43
|
+
actions: AdminAction[]
|
|
44
|
+
remove?: boolean
|
|
45
|
+
}) {
|
|
46
|
+
return (
|
|
43
47
|
<>
|
|
44
48
|
{actions.map((props) => (
|
|
45
49
|
<BulkActionButton key={props.id} {...props} />
|
|
@@ -47,4 +51,6 @@ setupAdmin(
|
|
|
47
51
|
{remove && <BulkDeleteButton />}
|
|
48
52
|
</>
|
|
49
53
|
)
|
|
50
|
-
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setupAdmin(["list-actions"], MuffinResourceListActions)
|
|
@@ -9,16 +9,17 @@ import {
|
|
|
9
9
|
import { LinkAction } from "./actions"
|
|
10
10
|
import { buildRA } from "./buildRA"
|
|
11
11
|
import { ActionButton } from "./buttons"
|
|
12
|
+
import { useMuffinResourceOpts } from "./hooks"
|
|
12
13
|
import { AdminAction, AdminShowProps } from "./types"
|
|
13
14
|
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
14
15
|
|
|
15
|
-
export function MuffinResourceShow(
|
|
16
|
-
const
|
|
17
|
-
const ShowActions = findBuilder(["show-actions",
|
|
16
|
+
export function MuffinResourceShow() {
|
|
17
|
+
const { show, name } = useMuffinResourceOpts()
|
|
18
|
+
const ShowActions = findBuilder(["show-actions", name])
|
|
18
19
|
|
|
19
20
|
return (
|
|
20
|
-
<Show actions={<ShowActions {...
|
|
21
|
-
<SimpleShowLayout>{buildAdmin(["show-fields",
|
|
21
|
+
<Show actions={<ShowActions {...show} />}>
|
|
22
|
+
<SimpleShowLayout>{buildAdmin(["show-fields", name], show)}</SimpleShowLayout>
|
|
22
23
|
</Show>
|
|
23
24
|
)
|
|
24
25
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { useContext } from "react"
|
|
2
1
|
import { useRecordContext, useResourceContext } from "react-admin"
|
|
3
2
|
import LinkButton from "../buttons/LinkButton"
|
|
3
|
+
import { useMuffinAdminOpts } from "../hooks"
|
|
4
4
|
import { AdminShowLink } from "../types"
|
|
5
|
-
import { AdminPropsContext } from "../utils"
|
|
6
5
|
|
|
7
6
|
export function LinkAction({ field, icon, ...props }: AdminShowLink & { resource: string }) {
|
|
8
|
-
const
|
|
7
|
+
const { resources } = useMuffinAdminOpts()
|
|
9
8
|
const record = useRecordContext()
|
|
10
9
|
const currentResource = useResourceContext()
|
|
11
10
|
if (!record) return null
|
|
12
11
|
|
|
13
|
-
const resource =
|
|
12
|
+
const resource = resources.find((r) => r.name === props.resource)
|
|
14
13
|
|
|
15
14
|
return (
|
|
16
15
|
<LinkButton
|
package/src/authprovider.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Cookies from "js-cookie"
|
|
2
|
-
import {
|
|
2
|
+
import { findBuilder, makeRequest, requestHeaders, setupAdmin } from "."
|
|
3
3
|
import { AdminOpts } from "./types"
|
|
4
4
|
|
|
5
5
|
setupAdmin(
|
|
@@ -19,8 +19,8 @@ setupAdmin(["auth-storage-set"], ({ storage }) => (name, value) => {
|
|
|
19
19
|
export function MuffinAuthProvider(props: AdminOpts["auth"]) {
|
|
20
20
|
const { identityURL, authorizeURL, logoutURL, required, storageName } = props
|
|
21
21
|
|
|
22
|
-
const authGet =
|
|
23
|
-
const authSet =
|
|
22
|
+
const authGet = findBuilder(["auth-storage-get"])(props)
|
|
23
|
+
const authSet = findBuilder(["auth-storage-set"])(props)
|
|
24
24
|
|
|
25
25
|
// Initialize request headers
|
|
26
26
|
authSet(storageName, authGet(storageName))
|
package/src/buildRA.tsx
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
import { AvatarField, EditableBooleanField, FKField, JsonField } from "./fields"
|
|
38
38
|
import { FKInput, JsonInput } from "./inputs"
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
const UI: Record<string, JSX.ElementType> = {
|
|
41
41
|
// Fields
|
|
42
42
|
BooleanField,
|
|
43
43
|
ChipField,
|
|
@@ -97,6 +97,10 @@ export function buildRAComponent(name, props) {
|
|
|
97
97
|
return <Item key={props.source} {...props} />
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export function buildRA(items) {
|
|
100
|
+
export function buildRA(items: [string, Record<string, any>][]) {
|
|
101
101
|
return items.map((item) => buildRAComponent(item[0], item[1]))
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
export function registerUI(name, component) {
|
|
105
|
+
UI[name] = component
|
|
106
|
+
}
|
package/src/context.ts
ADDED
package/src/dataprovider.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { AdminOpts } from "./types"
|
|
2
1
|
import { APIParams, makeRequest, setupAdmin } from "./utils"
|
|
3
2
|
|
|
4
|
-
export function MuffinDataprovider(
|
|
3
|
+
export function MuffinDataprovider(apiUrl: string) {
|
|
5
4
|
async function request(url: string, options?: APIParams) {
|
|
6
5
|
if (!url.startsWith("/")) url = `${apiUrl}/${url}`
|
|
7
6
|
const { json, headers } = await makeRequest(url, options)
|
package/src/hooks/index.ts
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useResourceContext } from "react-admin"
|
|
2
|
+
import { useMuffinAdminOpts } from "./useMuffinAdminOpts"
|
|
3
|
+
|
|
4
|
+
export function useMuffinResourceOpts() {
|
|
5
|
+
const resource = useResourceContext()
|
|
6
|
+
const { resources } = useMuffinAdminOpts()
|
|
7
|
+
return resources.find((r) => r.name === resource)
|
|
8
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { createRoot } from "react-dom/client"
|
|
2
|
-
import {
|
|
2
|
+
import { MuffinAdmin } from "./MuffinAdmin"
|
|
3
|
+
import { MuffinAdminContext } from "./context"
|
|
4
|
+
|
|
5
|
+
export * from "./utils"
|
|
3
6
|
|
|
4
7
|
export * from "./MuffinAdmin"
|
|
5
8
|
export * from "./MuffinDashboard"
|
|
@@ -12,17 +15,21 @@ export * from "./actions"
|
|
|
12
15
|
export * from "./authprovider"
|
|
13
16
|
export * from "./buildRA"
|
|
14
17
|
export * from "./buttons"
|
|
18
|
+
export * from "./context"
|
|
15
19
|
export * from "./dataprovider"
|
|
16
20
|
export * from "./fields"
|
|
17
21
|
export * from "./hooks"
|
|
18
22
|
export * from "./types"
|
|
19
|
-
export * from "./utils"
|
|
20
23
|
|
|
21
24
|
export async function initAdmin(prefix = "", containerId: string = "root") {
|
|
22
25
|
const response = await fetch(`${prefix}/ra.json`)
|
|
23
|
-
const
|
|
26
|
+
const adminOpts = await response.json()
|
|
24
27
|
const container = document.getElementById(containerId)
|
|
25
28
|
if (!container) throw new Error(`Container #${containerId} not found`)
|
|
26
29
|
const root = createRoot(container)
|
|
27
|
-
root.render(
|
|
30
|
+
root.render(
|
|
31
|
+
<MuffinAdminContext.Provider value={adminOpts}>
|
|
32
|
+
<MuffinAdmin />
|
|
33
|
+
</MuffinAdminContext.Provider>
|
|
34
|
+
)
|
|
28
35
|
}
|
package/src/utils.tsx
CHANGED
|
@@ -1,36 +1,33 @@
|
|
|
1
1
|
import * as icons from "@mui/icons-material"
|
|
2
2
|
import { stringify } from "query-string"
|
|
3
3
|
import { fetchUtils } from "ra-core"
|
|
4
|
-
import { createContext } from "react"
|
|
5
|
-
import { AdminOpts } from "./types"
|
|
6
4
|
|
|
7
5
|
const builders = new Map<string, (props) => any>()
|
|
8
6
|
|
|
9
|
-
export function setupAdmin<T>(adminType: string[], fc: (
|
|
7
|
+
export function setupAdmin<T>(adminType: string[], fc: (props) => T) {
|
|
10
8
|
const key = adminType.join("/")
|
|
11
9
|
builders.set(key, fc)
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
export function buildAdmin(adminType: string[], props = {}) {
|
|
15
|
-
if (process.env.NODE_ENV == "development") console.log(adminType, props)
|
|
16
13
|
const builder = findBuilder(adminType)
|
|
14
|
+
if (process.env.NODE_ENV == "development") console.log(props)
|
|
17
15
|
if (builder) return builder(props)
|
|
18
16
|
|
|
19
17
|
console.warn(`No admin renderer found for ${adminType.join("/")}`)
|
|
20
18
|
return null
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
export function findBuilder(adminType: string[]) {
|
|
21
|
+
export function findBuilder(adminType: string[]): (props) => any {
|
|
22
|
+
if (process.env.NODE_ENV == "development") console.log(adminType)
|
|
24
23
|
const key = [...adminType]
|
|
25
24
|
while (key.length) {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
25
|
+
const builder = builders.get(key.join("/"))
|
|
26
|
+
if (builder) return builder
|
|
28
27
|
key.pop()
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
export const AdminPropsContext = createContext<AdminOpts | null>(null)
|
|
33
|
-
|
|
34
31
|
export type APIParams = {
|
|
35
32
|
method?: string
|
|
36
33
|
query?: {
|