@applica-software-guru/react-admin 1.5.262 → 1.5.264

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 (35) hide show
  1. package/dist/components/ra-forms/TableForm/AddTableRow.d.ts +4 -0
  2. package/dist/components/ra-forms/TableForm/AddTableRow.d.ts.map +1 -0
  3. package/dist/components/ra-forms/TableForm/CreateButton.d.ts +12 -0
  4. package/dist/components/ra-forms/TableForm/CreateButton.d.ts.map +1 -0
  5. package/dist/components/ra-forms/TableForm/EditButton.d.ts +3 -0
  6. package/dist/components/ra-forms/TableForm/EditButton.d.ts.map +1 -0
  7. package/dist/components/ra-forms/TableForm/Field.d.ts +8 -0
  8. package/dist/components/ra-forms/TableForm/Field.d.ts.map +1 -0
  9. package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts +97 -5
  10. package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts.map +1 -1
  11. package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts +5 -2
  12. package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts.map +1 -1
  13. package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts +1 -0
  14. package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts.map +1 -1
  15. package/dist/components/ra-forms/TableForm/index.d.ts +4 -0
  16. package/dist/components/ra-forms/TableForm/index.d.ts.map +1 -1
  17. package/dist/react-admin.cjs.js +52 -52
  18. package/dist/react-admin.cjs.js.gz +0 -0
  19. package/dist/react-admin.cjs.js.map +1 -1
  20. package/dist/react-admin.es.js +8392 -8397
  21. package/dist/react-admin.es.js.gz +0 -0
  22. package/dist/react-admin.es.js.map +1 -1
  23. package/dist/react-admin.umd.js +51 -51
  24. package/dist/react-admin.umd.js.gz +0 -0
  25. package/dist/react-admin.umd.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/ra-forms/TableForm/AddTableRow.tsx +34 -0
  28. package/src/components/ra-forms/TableForm/CreateButton.tsx +58 -0
  29. package/src/components/ra-forms/TableForm/EditButton.tsx +42 -0
  30. package/src/components/ra-forms/TableForm/Field.tsx +23 -0
  31. package/src/components/ra-forms/TableForm/TableFormIterator.tsx +147 -65
  32. package/src/components/ra-forms/TableForm/TableFormIteratorItem.tsx +37 -7
  33. package/src/components/ra-forms/TableForm/TableFormIteratorItemContext.ts +1 -0
  34. package/src/components/ra-forms/TableForm/index.ts +4 -0
  35. package/src/components/ra-inputs/LabeledInput.tsx +1 -1
package/package.json CHANGED
@@ -106,5 +106,5 @@
106
106
  "type": "module",
107
107
  "types": "dist/index.d.ts",
108
108
  "typings": "dist/index.d.ts",
109
- "version": "1.5.262"
109
+ "version": "1.5.264"
110
110
  }
@@ -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,25 @@ import {
16
17
  Typography
17
18
  } from '@mui/material';
18
19
  import { styled, useTheme } from '@mui/material/styles';
19
- import get from 'lodash/get';
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
+ import { Tooltip } from '@/components/@extended';
25
26
 
26
27
  /**
28
+ * How to use TableFormIterator:
27
29
  *
28
30
  * @example
29
31
  * <Grid container>
30
32
  * <Grid item xs={12}>
31
33
  * <ArrayInput label={false} source="descriptor.fields">
32
- * <TableFormIterator template={{ property: 'FIELD' }} label="Catalogo proprietà"> // template: default value for new row
34
+ * <TableFormIterator label="Property catalog">
33
35
  * <TextInput label="Name" source={'name'} validate={required()} />
34
- * <TextInput source={'denomination'} helperText={false} />
36
+ * <TextInput label="Denomination" source={'denomination'} helperText={false} />
35
37
  * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
38
+ * {...}
36
39
  * </TableFormIterator>
37
40
  * </ArrayInput>
38
41
  * </Grid>
@@ -50,15 +53,14 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
50
53
  className,
51
54
  empty,
52
55
  template = {},
56
+ addButton = <AddTableRow />,
53
57
  inset
54
58
  } = props;
55
59
  const [confirmIsOpen, setConfirmIsOpen] = useState<boolean>(false);
56
60
  const { fields, remove, replace, append } = useArrayInput(props);
57
61
  const { resetField } = useFormContext();
58
-
59
62
  const theme = useTheme();
60
63
  const translate = useTranslate();
61
- const record = useRecordContext(props);
62
64
  const initialDefaultValue = useRef(template || {});
63
65
 
64
66
  const translateLabel = useTranslateLabel();
@@ -129,9 +131,6 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
129
131
  setConfirmIsOpen(false);
130
132
  }, [replace]);
131
133
 
132
- // @ts-ignore
133
- const records = get(record, source);
134
-
135
134
  const context = useMemo(
136
135
  () => ({
137
136
  total: fields.length,
@@ -149,12 +148,15 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
149
148
  // @ts-ignore
150
149
  <TableFormIteratorContext.Provider value={context}>
151
150
  <div className={className}>
152
- {React.cloneElement(<AddTableRow />, {
151
+ {React.cloneElement(addButton, {
153
152
  label,
154
153
  source,
155
154
  disableAdd,
156
155
  template,
157
- onClick: handleAddButtonClick((props?.addButton as any)?.props?.onClick),
156
+ onClick:
157
+ addButton?.type !== CreateButton
158
+ ? handleAddButtonClick((props?.addButton as any)?.props?.onClick)
159
+ : undefined,
158
160
  inset
159
161
  })}
160
162
 
@@ -173,30 +175,44 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
173
175
  <TableRow>
174
176
  {/** @ts-ignore */}
