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.
Files changed (142) hide show
  1. package/dist/MuffinAdmin.d.ts +2 -0
  2. package/dist/MuffinAdmin.js +25 -0
  3. package/dist/MuffinDashboard.d.ts +2 -0
  4. package/dist/MuffinDashboard.js +16 -0
  5. package/dist/MuffinResource.d.ts +2 -0
  6. package/dist/MuffinResource.js +19 -0
  7. package/dist/MuffinResourceCreate.d.ts +4 -0
  8. package/dist/MuffinResourceCreate.js +11 -0
  9. package/dist/MuffinResourceEdit.d.ts +2 -0
  10. package/dist/MuffinResourceEdit.js +26 -0
  11. package/dist/MuffinResourceList.d.ts +2 -0
  12. package/dist/MuffinResourceList.js +16 -0
  13. package/dist/MuffinResourceShow.d.ts +2 -0
  14. package/dist/MuffinResourceShow.js +13 -0
  15. package/dist/actions/LinkAction.d.ts +4 -0
  16. package/dist/actions/LinkAction.js +10 -0
  17. package/dist/actions/index.d.ts +1 -0
  18. package/dist/actions/index.js +1 -0
  19. package/dist/authprovider.d.ts +9 -0
  20. package/dist/authprovider.js +80 -0
  21. package/dist/buildRA.d.ts +2 -0
  22. package/dist/buildRA.js +63 -0
  23. package/dist/buttons/ActionButton.d.ts +7 -0
  24. package/dist/buttons/ActionButton.js +51 -0
  25. package/dist/buttons/LinkButton.d.ts +6 -0
  26. package/dist/buttons/LinkButton.js +12 -0
  27. package/dist/buttons/index.d.ts +2 -0
  28. package/dist/buttons/index.js +2 -0
  29. package/dist/dataprovider.d.ts +59 -0
  30. package/dist/dataprovider.js +106 -0
  31. package/dist/fields/AvatarField.d.ts +13 -0
  32. package/dist/fields/AvatarField.js +33 -0
  33. package/dist/fields/EditableBooleanField.d.ts +3 -0
  34. package/dist/fields/EditableBooleanField.js +5 -0
  35. package/dist/fields/FKField.d.ts +14 -0
  36. package/dist/fields/FKField.js +21 -0
  37. package/dist/fields/JsonField.d.ts +4 -0
  38. package/dist/fields/JsonField.js +11 -0
  39. package/dist/fields/index.d.ts +4 -0
  40. package/dist/fields/index.js +4 -0
  41. package/dist/hooks/useAction.d.ts +5 -0
  42. package/dist/hooks/useAction.js +6 -0
  43. package/dist/index.d.ts +14 -0
  44. package/dist/index.js +35 -0
  45. package/dist/inputs/FKInput.d.ts +8 -0
  46. package/dist/inputs/FKInput.js +27 -0
  47. package/dist/inputs/JsonInput.d.ts +19 -0
  48. package/dist/inputs/JsonInput.js +69 -0
  49. package/dist/inputs/index.d.ts +2 -0
  50. package/dist/inputs/index.js +2 -0
  51. package/dist/tsconfig.tsbuildinfo +1 -0
  52. package/dist/types.d.ts +76 -0
  53. package/dist/types.js +1 -0
  54. package/dist/utils.d.ts +28 -0
  55. package/dist/utils.js +57 -0
  56. package/dist/web.d.ts +1 -0
  57. package/dist/web.js +3 -0
  58. package/package.json +31 -14
  59. package/src/MuffinAdmin.tsx +73 -0
  60. package/src/MuffinDashboard.tsx +52 -0
  61. package/src/MuffinResource.tsx +27 -0
  62. package/src/MuffinResourceCreate.tsx +24 -0
  63. package/src/MuffinResourceEdit.tsx +42 -0
  64. package/src/MuffinResourceList.tsx +46 -0
  65. package/src/MuffinResourceShow.tsx +39 -0
  66. package/src/actions/LinkAction.tsx +10 -0
  67. package/src/actions/index.ts +1 -0
  68. package/src/{authprovider.js → authprovider.ts} +27 -22
  69. package/src/{ui.jsx → buildRA.tsx} +30 -35
  70. package/src/buttons/{ActionButton.jsx → ActionButton.tsx} +18 -30
  71. package/src/buttons/{LinkButton.jsx → LinkButton.tsx} +11 -6
  72. package/src/buttons/index.ts +2 -0
  73. package/src/{dataprovider.js → dataprovider.ts} +8 -6
  74. package/src/fields/{AvatarField.jsx → AvatarField.tsx} +3 -7
  75. package/src/fields/EditableBooleanField.tsx +5 -0
  76. package/src/fields/{FKField.jsx → FKField.tsx} +2 -10
  77. package/src/fields/{JsonField.jsx → JsonField.tsx} +2 -3
  78. package/src/fields/index.ts +4 -0
  79. package/src/hooks/{useAction.js → useAction.ts} +2 -2
  80. package/src/index.tsx +25 -0
  81. package/src/inputs/FKInput.tsx +27 -0
  82. package/src/inputs/{JsonInput.jsx → JsonInput.tsx} +3 -4
  83. package/src/inputs/index.ts +2 -0
  84. package/src/types.ts +73 -0
  85. package/src/utils.tsx +69 -0
  86. package/src/web.ts +4 -0
  87. package/dist/cjs/admin.js +0 -80
  88. package/dist/cjs/authprovider.js +0 -214
  89. package/dist/cjs/buttons/ActionButton.js +0 -96
  90. package/dist/cjs/buttons/LinkButton.js +0 -34
  91. package/dist/cjs/dashboard.js +0 -63
  92. package/dist/cjs/dataprovider.js +0 -304
  93. package/dist/cjs/fields/AvatarField.js +0 -37
  94. package/dist/cjs/fields/EditableBooleanField.js +0 -25
  95. package/dist/cjs/fields/FKField.js +0 -35
  96. package/dist/cjs/fields/JsonField.js +0 -38
  97. package/dist/cjs/hooks/useAction.js +0 -14
  98. package/dist/cjs/index.js +0 -76
  99. package/dist/cjs/inputs/FKInput.js +0 -41
  100. package/dist/cjs/inputs/JsonInput.js +0 -70
  101. package/dist/cjs/resources.js +0 -52
  102. package/dist/cjs/ui.js +0 -76
  103. package/dist/cjs/utils.js +0 -49
  104. package/dist/cjs/views/create.js +0 -18
  105. package/dist/cjs/views/edit.js +0 -31
  106. package/dist/cjs/views/list.js +0 -67
  107. package/dist/cjs/views/show.js +0 -37
  108. package/dist/cjs/web.js +0 -4
  109. package/dist/esm/admin.js +0 -74
  110. package/dist/esm/authprovider.js +0 -206
  111. package/dist/esm/buttons/ActionButton.js +0 -83
  112. package/dist/esm/buttons/LinkButton.js +0 -23
  113. package/dist/esm/dashboard.js +0 -60
  114. package/dist/esm/dataprovider.js +0 -296
  115. package/dist/esm/fields/AvatarField.js +0 -29
  116. package/dist/esm/fields/EditableBooleanField.js +0 -17
  117. package/dist/esm/fields/FKField.js +0 -27
  118. package/dist/esm/fields/JsonField.js +0 -28
  119. package/dist/esm/hooks/useAction.js +0 -8
  120. package/dist/esm/index.js +0 -42
  121. package/dist/esm/inputs/FKInput.js +0 -33
  122. package/dist/esm/inputs/JsonInput.js +0 -63
  123. package/dist/esm/resources.js +0 -47
  124. package/dist/esm/ui.js +0 -70
  125. package/dist/esm/utils.js +0 -38
  126. package/dist/esm/views/create.js +0 -16
  127. package/dist/esm/views/edit.js +0 -29
  128. package/dist/esm/views/list.js +0 -64
  129. package/dist/esm/views/show.js +0 -35
  130. package/dist/esm/web.js +0 -2
  131. package/src/admin.jsx +0 -78
  132. package/src/dashboard.jsx +0 -74
  133. package/src/fields/EditableBooleanField.jsx +0 -11
  134. package/src/index.js +0 -16
  135. package/src/inputs/FKInput.jsx +0 -42
  136. package/src/resources.jsx +0 -39
  137. package/src/utils.js +0 -38
  138. package/src/views/create.jsx +0 -30
  139. package/src/views/edit.jsx +0 -48
  140. package/src/views/list.jsx +0 -86
  141. package/src/views/show.jsx +0 -51
  142. 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
