@applica-software-guru/react-admin 1.5.262 → 1.5.263
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/components/ra-forms/TableForm/AddTableRow.d.ts +4 -0
- package/dist/components/ra-forms/TableForm/AddTableRow.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/CreateButton.d.ts +12 -0
- package/dist/components/ra-forms/TableForm/CreateButton.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/EditButton.d.ts +3 -0
- package/dist/components/ra-forms/TableForm/EditButton.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/Field.d.ts +8 -0
- package/dist/components/ra-forms/TableForm/Field.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts +97 -5
- package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts.map +1 -1
- package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts +5 -2
- package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts.map +1 -1
- package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts +1 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts.map +1 -1
- package/dist/components/ra-forms/TableForm/index.d.ts +4 -0
- package/dist/components/ra-forms/TableForm/index.d.ts.map +1 -1
- package/dist/react-admin.cjs.js +52 -52
- package/dist/react-admin.cjs.js.gz +0 -0
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +7997 -8010
- package/dist/react-admin.es.js.gz +0 -0
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +51 -51
- package/dist/react-admin.umd.js.gz +0 -0
- package/dist/react-admin.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ra-forms/TableForm/AddTableRow.tsx +34 -0
- package/src/components/ra-forms/TableForm/CreateButton.tsx +58 -0
- package/src/components/ra-forms/TableForm/EditButton.tsx +42 -0
- package/src/components/ra-forms/TableForm/Field.tsx +23 -0
- package/src/components/ra-forms/TableForm/TableFormIterator.tsx +131 -62
- package/src/components/ra-forms/TableForm/TableFormIteratorItem.tsx +37 -7
- package/src/components/ra-forms/TableForm/TableFormIteratorItemContext.ts +1 -0
- package/src/components/ra-forms/TableForm/index.ts +4 -0
package/package.json
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PlusCircleOutlined } from '@ant-design/icons';
|
|
2
|
+
import { IconButton, Stack, Typography, useTheme } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
function AddTableRow(props: any): JSX.Element {
|
|
6
|
+
const { label, disableAdd, onClick, inset } = props;
|
|
7
|
+
const theme = useTheme();
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const tableBorderColor = theme.palette.mode === 'dark' ? theme.palette.grey.A400 : theme.palette.grey.A800;
|
|
10
|
+
const iconColor = theme.palette.mode === 'light' ? '#000000' : '#FFFFFF';
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Stack
|
|
14
|
+
justifyContent={'space-between'}
|
|
15
|
+
alignItems={'center'}
|
|
16
|
+
flexDirection={'row'}
|
|
17
|
+
sx={inset ? { p: 2.5 } : { pt: 2 }}
|
|
18
|
+
>
|
|
19
|
+
{label !== false && <Typography>{label}</Typography>}
|
|
20
|
+
{!disableAdd &&
|
|
21
|
+
(React.isValidElement(props?.customButton) ? (
|
|
22
|
+
React.cloneElement(props?.customButton, {
|
|
23
|
+
onClick: onClick
|
|
24
|
+
})
|
|
25
|
+
) : (
|
|
26
|
+
<IconButton color="secondary" sx={{ border: `1px solid ${tableBorderColor}` }} onClick={onClick}>
|
|
27
|
+
<PlusCircleOutlined style={{ color: iconColor }} />
|
|
28
|
+
</IconButton>
|
|
29
|
+
))}
|
|
30
|
+
</Stack>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { AddTableRow };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AddTableRow } from './AddTableRow';
|
|
2
|
+
import { Dialog } from '@mui/material';
|
|
3
|
+
import { CreateContextProvider, SaveHandler } from 'ra-core';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useArrayInput } from 'react-admin';
|
|
6
|
+
|
|
7
|
+
interface CreateButtonProps {
|
|
8
|
+
label: string;
|
|
9
|
+
disableAdd?: boolean;
|
|
10
|
+
inset?: boolean;
|
|
11
|
+
source?: string;
|
|
12
|
+
template?: any;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function CreateButton(props: CreateButtonProps): JSX.Element {
|
|
17
|
+
const { label, disableAdd, inset, source, template } = props;
|
|
18
|
+
const [open, setOpen] = React.useState(false);
|
|
19
|
+
const { append } = useArrayInput();
|
|
20
|
+
|
|
21
|
+
const toggleOpen = React.useCallback(() => {
|
|
22
|
+
setOpen((prev) => !prev);
|
|
23
|
+
}, [setOpen]);
|
|
24
|
+
|
|
25
|
+
const handleSave = React.useCallback(
|
|
26
|
+
(data: any) => {
|
|
27
|
+
setOpen(false);
|
|
28
|
+
append(data);
|
|
29
|
+
return Promise.resolve();
|
|
30
|
+
},
|
|
31
|
+
[setOpen, append]
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
{React.cloneElement(<AddTableRow />, {
|
|
37
|
+
label,
|
|
38
|
+
source,
|
|
39
|
+
disableAdd,
|
|
40
|
+
template,
|
|
41
|
+
onClick: toggleOpen,
|
|
42
|
+
inset
|
|
43
|
+
})}
|
|
44
|
+
<Dialog open={open} onClose={toggleOpen} maxWidth="xs">
|
|
45
|
+
<CreateContextProvider
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
value={{
|
|
48
|
+
save: handleSave as SaveHandler<any>
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{props.children}
|
|
52
|
+
</CreateContextProvider>
|
|
53
|
+
</Dialog>
|
|
54
|
+
</>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { CreateButton };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useTableFormIteratorItem } from './TableFormIteratorItemContext';
|
|
2
|
+
import { Button, Dialog } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { EditContextProvider, SaveHandler, useArrayInput, useTranslate } from 'react-admin';
|
|
5
|
+
|
|
6
|
+
function EditButton(props: any) {
|
|
7
|
+
const { children } = props;
|
|
8
|
+
const { item, index } = useTableFormIteratorItem();
|
|
9
|
+
const [open, setOpen] = React.useState(false);
|
|
10
|
+
const { update } = useArrayInput();
|
|
11
|
+
const translate = useTranslate();
|
|
12
|
+
|
|
13
|
+
const handleSave: SaveHandler<any> = React.useCallback(
|
|
14
|
+
(data) => {
|
|
15
|
+
setOpen(false);
|
|
16
|
+
update(index, data);
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
},
|
|
19
|
+
[index, update]
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
<Button color="primary" onClick={() => setOpen(true)} sx={{ justifyContent: 'flex-start' }}>
|
|
25
|
+
{translate('ra.action.edit')}
|
|
26
|
+
</Button>
|
|
27
|
+
<Dialog open={open} onClose={() => setOpen(false)} maxWidth="xs" fullWidth>
|
|
28
|
+
<EditContextProvider
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
value={{
|
|
31
|
+
record: item,
|
|
32
|
+
save: handleSave
|
|
33
|
+
}}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</EditContextProvider>
|
|
37
|
+
</Dialog>
|
|
38
|
+
</>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { EditButton };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { Children } from 'react';
|
|
2
|
+
import { useRecordContext } from 'react-admin';
|
|
3
|
+
import { useFormContext } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
interface FieldProps {
|
|
6
|
+
source: string;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ChildProps {
|
|
11
|
+
source: string;
|
|
12
|
+
record: Record<string, any>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function Field({ source, children }: FieldProps): JSX.Element | null {
|
|
16
|
+
const Child = Children.only(children) as React.ReactElement<ChildProps>;
|
|
17
|
+
const { getValues } = useFormContext();
|
|
18
|
+
const record = useRecordContext({ record: getValues() });
|
|
19
|
+
|
|
20
|
+
return React.isValidElement(Child) ? React.cloneElement(Child, { source, record }) : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { Field };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { Field } from './Field';
|
|
2
|
+
import { AddTableRow } from './AddTableRow';
|
|
3
|
+
import { CreateButton } from './CreateButton';
|
|
4
|
+
import { EditButton } from './EditButton';
|
|
1
5
|
import { ActionsMenu } from '@/components/ActionsMenu';
|
|
2
6
|
import { TableFormIteratorContext } from '@/components/ra-forms/TableForm/TableFormIteratorContext';
|
|
3
7
|
import { TableFormIteratorItem } from '@/components/ra-forms/TableForm/TableFormIteratorItem';
|
|
4
|
-
import { PlusCircleOutlined } from '@ant-design/icons';
|
|
5
8
|
import {
|
|
6
|
-
IconButton,
|
|
7
9
|
Paper,
|
|
8
|
-
Stack,
|
|
9
10
|
SxProps,
|
|
10
11
|
Table,
|
|
11
12
|
TableBody,
|
|
@@ -16,23 +17,24 @@ import {
|
|
|
16
17
|
Typography
|
|
17
18
|
} from '@mui/material';
|
|
18
19
|
import { styled, useTheme } from '@mui/material/styles';
|
|
19
|
-
import
|
|
20
|
-
import { FormDataConsumer, RaRecord, useRecordContext, useTranslate, useTranslateLabel } from 'ra-core';
|
|
20
|
+
import { FormDataConsumer, RaRecord, useTranslate, useTranslateLabel } from 'ra-core';
|
|
21
21
|
import * as React from 'react';
|
|
22
22
|
import { Children, ReactElement, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
|
|
23
23
|
import { Confirm, useArrayInput } from 'react-admin';
|
|
24
24
|
import { UseFieldArrayReturn, useFormContext } from 'react-hook-form';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
+
* How to use TableFormIterator:
|
|
27
28
|
*
|
|
28
29
|
* @example
|
|
29
30
|
* <Grid container>
|
|
30
31
|
* <Grid item xs={12}>
|
|
31
32
|
* <ArrayInput label={false} source="descriptor.fields">
|
|
32
|
-
* <TableFormIterator
|
|
33
|
+
* <TableFormIterator label="Property catalog">
|
|
33
34
|
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
34
|
-
* <TextInput source={'denomination'} helperText={false} />
|
|
35
|
+
* <TextInput label="Denomination" source={'denomination'} helperText={false} />
|
|
35
36
|
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
37
|
+
* {...}
|
|
36
38
|
* </TableFormIterator>
|
|
37
39
|
* </ArrayInput>
|
|
38
40
|
* </Grid>
|
|
@@ -50,15 +52,14 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
50
52
|
className,
|
|
51
53
|
empty,
|
|
52
54
|
template = {},
|
|
55
|
+
addButton = <AddTableRow />,
|
|
53
56
|
inset
|
|
54
57
|
} = props;
|
|
55
58
|
const [confirmIsOpen, setConfirmIsOpen] = useState<boolean>(false);
|
|
56
59
|
const { fields, remove, replace, append } = useArrayInput(props);
|
|
57
60
|
const { resetField } = useFormContext();
|
|
58
|
-
|
|
59
61
|
const theme = useTheme();
|
|
60
62
|
const translate = useTranslate();
|
|
61
|
-
const record = useRecordContext(props);
|
|
62
63
|
const initialDefaultValue = useRef(template || {});
|
|
63
64
|
|
|
64
65
|
const translateLabel = useTranslateLabel();
|
|
@@ -129,9 +130,6 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
129
130
|
setConfirmIsOpen(false);
|
|
130
131
|
}, [replace]);
|
|
131
132
|
|
|
132
|
-
// @ts-ignore
|
|
133
|
-
const records = get(record, source);
|
|
134
|
-
|
|
135
133
|
const context = useMemo(
|
|
136
134
|
() => ({
|
|
137
135
|
total: fields.length,
|
|
@@ -149,12 +147,15 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
149
147
|
// @ts-ignore
|
|
150
148
|
<TableFormIteratorContext.Provider value={context}>
|
|
151
149
|
<div className={className}>
|
|
152
|
-
{React.cloneElement(
|
|
150
|
+
{React.cloneElement(addButton, {
|
|
153
151
|
label,
|
|
154
152
|
source,
|
|
155
153
|
disableAdd,
|
|
156
154
|
template,
|
|
157
|
-
onClick:
|
|
155
|
+
onClick:
|
|
156
|
+
addButton?.type !== CreateButton
|
|
157
|
+
? handleAddButtonClick((props?.addButton as any)?.props?.onClick)
|
|
158
|
+
: undefined,
|
|
158
159
|
inset
|
|
159
160
|
})}
|
|
160
161
|
|
|
@@ -173,6 +174,9 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
173
174
|
<TableRow>
|
|
174
175
|
{/** @ts-ignore */}
|
|
175
176
|
{Children.map(children, (input: ReactElement, index) => {
|
|
177
|
+
if (input.type === EditButton) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
176
180
|
if (!React.isValidElement<any>(input)) {
|
|
177
181
|
return null;
|
|
178
182
|
}
|
|
@@ -185,18 +189,17 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
185
189
|
);
|
|
186
190
|
})}
|
|
187
191
|
|
|
188
|
-
{!disableRemove &&
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
))}
|
|
192
|
+
{!disableRemove && showClearAllButton ? (
|
|
193
|
+
<TableCell key="actions" sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
|
194
|
+
<ActionsMenu horizontal>
|
|
195
|
+
<Typography color="error" onClick={() => setConfirmIsOpen(true)}>
|
|
196
|
+
{translate('ra.action.delete')}
|
|
197
|
+
</Typography>
|
|
198
|
+
</ActionsMenu>
|
|
199
|
+
</TableCell>
|
|
200
|
+
) : (
|
|
201
|
+
<TableCell key="empty_actions" />
|
|
202
|
+
)}
|
|
200
203
|
</TableRow>
|
|
201
204
|
</TableHead>
|
|
202
205
|
|
|
@@ -223,7 +226,7 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
223
226
|
index={index}
|
|
224
227
|
member={`${source}.${index}`}
|
|
225
228
|
onRemoveField={removeField}
|
|
226
|
-
record={(
|
|
229
|
+
record={(fields && fields[index]) || {}}
|
|
227
230
|
// @ts-ignore
|
|
228
231
|
resource={resource}
|
|
229
232
|
// @ts-ignore
|
|
@@ -251,35 +254,6 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
|
|
|
251
254
|
) : null;
|
|
252
255
|
}
|
|
253
256
|
|
|
254
|
-
function AddTableRow(props: any): JSX.Element {
|
|
255
|
-
const { label, disableAdd, onClick, inset } = props;
|
|
256
|
-
const theme = useTheme();
|
|
257
|
-
// @ts-ignore
|
|
258
|
-
const tableBorderColor = theme.palette.mode === 'dark' ? theme.palette.grey.A400 : theme.palette.grey.A800;
|
|
259
|
-
const iconColor = theme.palette.mode === 'light' ? '#000000' : '#FFFFFF';
|
|
260
|
-
|
|
261
|
-
return (
|
|
262
|
-
<Stack
|
|
263
|
-
justifyContent={'space-between'}
|
|
264
|
-
alignItems={'center'}
|
|
265
|
-
flexDirection={'row'}
|
|
266
|
-
sx={inset ? { p: 2.5 } : { pt: 2 }}
|
|
267
|
-
>
|
|
268
|
-
{label !== false && <Typography>{label}</Typography>}
|
|
269
|
-
{!disableAdd &&
|
|
270
|
-
(React.isValidElement(props?.addButton) ? (
|
|
271
|
-
React.cloneElement(props?.addButton, {
|
|
272
|
-
onClick: onClick
|
|
273
|
-
})
|
|
274
|
-
) : (
|
|
275
|
-
<IconButton color="secondary" sx={{ border: `1px solid ${tableBorderColor}` }} onClick={onClick}>
|
|
276
|
-
<PlusCircleOutlined style={{ color: iconColor }} />
|
|
277
|
-
</IconButton>
|
|
278
|
-
))}
|
|
279
|
-
</Stack>
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
257
|
const TableFormIterator = styled(RawTableFormIterator, { slot: 'Root' })(({ theme }) => ({
|
|
284
258
|
'& > div.MuiPaper-root': {
|
|
285
259
|
overflowX: 'auto',
|
|
@@ -302,12 +276,23 @@ interface TableFormIteratorProps extends Partial<UseFieldArrayReturn> {
|
|
|
302
276
|
disableAdd?: boolean;
|
|
303
277
|
disableRemove?: boolean;
|
|
304
278
|
enableClearAll?: boolean;
|
|
279
|
+
/**
|
|
280
|
+
* Adding the template prop will allow to set a default value for the new row.
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* <Grid container>
|
|
284
|
+
* <Grid item xs={12}>
|
|
285
|
+
* <ArrayInput label={false} source="descriptor.fields">
|
|
286
|
+
* <TableFormIterator template={{ property: 'FIELD' }} label="Property catalog">
|
|
287
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
288
|
+
* <TextInput source={'denomination'} helperText={false} />
|
|
289
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
290
|
+
* </TableFormIterator>
|
|
291
|
+
* </ArrayInput>
|
|
292
|
+
* </Grid>
|
|
293
|
+
* </Grid>
|
|
294
|
+
*/
|
|
305
295
|
template?: object;
|
|
306
|
-
meta?: {
|
|
307
|
-
// the type defined in FieldArrayRenderProps says error is boolean, which is wrong.
|
|
308
|
-
error?: any;
|
|
309
|
-
submitFailed?: boolean;
|
|
310
|
-
};
|
|
311
296
|
record?: RaRecord;
|
|
312
297
|
label?: string | boolean;
|
|
313
298
|
resource?: string;
|
|
@@ -317,5 +302,89 @@ interface TableFormIteratorProps extends Partial<UseFieldArrayReturn> {
|
|
|
317
302
|
inset?: boolean;
|
|
318
303
|
}
|
|
319
304
|
|
|
320
|
-
|
|
305
|
+
type ITableForm = typeof TableFormIterator & {
|
|
306
|
+
/**
|
|
307
|
+
* TableFormiterator allows to insert an addButton which will render the default btn and open a dialog with the form fields passed as children.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* <Grid container>
|
|
311
|
+
* <Grid item xs={12}>
|
|
312
|
+
* <ArrayInput label={false} source="descriptor.fields">
|
|
313
|
+
* <TableFormIterator
|
|
314
|
+
* addButton={<TableFormIterator.CreateButton>
|
|
315
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
316
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
317
|
+
* </TableFormIterator.CreateButton>}
|
|
318
|
+
* label="Property catalog">
|
|
319
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
320
|
+
* <TextInput label="Denomination" source={'denomination'} helperText={false} />
|
|
321
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
322
|
+
* </TableFormIterator>
|
|
323
|
+
* </ArrayInput>
|
|
324
|
+
* </Grid>
|
|
325
|
+
* </Grid>
|
|
326
|
+
*/
|
|
327
|
+
CreateButton: typeof CreateButton;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* TableFormiterator allows a child EditButton which will render an edit button in the ActionsMenu of each row.
|
|
331
|
+
* The EditButton will open a dialog with the form fields passed as children.
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* <Grid container>
|
|
335
|
+
* <Grid item xs={12}>
|
|
336
|
+
* <ArrayInput label={false} source="descriptor.fields">
|
|
337
|
+
* <TableFormIterator label="Property catalog">
|
|
338
|
+
*
|
|
339
|
+
* <TableFormIterator.EditButton>
|
|
340
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
341
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
342
|
+
* </TableFormIterator.EditButton>
|
|
343
|
+
*
|
|
344
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
345
|
+
* <TextInput label="Denomination" source={'denomination'} helperText={false} />
|
|
346
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
347
|
+
* </TableFormIterator>
|
|
348
|
+
* </ArrayInput>
|
|
349
|
+
* </Grid>
|
|
350
|
+
* </Grid>
|
|
351
|
+
*/
|
|
352
|
+
EditButton: typeof EditButton;
|
|
353
|
+
/**
|
|
354
|
+
* TableFormiterator allows a child Field which will render a read-only field in the Table with a custom record context.
|
|
355
|
+
* The record context will overwritthe by getValues() of useFormContext() hook.
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* <Grid container>
|
|
359
|
+
* <Grid item xs={12}>
|
|
360
|
+
* <ArrayInput label={false} source="descriptor.fields">
|
|
361
|
+
* <TableFormIterator label="Property catalog">
|
|
362
|
+
*
|
|
363
|
+
* <TableFormIterator.EditButton>
|
|
364
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
365
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
366
|
+
* </TableFormIterator.EditButton>
|
|
367
|
+
*
|
|
368
|
+
* <TableFormIterator.Field source="name">
|
|
369
|
+
* <TextField />
|
|
370
|
+
* </TableFormIterator.Field>
|
|
371
|
+
* <TableFormIterator.Field source="type">
|
|
372
|
+
* <TextField />
|
|
373
|
+
* </TableFormIterator.Field>
|
|
374
|
+
* {...}
|
|
375
|
+
* </TableFormIterator>
|
|
376
|
+
* </ArrayInput>
|
|
377
|
+
* </Grid>
|
|
378
|
+
* </Grid>
|
|
379
|
+
*/
|
|
380
|
+
Field: typeof Field;
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const DefaultTableForm = TableFormIterator as ITableForm;
|
|
384
|
+
|
|
385
|
+
DefaultTableForm.CreateButton = CreateButton;
|
|
386
|
+
DefaultTableForm.EditButton = EditButton;
|
|
387
|
+
DefaultTableForm.Field = Field;
|
|
388
|
+
|
|
389
|
+
export { DefaultTableForm as TableFormIterator };
|
|
321
390
|
export type { TableFormIteratorProps };
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
+
import { EditButton } from './EditButton';
|
|
1
2
|
import { ActionsMenu } from '@/components/ActionsMenu';
|
|
2
3
|
import { useTableFormIterator } from '@/components/ra-forms/TableForm/TableFormIteratorContext';
|
|
3
4
|
import {
|
|
4
5
|
TableFormIteratorItemContext,
|
|
5
6
|
TableFormIteratorItemContextValue
|
|
6
7
|
} from '@/components/ra-forms/TableForm/TableFormIteratorItemContext';
|
|
7
|
-
import { Stack, TableCell
|
|
8
|
+
import { Button, Stack, TableCell } from '@mui/material';
|
|
8
9
|
import { RaRecord } from 'ra-core';
|
|
9
10
|
import { Children, ReactElement, ReactNode, cloneElement, isValidElement, useMemo } from 'react';
|
|
10
11
|
import * as React from 'react';
|
|
11
12
|
import { Confirm, useTranslate } from 'react-admin';
|
|
12
13
|
|
|
13
14
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
|
-
|
|
15
|
-
const { children, disabled, disableRemove = false, index, member, resource } = props;
|
|
15
|
+
const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorItemProps, _: any) => {
|
|
16
|
+
const { children, disabled, disableRemove = false, index, member, resource, record } = props;
|
|
16
17
|
const translate = useTranslate();
|
|
17
18
|
const [confirmIsOpen, setConfirmIsOpen] = React.useState<boolean>(false);
|
|
18
19
|
const { total, remove } = useTableFormIterator();
|
|
@@ -27,15 +28,31 @@ export const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorI
|
|
|
27
28
|
() => ({
|
|
28
29
|
index,
|
|
29
30
|
total,
|
|
31
|
+
item: record,
|
|
30
32
|
remove: () => remove(index)
|
|
31
33
|
}),
|
|
32
|
-
[index, total, remove]
|
|
34
|
+
[index, total, remove, record]
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const renderEditButton = useMemo(
|
|
38
|
+
() =>
|
|
39
|
+
Children.map(children, (Child) => {
|
|
40
|
+
if (isValidElement(Child) && Child?.type === EditButton) {
|
|
41
|
+
return React.isValidElement(Child) ? Child : null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}),
|
|
46
|
+
[children]
|
|
33
47
|
);
|
|
34
48
|
|
|
35
49
|
return (
|
|
36
50
|
<TableFormIteratorItemContext.Provider value={context}>
|
|
37
51
|
{/** @ts-ignore */}
|
|
38
52
|
{Children.map(children, (input: ReactElement, index2) => {
|
|
53
|
+
if (input.type === EditButton) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
39
56
|
if (!isValidElement<any>(input)) {
|
|
40
57
|
return null;
|
|
41
58
|
}
|
|
@@ -58,13 +75,22 @@ export const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorI
|
|
|
58
75
|
<TableCell>
|
|
59
76
|
<Stack direction="row" spacing={1} justifyContent="center" alignItems="center">
|
|
60
77
|
<ActionsMenu horizontal>
|
|
61
|
-
<
|
|
78
|
+
<Button onClick={() => setConfirmIsOpen(true)} color="error" sx={{ justifyContent: 'flex-start' }}>
|
|
62
79
|
{translate('ra.action.delete')}
|
|
63
|
-
</
|
|
80
|
+
</Button>
|
|
81
|
+
{renderEditButton}
|
|
64
82
|
</ActionsMenu>
|
|
65
83
|
</Stack>
|
|
66
84
|
</TableCell>
|
|
67
85
|
)}
|
|
86
|
+
{disableRemove && renderEditButton ? (
|
|
87
|
+
<TableCell>
|
|
88
|
+
<Stack direction="row" spacing={1} justifyContent="center" alignItems="center">
|
|
89
|
+
<ActionsMenu horizontal>{renderEditButton}</ActionsMenu>
|
|
90
|
+
</Stack>
|
|
91
|
+
</TableCell>
|
|
92
|
+
) : null}
|
|
93
|
+
|
|
68
94
|
{/** @ts-ignore */}
|
|
69
95
|
{children.length > 0 && (
|
|
70
96
|
<Confirm
|
|
@@ -79,7 +105,7 @@ export const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorI
|
|
|
79
105
|
);
|
|
80
106
|
});
|
|
81
107
|
|
|
82
|
-
|
|
108
|
+
type TableFormIteratorItemProps = {
|
|
83
109
|
children?: ReactNode;
|
|
84
110
|
disabled?: boolean;
|
|
85
111
|
disableRemove?: boolean;
|
|
@@ -88,6 +114,10 @@ export type TableFormIteratorItemProps = {
|
|
|
88
114
|
onRemoveField: (index: number) => void;
|
|
89
115
|
record: RaRecord;
|
|
90
116
|
removeButton?: ReactElement;
|
|
117
|
+
editAction?: ReactElement;
|
|
91
118
|
resource: string;
|
|
92
119
|
source: string;
|
|
93
120
|
};
|
|
121
|
+
|
|
122
|
+
export { TableFormIteratorItem };
|
|
123
|
+
export type { TableFormIteratorItemProps };
|