175
177
  {Children.map(children, (input: ReactElement, index) => {
178
+ if (input.type === EditButton) {
179
+ return null;
180
+ }
176
181
  if (!React.isValidElement<any>(input)) {
177
182
  return null;
178
183
  }
184
+
185
+ const columnText = (
186
+ <Typography display={'flex'} variant="subtitle1" color="text.primary" textTransform="none">
187
+ {translateLabel({ ...input.props, resource })}
188
+ </Typography>
189
+ );
190
+
179
191
  return (
180
192
  <TableCell key={index}>
181
- <Typography display={'flex'} variant="subtitle1" color="text.primary" textTransform="none">
182
- {translateLabel({ ...input.props, resource })}
183
- </Typography>
193
+ {input.props.title ? (
194
+ // @ts-ignore
195
+ <Tooltip title={input.props.title} arrow>
196
+ {columnText}
197
+ </Tooltip>
198
+ ) : (
199
+ columnText
200
+ )}
184
201
  </TableCell>
185
202
  );
186
203
  })}
187
204
 
188
- {!disableRemove &&
189
- (showClearAllButton ? (
190
- <TableCell key="actions" sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
191
- <ActionsMenu horizontal>
192
- <Typography color="error" onClick={() => setConfirmIsOpen(true)}>
193
- {translate('ra.action.delete')}
194
- </Typography>
195
- </ActionsMenu>
196
- </TableCell>
197
- ) : (
198
- <TableCell key="empty_actions" />
199
- ))}
205
+ {!disableRemove && showClearAllButton ? (
206
+ <TableCell key="actions" sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
207
+ <ActionsMenu horizontal>
208
+ <Typography color="error" onClick={() => setConfirmIsOpen(true)}>
209
+ {translate('ra.action.delete')}
210
+ </Typography>
211
+ </ActionsMenu>
212
+ </TableCell>
213
+ ) : (
214
+ <TableCell key="empty_actions" />
215
+ )}
200
216
  </TableRow>
201
217
  </TableHead>
202
218
 
@@ -223,7 +239,7 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
223
239
  index={index}
224
240
  member={`${source}.${index}`}
225
241
  onRemoveField={removeField}
226
- record={(records && records[index]) || {}}
242
+ record={(fields && fields[index]) || {}}
227
243
  // @ts-ignore
228
244
  resource={resource}
229
245
  // @ts-ignore
@@ -251,35 +267,6 @@ function RawTableFormIterator(props: TableFormIteratorProps): ReactElement | nul
251
267
  ) : null;
252
268
  }