- ImageInput,
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
- SelectInput,
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/AvatarField"
42
- import FKField from "./fields/FKField"
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
- JsonField,
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 = initRAItems(props.children)[0]
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 default function initRAItems(items) {
106
- return items.map((item) => buildRAComponent(...item))
100
+ export function buildRA(items) {
101
+ return items.map((item) => buildRAComponent(item[0], item[1]))
107
102
  }
@@ -1,32 +1,27 @@
1
- import React from "react"
2
-
1
+ import * as icons from "@mui/icons-material"
3
2
  import {
4
3
  Button,
5
- useRefresh,
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 const BulkActionButton = ({
15
- label,
16
- icon,
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
- let onClick = () => {
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
- label={label}
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 const ActionButton = (props) => {
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
- let onClick = () => {
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: (error) => {
79
- notify(typeof error === "string" ? error : error.message, {
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 * as icons from "@mui/icons-material"
3
+ import { AdminShowLink } from "../types"
4
+ import { buildIcon } from "../utils"
5
5
 
6
- const LinkButton = ({ label, icon, title, resource, filters }) => {
7
- const Icon = icons[icon] || icon
8
- let linkParams = {
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
- {Icon && <Icon />}
20
+ {buildIcon(icon)}
16
21
  </Button>
17
22
  )
18
23
  }
@@ -0,0 +1,2 @@
1
+ export * from "./ActionButton"
2
+ export * from "./LinkButton"
@@ -1,9 +1,11 @@
1
- import { makeRequest } from "./utils"
1
+ import { AdminOpts } from "./types"
2
+ import { APIParams, makeRequest, setupAdmin } from "./utils"
2
3
 
3
- export default (apiUrl) => {
4
+ export function MuffinDataprovider({ apiUrl }: AdminOpts) {
4
5
  const methods = {
5
- getList: async (resource, { filter, pagination, sort }) => {
6
- const query = {}
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 React from "react"
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
- const AvatarField = ({ source, alt, style, nameProp, ...props }) => {
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
@@ -0,0 +1,5 @@
1
+ import { BooleanInput } from "ra-ui-materialui"
2
+
3
+ export function EditableBooleanField({ source }) {
4
+ return <BooleanInput source={source} />
5
+ }
@@ -1,14 +1,8 @@
1
- import React from "react"
2
1
  import { ReferenceField, TextField } from "react-admin"
3
2
 
4
- const FKField = ({ refSource, refID, link, reference, source, ...props }) => {
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 default function JsonField({ label, source }) {
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)
@@ -0,0 +1,4 @@
1
+ export * from "./AvatarField"
2
+ export * from "./EditableBooleanField"
3
+ export * from "./FKField"
4
+ export * from "./JsonField"
@@ -1,9 +1,9 @@
1
1
  import { useDataProvider } from "react-admin"
2
2
  import { useMutation } from "react-query"
3
3
 
4
- export default function useAction(resource, action) {
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 default function JsonInput(props) {
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
@@ -0,0 +1,2 @@
1
+ export * from "./FKInput"
2
+ export * from "./JsonInput"
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
@@ -0,0 +1,4 @@
1
+ import { initAdmin } from "."
2
+
3
+ // @ts-ignore
4
+ globalThis.initAdmin = initAdmin
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
- });