muffin-admin 9.5.3 → 10.0.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/MuffinDashboard.js +3 -3
- package/dist/MuffinResourceEdit.js +2 -2
- package/dist/MuffinResourceList.js +2 -2
- package/dist/MuffinResourceShow.js +2 -2
- package/dist/dataprovider.d.ts +7 -2
- package/dist/dataprovider.js +19 -5
- package/dist/fields/FKField.js +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/inputs/FKInput.js +3 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/utils.d.ts +1 -1
- package/package.json +9 -9
- package/src/MuffinDashboard.tsx +12 -14
- package/src/MuffinResourceEdit.tsx +2 -2
- package/src/MuffinResourceList.tsx +9 -2
- package/src/MuffinResourceShow.tsx +2 -2
- package/src/dataprovider.ts +22 -5
- package/src/fields/FKField.tsx +8 -3
- package/src/index.tsx +1 -1
- package/src/inputs/FKInput.tsx +7 -1
- package/src/types.ts +1 -0
- package/src/utils.tsx +1 -1
package/dist/types.d.ts
CHANGED
package/dist/utils.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muffin-admin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.1",
|
|
4
4
|
"description": "NPM package for https://github.com/klen/muffin-admin",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"date-fns": "^4.1.0",
|
|
27
27
|
"js-cookie": "^3.0.5",
|
|
28
|
-
"ra-language-russian": "^4.
|
|
29
|
-
"react": "^
|
|
30
|
-
"react-admin": "^5.
|
|
28
|
+
"ra-language-russian": "^5.4.4",
|
|
29
|
+
"react": "^19.1.1",
|
|
30
|
+
"react-admin": "^5.10.0",
|
|
31
31
|
"react-datepicker": "^8.1.0",
|
|
32
|
-
"react-dom": "^
|
|
32
|
+
"react-dom": "^19.1.1",
|
|
33
33
|
"validator": "^13.12.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/lodash": "^4.17.
|
|
37
|
-
"@types/node": "
|
|
38
|
-
"@types/react": "
|
|
39
|
-
"@types/react-dom": "
|
|
36
|
+
"@types/lodash": "^4.17.20",
|
|
37
|
+
"@types/node": "24.1.0",
|
|
38
|
+
"@types/react": "19.1.9",
|
|
39
|
+
"@types/react-dom": "19.1.7",
|
|
40
40
|
"@types/react-window": "^1.8.8",
|
|
41
41
|
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
42
42
|
"@typescript-eslint/parser": "^7.12.0",
|
package/src/MuffinDashboard.tsx
CHANGED
|
@@ -43,7 +43,7 @@ setupAdmin(["dashboard-content"], () => null)
|
|
|
43
43
|
function AdminCards({ src }: { src: AdminDashboardBlock | AdminDashboardBlock[] }) {
|
|
44
44
|
if (Array.isArray(src))
|
|
45
45
|
return (
|
|
46
|
-
<Grid container
|
|
46
|
+
<Grid container spacing={2}>
|
|
47
47
|
{src.map((card, idx) => (
|
|
48
48
|
<AdminCards key={idx} src={card} />
|
|
49
49
|
))}
|
|
@@ -55,23 +55,21 @@ function AdminCards({ src }: { src: AdminDashboardBlock | AdminDashboardBlock[]
|
|
|
55
55
|
|
|
56
56
|
function DashboardCard({ title, value }: AdminDashboardBlock) {
|
|
57
57
|
return (
|
|
58
|
-
<
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
</Card>
|
|
69
|
-
</Grid>
|
|
58
|
+
<Card>
|
|
59
|
+
<CardContent>
|
|
60
|
+
<Typography variant="h5" component="h2" m={2} style={{ textAlign: "center" }}>
|
|
61
|
+
{title}
|
|
62
|
+
</Typography>
|
|
63
|
+
{(Array.isArray(value) && <AdminTableView src={value} />) || (
|
|
64
|
+
<pre>{JSON.stringify(value, null, 2)}</pre>
|
|
65
|
+
)}
|
|
66
|
+
</CardContent>
|
|
67
|
+
</Card>
|
|
70
68
|
)
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
const AdminTableView = ({ src }) => (
|
|
74
|
-
<Table>
|
|
72
|
+
<Table width="100%" sx={{ tableLayout: "fixed" }}>
|
|
75
73
|
<TableBody>
|
|
76
74
|
{src.map((row: any, idx: number) => (
|
|
77
75
|
<TableRow key={idx} hover>
|
|
@@ -20,7 +20,7 @@ export function MuffinEdit({ children }: PropsWithChildren) {
|
|
|
20
20
|
adminProps: { mutationMode = "optimistic" },
|
|
21
21
|
} = useMuffinAdminOpts()
|
|
22
22
|
|
|
23
|
-
const { edit, name } = useMuffinResourceOpts()
|
|
23
|
+
const { edit, name, pk } = useMuffinResourceOpts()
|
|
24
24
|
if (!edit) return null
|
|
25
25
|
|
|
26
26
|
const Actions = findBuilder(["edit-toolbar", name])
|
|
@@ -28,7 +28,7 @@ export function MuffinEdit({ children }: PropsWithChildren) {
|
|
|
28
28
|
const FormToolbar = findBuilder(["edit-form-toolbar", name])
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
|
-
<Edit actions={<Actions />} mutationMode={mutationMode}>
|
|
31
|
+
<Edit actions={<Actions />} mutationMode={mutationMode} queryOptions={{ meta: { key: pk } }}>
|
|
32
32
|
{children}
|
|
33
33
|
<SimpleForm toolbar={<FormToolbar />}>
|
|
34
34
|
<Inputs />
|
|
@@ -23,7 +23,7 @@ import { AdminInput } from "./types"
|
|
|
23
23
|
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
24
24
|
|
|
25
25
|
export function MuffinList({ children }: PropsWithChildren) {
|
|
26
|
-
const { name, list } = useMuffinResourceOpts()
|
|
26
|
+
const { name, list, pk } = useMuffinResourceOpts()
|
|
27
27
|
const { limit, limitMax, limitTotal, sort, filters } = list
|
|
28
28
|
|
|
29
29
|
const DataGrid = findBuilder(["list-grid", name])
|
|
@@ -36,6 +36,7 @@ export function MuffinList({ children }: PropsWithChildren) {
|
|
|
36
36
|
perPage={limit}
|
|
37
37
|
filters={raFilters}
|
|
38
38
|
actions={<Toolbar />}
|
|
39
|
+
queryOptions={{ meta: { key: pk } }}
|
|
39
40
|
pagination={
|
|
40
41
|
<Pagination rowsPerPageOptions={sortBy(uniq([10, 25, 50, 100, limit, limitMax]))} />
|
|
41
42
|
}
|
|
@@ -44,7 +45,13 @@ export function MuffinList({ children }: PropsWithChildren) {
|
|
|
44
45
|
<DataGrid />
|
|
45
46
|
</List>
|
|
46
47
|
) : (
|
|
47
|
-
<InfiniteList
|
|
48
|
+
<InfiniteList
|
|
49
|
+
sort={sort}
|
|
50
|
+
perPage={limit}
|
|
51
|
+
filters={raFilters}
|
|
52
|
+
actions={<Toolbar />}
|
|
53
|
+
queryOptions={{ meta: { key: pk } }}
|
|
54
|
+
>
|
|
48
55
|
{children}
|
|
49
56
|
<DataGrid />
|
|
50
57
|
</InfiniteList>
|
|
@@ -7,11 +7,11 @@ import { useMuffinResourceOpts } from "./hooks"
|
|
|
7
7
|
import { buildAdmin, findBuilder, setupAdmin } from "./utils"
|
|
8
8
|
|
|
9
9
|
export function MuffinShow({ children }: PropsWithChildren) {
|
|
10
|
-
const { show, name } = useMuffinResourceOpts()
|
|
10
|
+
const { show, name, pk } = useMuffinResourceOpts()
|
|
11
11
|
const ShowToolbar = findBuilder(["show-toolbar", name])
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
|
-
<Show actions={<ShowToolbar />}>
|
|
14
|
+
<Show actions={<ShowToolbar />} queryOptions={{ meta: { key: pk } }}>
|
|
15
15
|
<SimpleShowLayout>{buildAdmin(["show-fields", name], show)}</SimpleShowLayout>
|
|
16
16
|
{children}
|
|
17
17
|
</Show>
|
package/src/dataprovider.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { TID } from "./types"
|
|
2
2
|
import { APIParams, makeRequest, prepareFilters, setupAdmin } from "./utils"
|
|
3
3
|
|
|
4
|
+
type TQueryMeta = {
|
|
5
|
+
key?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
4
8
|
export function MuffinDataprovider(apiUrl: string) {
|
|
5
9
|
async function request(url: string, options?: APIParams) {
|
|
6
10
|
if (!url.startsWith("/")) url = `${apiUrl}/${url}`
|
|
@@ -10,7 +14,7 @@ export function MuffinDataprovider(apiUrl: string) {
|
|
|
10
14
|
|
|
11
15
|
const methods = {
|
|
12
16
|
request,
|
|
13
|
-
getList: async (resource: string, params: any) => {
|
|
17
|
+
getList: async (resource: string, { meta, ...params }: any) => {
|
|
14
18
|
const { filter, pagination, sort } = params
|
|
15
19
|
const query: APIParams["query"] = {}
|
|
16
20
|
if (filter) query.where = prepareFilters(filter)
|
|
@@ -24,6 +28,14 @@ export function MuffinDataprovider(apiUrl: string) {
|
|
|
24
28
|
query.sort = order == "ASC" ? field : `-${field}`
|
|
25
29
|
}
|
|
26
30
|
const { headers, data } = await request(resource, { query })
|
|
31
|
+
|
|
32
|
+
// React-admin requires item to have an `id` field
|
|
33
|
+
if (meta?.key) {
|
|
34
|
+
for (const item of data) {
|
|
35
|
+
item.id = item.id ?? item[meta.key]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
if (pagination)
|
|
28
40
|
return {
|
|
29
41
|
data,
|
|
@@ -37,8 +49,13 @@ export function MuffinDataprovider(apiUrl: string) {
|
|
|
37
49
|
return { data }
|
|
38
50
|
},
|
|
39
51
|
|
|
40
|
-
getOne: async (resource: string, { id }: { id: TID }) => {
|
|
41
|
-
|
|
52
|
+
getOne: async (resource: string, { id, meta }: { id: TID; meta?: TQueryMeta }) => {
|
|
53
|
+
const response = await request(`${resource}/${id}`)
|
|
54
|
+
const { data } = response
|
|
55
|
+
if (meta?.key) {
|
|
56
|
+
data.id = data.id ?? data[meta.key]
|
|
57
|
+
}
|
|
58
|
+
return response
|
|
42
59
|
},
|
|
43
60
|
|
|
44
61
|
create: async (resource: string, { data }) => {
|
|
@@ -76,7 +93,7 @@ export function MuffinDataprovider(apiUrl: string) {
|
|
|
76
93
|
getMany: (resource: string, props: { ids: TID[]; meta: any }) => {
|
|
77
94
|
const { ids, meta } = props
|
|
78
95
|
const key = meta?.key || "id"
|
|
79
|
-
return methods.getList(resource, { filter: { [key]: { $in: ids } } })
|
|
96
|
+
return methods.getList(resource, { filter: { [key]: { $in: ids } }, meta })
|
|
80
97
|
},
|
|
81
98
|
|
|
82
99
|
getManyReference: async (resource: string, { target, id, filter, ...opts }) => {
|
|
@@ -92,7 +109,7 @@ export function MuffinDataprovider(apiUrl: string) {
|
|
|
92
109
|
action = action.replace(/\{([^}]+)\}/, (_, field) => record[field])
|
|
93
110
|
}
|
|
94
111
|
const { json } = await makeRequest(`${apiUrl}/${action}`, {
|
|
95
|
-
query: { ids },
|
|
112
|
+
query: { pks: ids },
|
|
96
113
|
method: "POST",
|
|
97
114
|
data: payload,
|
|
98
115
|
})
|
package/src/fields/FKField.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReferenceField, TextField } from "react-admin"
|
|
2
2
|
|
|
3
3
|
export function FKField({ reference, refSource, refKey, link, source, ...props }) {
|
|
4
|
+
refKey = refKey || "id"
|
|
4
5
|
return (
|
|
5
6
|
<ReferenceField
|
|
6
7
|
source={source}
|
|
@@ -11,9 +12,13 @@ export function FKField({ reference, refSource, refKey, link, source, ...props }
|
|
|
11
12
|
>
|
|
12
13
|
<>
|
|
13
14
|
<TextField source={refSource} />
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
{refSource !== refKey && (
|
|
16
|
+
<>
|
|
17
|
+
{" (#"}
|
|
18
|
+
<TextField source={refKey} />
|
|
19
|
+
{")"}
|
|
20
|
+
</>
|
|
21
|
+
)}
|
|
17
22
|
</>
|
|
18
23
|
</ReferenceField>
|
|
19
24
|
)
|
package/src/index.tsx
CHANGED
package/src/inputs/FKInput.tsx
CHANGED
|
@@ -16,7 +16,13 @@ export function FKInput({ refKey, refSource, fullWidth, reference, source, ...pr
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
|
-
<ReferenceInput
|
|
19
|
+
<ReferenceInput
|
|
20
|
+
reference={reference}
|
|
21
|
+
source={source}
|
|
22
|
+
queryOptions={{
|
|
23
|
+
meta: { key: refKey },
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
20
26
|
<AutocompleteInput
|
|
21
27
|
source={refKey}
|
|
22
28
|
optionText={renderText}
|
package/src/types.ts
CHANGED