253
269
 
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
270
  const TableFormIterator = styled(RawTableFormIterator, { slot: 'Root' })(({ theme }) => ({
284
271
  '& > div.MuiPaper-root': {
285
272
  overflowX: 'auto',
@@ -302,12 +289,23 @@ interface TableFormIteratorProps extends Partial<UseFieldArrayReturn> {
302
289
  disableAdd?: boolean;
303
290
  disableRemove?: boolean;
304
291
  enableClearAll?: boolean;
292
+ /**
293
+ * Adding the template prop will allow to set a default value for the new row.
294
+ *
295
+ * @example
296
+ * <Grid container>
297
+ * <Grid item xs={12}>
298
+ * <ArrayInput label={false} source="descriptor.fields">
299
+ * <TableFormIterator template={{ property: 'FIELD' }} label="Property catalog">
300
+ * <TextInput label="Name" source={'name'} validate={required()} />
301
+ * <TextInput source={'denomination'} helperText={false} />
302
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
303
+ * </TableFormIterator>
304
+ * </ArrayInput>
305
+ * </Grid>
306
+ * </Grid>
307
+ */
305
308
  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
309
  record?: RaRecord;
312
310
  label?: string | boolean;
313
311
  resource?: string;
@@ -317,5 +315,89 @@ interface TableFormIteratorProps extends Partial<UseFieldArrayReturn> {
317
315
  inset?: boolean;
318
316
  }
319
317
 
320
- export { TableFormIterator };
318
+ type ITableForm = typeof TableFormIterator & {
319
+ /**
320
+ * TableFormiterator allows to insert an addButton which will render the default btn and open a dialog with the form fields passed as children.
321
+ *
322
+ * @example
323
+ * <Grid container>
324
+ * <Grid item xs={12}>
325
+ * <ArrayInput label={false} source="descriptor.fields">
326
+ * <TableFormIterator
327
+ * addButton={<TableFormIterator.CreateButton>
328
+ * <TextInput label="Name" source={'name'} validate={required()} />
329
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
330
+ * </TableFormIterator.CreateButton>}
331
+ * label="Property catalog">
332
+ * <TextInput label="Name" source={'name'} validate={required()} />
333
+ * <TextInput label="Denomination" source={'denomination'} helperText={false} />
334
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
335
+ * </TableFormIterator>
336
+ * </ArrayInput>
337
+ * </Grid>
338
+ * </Grid>
339
+ */
340
+ CreateButton: typeof CreateButton;
341
+
342
+ /**
343
+ * TableFormiterator allows a child EditButton which will render an edit button in the ActionsMenu of each row.
344
+ * The EditButton will open a dialog with the form fields passed as children.
345
+ *
346
+ * @example
347
+ * <Grid container>
348
+ * <Grid item xs={12}>
349
+ * <ArrayInput label={false} source="descriptor.fields">
350
+ * <TableFormIterator label="Property catalog">
351
+ *
352
+ * <TableFormIterator.EditButton>
353
+ * <TextInput label="Name" source={'name'} validate={required()} />
354
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
355
+ * </TableFormIterator.EditButton>
356
+ *
357
+ * <TextInput label="Name" source={'name'} validate={required()} />
358
+ * <TextInput label="Denomination" source={'denomination'} helperText={false} />
359
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
360
+ * </TableFormIterator>
361
+ * </ArrayInput>
362
+ * </Grid>
363
+ * </Grid>
364
+ */
365
+ EditButton: typeof EditButton;
366
+ /**
367
+ * TableFormiterator allows a child Field which will render a read-only field in the Table with a custom record context.
368
+ * The record context will overwritthe by getValues() of useFormContext() hook.
369
+ *
370
+ * @example
371
+ * <Grid container>
372
+ * <Grid item xs={12}>
373
+ * <ArrayInput label={false} source="descriptor.fields">
374
+ * <TableFormIterator label="Property catalog">
375
+ *
376
+ * <TableFormIterator.EditButton>
377
+ * <TextInput label="Name" source={'name'} validate={required()} />
378
+ * <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
379
+ * </TableFormIterator.EditButton>
380
+ *
381
+ * <TableFormIterator.Field source="name">
382
+ * <TextField />
383
+ * </TableFormIterator.Field>
384
+ * <TableFormIterator.Field source="type">
385
+ * <TextField />
386
+ * </TableFormIterator.Field>
387
+ * {...}
388
+ * </TableFormIterator>
389
+ * </ArrayInput>
390
+ * </Grid>
391
+ * </Grid>
392
+ */
393
+ Field: typeof Field;
394
+ };
395
+
396
+ const DefaultTableForm = TableFormIterator as ITableForm;
397
+
398
+ DefaultTableForm.CreateButton = CreateButton;
399
+ DefaultTableForm.EditButton = EditButton;
400
+ DefaultTableForm.Field = Field;
401
+
402
+ export { DefaultTableForm as TableFormIterator };
321
403
  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, Typography } from '@mui/material';
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
- export const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorItemProps, _: any) => {
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
- <Typography color="error" onClick={() => setConfirmIsOpen(true)}>
78
+ <Button onClick={() => setConfirmIsOpen(true)} color="error" sx={{ justifyContent: 'flex-start' }}>
62
79
  {translate('ra.action.delete')}
63
- </Typography>
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
- export type TableFormIteratorItemProps = {
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 };
@@ -12,6 +12,7 @@ const TableFormIteratorItemContext = createContext<TableFormIteratorItemContextV
12
12
  type TableFormIteratorItemContextValue = {
13
13
  index: number;
14
14
  total: number;
15
+ item: any;
15
16
  remove: () => void;
16
17
  reOrder: (newIndex: number) => void;
17
18
  };
@@ -1,3 +1,7 @@
1
+ export * from './AddTableRow';
2
+ export * from './CreateButton';
3
+ export * from './EditButton';
4
+ export * from './Field';
1
5
  export * from './TableFormIterator';
2
6
  export * from './TableFormIteratorContext';
3
7
  export * from './TableFormIteratorItem';
@@ -62,7 +62,7 @@ function LabeledInput({
62
62
  label: display === 'legend' ? label : false
63
63
  })
64
64
  : children}
65
- {display === 'label' && helperText ? (
65
+ {helperText ? (
66
66
  <FormHelperText
67
67
  sx={{
68
68
  pl: 1.8,