muffin-admin 1.29.0 → 1.30.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/.babelrc +5 -0
- package/.eslintrc.json +44 -0
- package/admin.jsx +50 -46
- package/authprovider.js +53 -48
- package/buttons/ActionButton.jsx +76 -45
- package/buttons/LinkButton.jsx +12 -12
- package/dashboard.jsx +46 -29
- package/dataprovider.js +62 -49
- package/fields/AvatarField.jsx +28 -19
- package/fields/FKField.jsx +16 -12
- package/fields/JsonField.jsx +25 -0
- package/hooks/useAction.js +9 -0
- package/index.js +7 -4
- package/inputs/FKInput.jsx +29 -17
- package/inputs/JsonInput.jsx +62 -0
- package/jsconfig.json +9 -0
- package/package.json +10 -7
- package/resources.jsx +25 -15
- package/ui.jsx +89 -33
- package/utils.js +23 -19
- package/views/create.jsx +22 -18
- package/views/edit.jsx +34 -26
- package/views/list.jsx +62 -32
- package/views/show.jsx +35 -26
- package/webpack.config.js +1 -0
package/dataprovider.js
CHANGED
|
@@ -1,81 +1,94 @@
|
|
|
1
|
-
import { makeRequest } from './utils'
|
|
2
|
-
|
|
1
|
+
import { makeRequest } from './utils'
|
|
3
2
|
|
|
4
3
|
export default (apiUrl) => {
|
|
5
|
-
|
|
6
4
|
const methods = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (filter) query.where = JSON.stringify(filter);
|
|
5
|
+
getList: async (resource, { filter, pagination, sort }) => {
|
|
6
|
+
const query = {}
|
|
7
|
+
if (filter) query.where = JSON.stringify(filter)
|
|
11
8
|
if (pagination) {
|
|
12
|
-
const {page, perPage: limit} = pagination
|
|
13
|
-
query.limit = limit
|
|
14
|
-
query.offset = limit * (page - 1)
|
|
9
|
+
const { page, perPage: limit } = pagination
|
|
10
|
+
query.limit = limit
|
|
11
|
+
query.offset = limit * (page - 1)
|
|
15
12
|
}
|
|
16
13
|
if (sort) {
|
|
17
|
-
const {field, order} = sort
|
|
18
|
-
query.sort = order == 'ASC' ? field : `-${field}
|
|
19
|
-
}
|
|
14
|
+
const { field, order } = sort
|
|
15
|
+
query.sort = order == 'ASC' ? field : `-${field}`
|
|
16
|
+
}
|
|
20
17
|
|
|
21
|
-
const {headers, json} = await makeRequest(`${apiUrl}/${resource}`, {
|
|
18
|
+
const { headers, json } = await makeRequest(`${apiUrl}/${resource}`, {
|
|
19
|
+
query,
|
|
20
|
+
})
|
|
22
21
|
return {
|
|
23
22
|
data: json,
|
|
24
23
|
total: parseInt(headers.get('x-total'), 10),
|
|
25
|
-
}
|
|
26
|
-
|
|
24
|
+
}
|
|
27
25
|
},
|
|
28
26
|
|
|
29
|
-
getOne: async (resource, {id}) => {
|
|
30
|
-
const {json} = await makeRequest(`${apiUrl}/${resource}/${id}`)
|
|
31
|
-
return {data: json}
|
|
27
|
+
getOne: async (resource, { id }) => {
|
|
28
|
+
const { json } = await makeRequest(`${apiUrl}/${resource}/${id}`)
|
|
29
|
+
return { data: json }
|
|
32
30
|
},
|
|
33
31
|
|
|
34
|
-
create: async (resource, {data}) => {
|
|
35
|
-
const {json} = await makeRequest(`${apiUrl}/${resource}`, {
|
|
36
|
-
|
|
32
|
+
create: async (resource, { data }) => {
|
|
33
|
+
const { json } = await makeRequest(`${apiUrl}/${resource}`, {
|
|
34
|
+
data,
|
|
35
|
+
method: 'POST',
|
|
36
|
+
})
|
|
37
|
+
return { data: json }
|
|
37
38
|
},
|
|
38
39
|
|
|
39
|
-
update: async (resource, {id, data}) => {
|
|
40
|
-
const {json} = await makeRequest(`${apiUrl}/${resource}/${id}`, {
|
|
41
|
-
|
|
40
|
+
update: async (resource, { id, data }) => {
|
|
41
|
+
const { json } = await makeRequest(`${apiUrl}/${resource}/${id}`, {
|
|
42
|
+
data,
|
|
43
|
+
method: 'PUT',
|
|
44
|
+
})
|
|
45
|
+
return { data: json }
|
|
42
46
|
},
|
|
43
47
|
|
|
44
|
-
updateMany: async (resource, {ids, data}) => {
|
|
45
|
-
await Promise.all(ids.map(id => methods.update(resource, {id, data})))
|
|
46
|
-
return {data: ids}
|
|
48
|
+
updateMany: async (resource, { ids, data }) => {
|
|
49
|
+
await Promise.all(ids.map((id) => methods.update(resource, { id, data })))
|
|
50
|
+
return { data: ids }
|
|
47
51
|
},
|
|
48
52
|
|
|
49
|
-
delete: async (resource, {id}) => {
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
delete: async (resource, { id }) => {
|
|
54
|
+
await makeRequest(`${apiUrl}/${resource}/${id}`, {
|
|
55
|
+
method: 'DELETE',
|
|
56
|
+
})
|
|
57
|
+
return { data: { id } }
|
|
52
58
|
},
|
|
53
59
|
|
|
54
|
-
deleteMany: async (resource, {ids}) => {
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
deleteMany: async (resource, { ids }) => {
|
|
61
|
+
await makeRequest(`${apiUrl}/${resource}`, {
|
|
62
|
+
data: ids,
|
|
63
|
+
method: 'DELETE',
|
|
64
|
+
})
|
|
65
|
+
return { data: ids }
|
|
57
66
|
},
|
|
58
67
|
|
|
59
|
-
getMany: (resource, {ids}) => {
|
|
60
|
-
return methods.getList(resource, {filter: {id: {
|
|
68
|
+
getMany: (resource, { ids }) => {
|
|
69
|
+
return methods.getList(resource, { filter: { id: { $in: ids } } })
|
|
61
70
|
},
|
|
62
71
|
|
|
63
|
-
getManyReference: async (resource, {target, id, filter, ...opts}) => {
|
|
64
|
-
filter = filter || {}
|
|
65
|
-
filter[target] = id
|
|
66
|
-
return await methods.getList(resource, {filter, ...opts})
|
|
72
|
+
getManyReference: async (resource, { target, id, filter, ...opts }) => {
|
|
73
|
+
filter = filter || {}
|
|
74
|
+
filter[target] = id
|
|
75
|
+
return await methods.getList(resource, { filter, ...opts })
|
|
67
76
|
},
|
|
68
77
|
|
|
69
|
-
runAction: async (resource, props) => {
|
|
70
|
-
|
|
78
|
+
runAction: async (resource, action, props) => {
|
|
79
|
+
const { payload, ids, record } = props
|
|
71
80
|
action = action.replace(/^\/+/, '')
|
|
72
|
-
if (record) {
|
|
73
|
-
|
|
74
|
-
|
|
81
|
+
if (record) {
|
|
82
|
+
action = action.replace(/\{([^}]+)\}/, (_, field) => record[field])
|
|
83
|
+
}
|
|
84
|
+
const { json } = await makeRequest(`${apiUrl}/${action}`, {
|
|
85
|
+
query: { ids },
|
|
86
|
+
method: 'POST',
|
|
87
|
+
data: payload,
|
|
88
|
+
})
|
|
89
|
+
return { data: json }
|
|
75
90
|
},
|
|
91
|
+
}
|
|
76
92
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return methods;
|
|
80
|
-
|
|
93
|
+
return methods
|
|
81
94
|
}
|
package/fields/AvatarField.jsx
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
|
-
import get from 'lodash/get'
|
|
4
|
-
import { useRecordContext } from 'ra-core'
|
|
5
|
-
import Avatar from '@material
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import get from 'lodash/get'
|
|
4
|
+
import { useRecordContext } from 'ra-core'
|
|
5
|
+
import Avatar from '@mui/material/Avatar'
|
|
6
|
+
|
|
7
|
+
const AvatarField = ({ source, alt, style, nameProp, ...props }) => {
|
|
8
|
+
const record = useRecordContext(props)
|
|
9
|
+
|
|
10
|
+
let value = get(record, source),
|
|
11
|
+
name = record[nameProp]
|
|
12
|
+
|
|
13
|
+
const letters = name
|
|
14
|
+
? name
|
|
15
|
+
.trim(' ')
|
|
16
|
+
.split(/\s+/)
|
|
17
|
+
.slice(0, 2)
|
|
18
|
+
.map((n) => n[0].toUpperCase())
|
|
19
|
+
.join('')
|
|
20
|
+
: ''
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Avatar src={value} alt={alt} style={style}>
|
|
24
|
+
{letters}
|
|
25
|
+
</Avatar>
|
|
26
|
+
)
|
|
18
27
|
}
|
|
19
28
|
|
|
20
|
-
AvatarField.displayName = 'AvatarField'
|
|
29
|
+
AvatarField.displayName = 'AvatarField'
|
|
21
30
|
AvatarField.defaultProps = {
|
|
22
31
|
addLabel: true,
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
export default AvatarField
|
|
34
|
+
export default AvatarField
|
package/fields/FKField.jsx
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import { ReferenceField, TextField } from 'react-admin'
|
|
4
4
|
|
|
5
|
-
const FKField = ({refSource, refID, link, ...props}) => {
|
|
5
|
+
const FKField = ({ refSource, refID, link, reference, source, ...props }) => {
|
|
6
6
|
return (
|
|
7
|
-
<ReferenceField
|
|
7
|
+
<ReferenceField
|
|
8
|
+
link={link || 'show'}
|
|
9
|
+
reference={reference}
|
|
10
|
+
source={source}
|
|
11
|
+
{...props}
|
|
12
|
+
>
|
|
8
13
|
<>
|
|
9
|
-
<TextField source={
|
|
10
|
-
{
|
|
11
|
-
<TextField source={
|
|
12
|
-
{
|
|
14
|
+
<TextField source={refSource} />
|
|
15
|
+
{' (#'}
|
|
16
|
+
<TextField source={refID || 'id'} />
|
|
17
|
+
{')'}
|
|
13
18
|
</>
|
|
14
19
|
</ReferenceField>
|
|
15
20
|
)
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
FKField.displayName = 'FKField'
|
|
23
|
+
FKField.displayName = 'FKField'
|
|
19
24
|
FKField.defaultProps = {
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default FKField;
|
|
25
|
+
addLabel: true,
|
|
26
|
+
}
|
|
24
27
|
|
|
28
|
+
export default FKField
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import get from 'lodash/get'
|
|
2
|
+
import React, { useState } from 'react'
|
|
3
|
+
import { Button, FunctionField, useRecordContext } from 'react-admin'
|
|
4
|
+
|
|
5
|
+
export default function JsonField({ label, source }) {
|
|
6
|
+
const [expand, setExpand] = useState(false)
|
|
7
|
+
const record = useRecordContext()
|
|
8
|
+
const src = JSON.stringify(get(record, source), null, 2)
|
|
9
|
+
const retval = (
|
|
10
|
+
<div>
|
|
11
|
+
<p></p>
|
|
12
|
+
{label}
|
|
13
|
+
<Button
|
|
14
|
+
variant='contained'
|
|
15
|
+
color='primary'
|
|
16
|
+
size='small'
|
|
17
|
+
label={expand ? 'colapse' : 'expand'}
|
|
18
|
+
onClick={() => setExpand(!expand)}
|
|
19
|
+
/>
|
|
20
|
+
<p>{expand && <pre>{src}</pre>}</p>
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
return <FunctionField render={() => retval} />
|
|
25
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useDataProvider } from 'react-admin'
|
|
2
|
+
import { useMutation } from 'react-query'
|
|
3
|
+
|
|
4
|
+
export default function useAction(resource, action) {
|
|
5
|
+
const dataProvider = useDataProvider()
|
|
6
|
+
return useMutation((params) =>
|
|
7
|
+
dataProvider.runAction(resource, action, params)
|
|
8
|
+
)
|
|
9
|
+
}
|
package/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRoot } from 'react-dom/client'
|
|
2
2
|
|
|
3
3
|
import { setupAdmin, processAdmin } from './utils.js'
|
|
4
4
|
|
|
5
|
-
import './admin.jsx'
|
|
5
|
+
import './admin.jsx'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const initAdmin = (globalThis.initAdmin = (props) => {
|
|
8
|
+
const container = document.getElementById('root')
|
|
9
|
+
const root = createRoot(container)
|
|
10
|
+
root.render(processAdmin('admin', props))
|
|
11
|
+
})
|
|
9
12
|
|
|
10
13
|
export { setupAdmin, processAdmin }
|
|
11
14
|
|
package/inputs/FKInput.jsx
CHANGED
|
@@ -1,30 +1,42 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
3
|
import { ReferenceInput, AutocompleteInput } from 'react-admin'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const FKInput = ({
|
|
6
|
+
refProp,
|
|
7
|
+
refSource,
|
|
8
|
+
fullWidth,
|
|
9
|
+
reference,
|
|
10
|
+
source,
|
|
11
|
+
...props
|
|
12
|
+
}) => {
|
|
13
|
+
let filterToQuery = (search) => {
|
|
14
|
+
let filters = {}
|
|
15
|
+
filters[refProp] = search
|
|
16
|
+
return filters
|
|
12
17
|
}
|
|
13
18
|
|
|
14
|
-
refSource = refSource || 'id'
|
|
19
|
+
refSource = refSource || 'id'
|
|
15
20
|
|
|
16
|
-
let renderText = record => {
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
let renderText = (record) => {
|
|
22
|
+
let pk = record[refSource]
|
|
23
|
+
return (pk && `${record[refProp]} (#${pk})`) || ''
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
return (
|
|
22
|
-
<ReferenceInput
|
|
23
|
-
|
|
27
|
+
<ReferenceInput
|
|
28
|
+
reference={reference}
|
|
29
|
+
source={source}
|
|
30
|
+
filterToQuery={filterToQuery}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
<AutocompleteInput
|
|
34
|
+
source={refSource}
|
|
35
|
+
optionText={renderText}
|
|
36
|
+
fullWidth={fullWidth}
|
|
37
|
+
/>
|
|
24
38
|
</ReferenceInput>
|
|
25
39
|
)
|
|
26
|
-
|
|
27
|
-
|
|
28
40
|
}
|
|
29
41
|
|
|
30
|
-
export default FKInput
|
|
42
|
+
export default FKInput
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { TextInput } from 'react-admin'
|
|
3
|
+
import isJSON from 'validator/lib/isJSON'
|
|
4
|
+
|
|
5
|
+
const DEFAULT_ERRORTEXT = 'Invalid JSON'
|
|
6
|
+
|
|
7
|
+
const parseFunction = (json) => {
|
|
8
|
+
let retval = json
|
|
9
|
+
try {
|
|
10
|
+
retval = JSON.parse(json)
|
|
11
|
+
} finally {
|
|
12
|
+
return retval
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* `JsonInput` validates if the entered value is JSON or not. If entered value is not a invalid JSON, `JsonInput` will throw an error.
|
|
19
|
+
* Default error message is: `Invalid JSON` and can be overridden using `errortext` prop.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* <JsonInput source='config' label='JSON Config' errortext='Enter a valid JSON'/>
|
|
23
|
+
*
|
|
24
|
+
* or use translate function:
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* <JsonInput source='config' label={translate('resources.resource_name.fields.config')} errortext={translate('myroot.validate.json')}/>
|
|
28
|
+
*
|
|
29
|
+
* By default, `JsonInput` parses and returns the entered string as object. Instead, to send string directly, please pass `parse` prop as `false`
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <JsonInput source='config' label='JSON Config' parse={false}/>
|
|
33
|
+
*/
|
|
34
|
+
export default function JsonInput(props) {
|
|
35
|
+
const {
|
|
36
|
+
validate = [],
|
|
37
|
+
errortext = DEFAULT_ERRORTEXT,
|
|
38
|
+
multiline = true,
|
|
39
|
+
parse = true,
|
|
40
|
+
...rest
|
|
41
|
+
} = props
|
|
42
|
+
// const errorobj = { message: errortext }
|
|
43
|
+
|
|
44
|
+
const validateJSON = (value) => {
|
|
45
|
+
if (!value || typeof value === 'object') return undefined
|
|
46
|
+
return isJSON(value) ? undefined : errortext
|
|
47
|
+
}
|
|
48
|
+
validate.push(validateJSON)
|
|
49
|
+
rest.validate = validate
|
|
50
|
+
|
|
51
|
+
const formatJSON = (json) => {
|
|
52
|
+
let retval = json
|
|
53
|
+
if (retval && typeof retval === 'object')
|
|
54
|
+
retval = JSON.stringify(retval, null, 2)
|
|
55
|
+
return retval
|
|
56
|
+
}
|
|
57
|
+
rest.format = formatJSON
|
|
58
|
+
//
|
|
59
|
+
if (parse) rest.parse = parseFunction
|
|
60
|
+
if (multiline) rest.multiline = true
|
|
61
|
+
return <TextInput {...rest} />
|
|
62
|
+
}
|
package/jsconfig.json
ADDED
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muffin-admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "NPM package for https://github.com/klen/muffin-admin",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
9
|
},
|
|
@@ -17,20 +18,22 @@
|
|
|
17
18
|
},
|
|
18
19
|
"homepage": "https://github.com/klen/muffin-admin#readme",
|
|
19
20
|
"dependencies": {
|
|
20
|
-
"@material
|
|
21
|
-
"@material
|
|
21
|
+
"@mui/icons-material": "^5.6.2",
|
|
22
|
+
"@mui/material": "^5.6.3",
|
|
22
23
|
"js-cookie": "^3.0.1",
|
|
23
|
-
"react": "
|
|
24
|
-
"react-admin": "
|
|
25
|
-
"react-
|
|
26
|
-
"
|
|
24
|
+
"react": "^18.1.0",
|
|
25
|
+
"react-admin": "^4.0.1",
|
|
26
|
+
"react-dom": "^18.1.0",
|
|
27
|
+
"validator": "^13.7.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@babel/core": "^7.17.8",
|
|
31
|
+
"@babel/eslint-parser": "^7.17.0",
|
|
30
32
|
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
31
33
|
"@babel/preset-env": "^7.16.11",
|
|
32
34
|
"@babel/preset-react": "^7.16.7",
|
|
33
35
|
"babel-loader": "^8.2.4",
|
|
36
|
+
"eslint-plugin-react": "^7.29.4",
|
|
34
37
|
"webpack": "^5.24.4",
|
|
35
38
|
"webpack-cli": "^4.9.1",
|
|
36
39
|
"webpack-dev-server": "^4.3.1"
|
package/resources.jsx
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
|
-
import { Resource } from
|
|
4
|
-
import * as icons from
|
|
3
|
+
import { Resource } from 'react-admin'
|
|
4
|
+
import * as icons from '@mui/icons-material'
|
|
5
5
|
|
|
6
|
-
import { checkParams, processAdmin,
|
|
6
|
+
import { checkParams, processAdmin, setupAdmin } from './utils'
|
|
7
7
|
|
|
8
8
|
import './views/list.jsx'
|
|
9
9
|
import './views/show.jsx'
|
|
10
10
|
import './views/edit.jsx'
|
|
11
11
|
import './views/create.jsx'
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
// Initialize Resources Components
|
|
15
|
-
setupAdmin('resources', resources =>
|
|
14
|
+
setupAdmin('resources', (resources) =>
|
|
15
|
+
resources.map((res) => processAdmin('resource', res, res.name))
|
|
16
|
+
)
|
|
16
17
|
|
|
17
18
|
// Initialize a resource's component
|
|
18
|
-
setupAdmin(
|
|
19
|
-
|
|
19
|
+
setupAdmin(
|
|
20
|
+
'resource',
|
|
21
|
+
checkParams((props, res) => {
|
|
22
|
+
let { create, edit, icon, list, name, show, ...resProps } = props
|
|
20
23
|
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
24
|
+
return (
|
|
25
|
+
<Resource
|
|
26
|
+
key={name}
|
|
27
|
+
name={name}
|
|
28
|
+
icon={icons[icon]}
|
|
29
|
+
create={processAdmin('create', create, res)}
|
|
30
|
+
edit={processAdmin('edit', edit, res)}
|
|
31
|
+
list={processAdmin('list', list, res)}
|
|
32
|
+
show={processAdmin('show', show, res)}
|
|
33
|
+
{...resProps}
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
})
|
|
37
|
+
)
|
package/ui.jsx
CHANGED
|
@@ -1,51 +1,107 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react'
|
|
2
2
|
|
|
3
|
-
import { required } from 'react-admin'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { required } from 'react-admin'
|
|
4
|
+
import {
|
|
5
|
+
BooleanField,
|
|
6
|
+
ChipField,
|
|
7
|
+
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
|
+
DateInput,
|
|
25
|
+
DateTimeInput,
|
|
26
|
+
ImageInput,
|
|
27
|
+
FileInput,
|
|
28
|
+
NumberInput,
|
|
29
|
+
PasswordInput,
|
|
30
|
+
TextInput,
|
|
31
|
+
AutocompleteInput,
|
|
32
|
+
RadioButtonGroupInput,
|
|
33
|
+
SelectInput,
|
|
34
|
+
ArrayInput,
|
|
35
|
+
AutocompleteArrayInput,
|
|
36
|
+
CheckboxGroupInput,
|
|
37
|
+
ReferenceArrayInput,
|
|
38
|
+
ReferenceInput,
|
|
39
|
+
} from 'react-admin'
|
|
7
40
|
|
|
8
|
-
import AvatarField from
|
|
9
|
-
import FKField from
|
|
10
|
-
import FKInput from
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// Fix JsonField
|
|
14
|
-
JsonField.displayName = 'JsonField';
|
|
15
|
-
JsonField.defaultProps = {
|
|
16
|
-
addLabel: true,
|
|
17
|
-
};
|
|
41
|
+
import AvatarField from './fields/AvatarField.jsx'
|
|
42
|
+
import FKField from './fields/FKField.jsx'
|
|
43
|
+
import FKInput from './inputs/FKInput.jsx'
|
|
44
|
+
import JsonField from './fields/JsonField.jsx'
|
|
45
|
+
import JsonInput from './inputs/JsonInput.jsx'
|
|
18
46
|
|
|
19
47
|
const ui = {
|
|
20
|
-
|
|
21
48
|
// Fields
|
|
22
|
-
BooleanField,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
49
|
+
BooleanField,
|
|
50
|
+
ChipField,
|
|
51
|
+
DateField,
|
|
52
|
+
EmailField,
|
|
53
|
+
ImageField,
|
|
54
|
+
FileField,
|
|
55
|
+
NumberField,
|
|
56
|
+
RichTextField,
|
|
57
|
+
TextField,
|
|
58
|
+
UrlField,
|
|
59
|
+
SelectField,
|
|
60
|
+
ArrayField,
|
|
61
|
+
ReferenceField,
|
|
62
|
+
ReferenceManyField,
|
|
63
|
+
ReferenceArrayField,
|
|
64
|
+
AvatarField,
|
|
65
|
+
JsonField,
|
|
66
|
+
FKField,
|
|
26
67
|
|
|
27
68
|
// Inputs
|
|
28
|
-
BooleanInput,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
BooleanInput,
|
|
70
|
+
NullableBooleanInput,
|
|
71
|
+
DateInput,
|
|
72
|
+
DateTimeInput,
|
|
73
|
+
ImageInput,
|
|
74
|
+
FileInput,
|
|
75
|
+
NumberInput,
|
|
76
|
+
PasswordInput,
|
|
77
|
+
TextInput,
|
|
78
|
+
AutocompleteInput,
|
|
79
|
+
RadioButtonGroupInput,
|
|
80
|
+
SelectInput,
|
|
81
|
+
ArrayInput,
|
|
82
|
+
AutocompleteArrayInput,
|
|
83
|
+
CheckboxGroupInput,
|
|
84
|
+
ReferenceArrayInput,
|
|
85
|
+
ReferenceInput,
|
|
86
|
+
JsonInput,
|
|
87
|
+
FKInput,
|
|
33
88
|
}
|
|
34
89
|
|
|
35
|
-
const initRAItems = itemsProps
|
|
90
|
+
const initRAItems = (itemsProps) =>
|
|
91
|
+
itemsProps.map((item) => {
|
|
36
92
|
const Item = ui[item[0]],
|
|
37
|
-
|
|
93
|
+
props = { ...item[1] }
|
|
38
94
|
|
|
39
95
|
if (props.required) {
|
|
40
|
-
|
|
41
|
-
|
|
96
|
+
props.validate = required()
|
|
97
|
+
delete props.required
|
|
42
98
|
}
|
|
43
99
|
|
|
44
100
|
props.fullWidth = props.fullWidth ?? true
|
|
45
101
|
|
|
46
|
-
if (props.children) props.children = initRAItems(props.children)[0]
|
|
47
|
-
|
|
48
|
-
return <Item key={
|
|
49
|
-
})
|
|
102
|
+
if (props.children) props.children = initRAItems(props.children)[0]
|
|
103
|
+
|
|
104
|
+
return <Item key={props.source} {...props} />
|
|
105
|
+
})
|
|
50
106
|
|
|
51
107
|
export default initRAItems
|