@applica-software-guru/react-admin 1.1.89 → 1.1.91
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/ActionsMenu.d.ts +2 -1
- package/dist/components/ActionsMenu.d.ts.map +1 -1
- package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts +41 -0
- package/dist/components/ra-forms/TableForm/TableFormIterator.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorContext.d.ts +17 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorContext.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts +18 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorItem.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts +15 -0
- package/dist/components/ra-forms/TableForm/TableFormIteratorItemContext.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/index.d.ts +7 -0
- package/dist/components/ra-forms/TableForm/index.d.ts.map +1 -0
- package/dist/components/ra-forms/TableForm/useTableFormIterator.d.ts +8 -0
- package/dist/components/ra-forms/TableForm/useTableFormIterator.d.ts.map +1 -0
- package/dist/components/ra-forms/index.d.ts +2 -1
- package/dist/components/ra-forms/index.d.ts.map +1 -1
- package/dist/react-admin.cjs.js +50 -50
- package/dist/react-admin.cjs.js.map +1 -1
- package/dist/react-admin.es.js +8344 -7903
- package/dist/react-admin.es.js.map +1 -1
- package/dist/react-admin.umd.js +51 -51
- package/dist/react-admin.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ActionsMenu.tsx +4 -3
- package/src/components/ra-forms/TableForm/TableFormIterator.tsx +245 -0
- package/src/components/ra-forms/TableForm/TableFormIteratorContext.ts +19 -0
- package/src/components/ra-forms/TableForm/TableFormIteratorItem.tsx +91 -0
- package/src/components/ra-forms/TableForm/TableFormIteratorItemContext.ts +17 -0
- package/src/components/ra-forms/TableForm/index.ts +7 -0
- package/src/components/ra-forms/TableForm/useTableFormIterator.ts +10 -0
- package/src/components/ra-forms/index.jsx +14 -1
- package/src/playground/components/ra-forms/UserForm.jsx +19 -1
- package/src/playground/components/ra-forms/index.jsx +0 -1
- package/src/playground/components/ra-lists/index.jsx +0 -1
- package/src/playground/entities/index.jsx +0 -1
- package/src/playground/menu.jsx +7 -0
- package/src/playground/components/ra-forms/OrderForm.jsx +0 -48
- package/src/playground/components/ra-lists/OrderList.jsx +0 -12
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import { IconButton, MenuItem, styled } from '@mui/material';
|
|
|
2
2
|
import React, { Children, useCallback, useState } from 'react';
|
|
3
3
|
|
|
4
4
|
import MenuPopover from './MenuPopover/MenuPopover';
|
|
5
|
-
import { MoreVert } from '@mui/icons-material';
|
|
5
|
+
import { MoreHoriz, MoreVert } from '@mui/icons-material';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
|
|
8
8
|
const StyledRoot = styled('div', {
|
|
@@ -28,6 +28,7 @@ const StyledMenuPopover = styled(MenuPopover, {
|
|
|
28
28
|
}));
|
|
29
29
|
export type ActionsMenuProps = {
|
|
30
30
|
children: React.ReactNode;
|
|
31
|
+
horizontal?: boolean;
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -43,7 +44,7 @@ export type ActionsMenuProps = {
|
|
|
43
44
|
* @param {ActionsMenuProps}
|
|
44
45
|
* @returns {React.ReactElement}
|
|
45
46
|
*/
|
|
46
|
-
const ActionsMenu = ({ children }: ActionsMenuProps): React.ReactElement | null => {
|
|
47
|
+
const ActionsMenu = ({ horizontal = false, children }: ActionsMenuProps): React.ReactElement | null => {
|
|
47
48
|
const [open, setOpen] = useState(null);
|
|
48
49
|
const handleClick = (e: any) => {
|
|
49
50
|
e.stopPropagation();
|
|
@@ -66,7 +67,7 @@ const ActionsMenu = ({ children }: ActionsMenuProps): React.ReactElement | null
|
|
|
66
67
|
return (
|
|
67
68
|
<StyledRoot>
|
|
68
69
|
<IconButton aria-label="more" aria-haspopup="true" onClick={handleClick} color={open ? 'inherit' : 'default'}>
|
|
69
|
-
<MoreVert />
|
|
70
|
+
{horizontal ? <MoreHoriz /> : <MoreVert />}
|
|
70
71
|
</IconButton>
|
|
71
72
|
<StyledMenuPopover open={open} onClose={handleClose} arrow="right-top">
|
|
72
73
|
{Children.map(
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Children, ReactElement, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { Confirm, useArrayInput } from 'react-admin';
|
|
5
|
+
import {
|
|
6
|
+
IconButton,
|
|
7
|
+
Paper,
|
|
8
|
+
Stack,
|
|
9
|
+
SxProps,
|
|
10
|
+
Table,
|
|
11
|
+
TableBody,
|
|
12
|
+
TableCell,
|
|
13
|
+
TableContainer,
|
|
14
|
+
TableHead,
|
|
15
|
+
TableRow,
|
|
16
|
+
Typography
|
|
17
|
+
} from '@mui/material';
|
|
18
|
+
import { RaRecord, useRecordContext, useTranslate } from 'ra-core';
|
|
19
|
+
|
|
20
|
+
import { MoreHoriz } from '@mui/icons-material';
|
|
21
|
+
import { PlusCircleOutlined } from '@ant-design/icons';
|
|
22
|
+
import PropTypes from 'prop-types';
|
|
23
|
+
import { TableFormIteratorContext } from './TableFormIteratorContext';
|
|
24
|
+
import { TableFormIteratorItem } from './TableFormIteratorItem';
|
|
25
|
+
import { UseFieldArrayReturn } from 'react-hook-form';
|
|
26
|
+
import get from 'lodash/get';
|
|
27
|
+
import { styled, useTheme } from '@mui/material/styles';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <Grid container>
|
|
33
|
+
* <Grid item xs={12}>
|
|
34
|
+
* <ArrayInput label={false} source="descriptor.fields">
|
|
35
|
+
* <TableFormIterator label="Catalogo proprietà">
|
|
36
|
+
* <TextInput label="Name" source={'name'} validate={required()} />
|
|
37
|
+
* <TextInput source={'denomination'} helperText={false} />
|
|
38
|
+
* <SelectInput choices={FieldTypes} source={'type'} helperText={false} />
|
|
39
|
+
* </TableFormIterator>
|
|
40
|
+
* </ArrayInput>
|
|
41
|
+
* </Grid>
|
|
42
|
+
* </Grid>
|
|
43
|
+
*
|
|
44
|
+
* @param props
|
|
45
|
+
* @returns
|
|
46
|
+
*/
|
|
47
|
+
const TableFormIterator = (props: TableFormIteratorProps) => {
|
|
48
|
+
const { children, resource, source, label, disableActions = false, disableAdd = false, disableRemove = false, className } = props;
|
|
49
|
+
const [confirmIsOpen, setConfirmIsOpen] = useState<boolean>(false);
|
|
50
|
+
const { fields, remove, replace } = useArrayInput(props);
|
|
51
|
+
const theme = useTheme()
|
|
52
|
+
const translate = useTranslate();
|
|
53
|
+
const record = useRecordContext(props);
|
|
54
|
+
const initialDefaultValue = useRef({});
|
|
55
|
+
const removeField = useCallback(
|
|
56
|
+
(index: number) => {
|
|
57
|
+
remove(index);
|
|
58
|
+
},
|
|
59
|
+
[remove]
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (fields.length > 0) {
|
|
63
|
+
const { ...rest } = fields[0];
|
|
64
|
+
initialDefaultValue.current = rest;
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
for (const k in initialDefaultValue.current) initialDefaultValue.current[k] = null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const handleArrayClear = useCallback(() => {
|
|
70
|
+
replace([]);
|
|
71
|
+
setConfirmIsOpen(false);
|
|
72
|
+
}, [replace]);
|
|
73
|
+
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
const records = get(record, source);
|
|
76
|
+
|
|
77
|
+
const context = useMemo(
|
|
78
|
+
() => ({
|
|
79
|
+
total: fields.length,
|
|
80
|
+
remove: removeField,
|
|
81
|
+
source
|
|
82
|
+
}),
|
|
83
|
+
[fields.length, removeField, source]
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const tableBorderColor = theme.palette.mode === 'dark' ? theme.palette.grey.A400 : theme.palette.grey.A800;
|
|
87
|
+
|
|
88
|
+
return fields ? (
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
<TableFormIteratorContext.Provider value={context}>
|
|
91
|
+
<div className={className}>
|
|
92
|
+
{/** @ts-ignore */}
|
|
93
|
+
<AddTableRow label={label} source={source} disableAdd={disableAdd} />
|
|
94
|
+
|
|
95
|
+
<TableContainer component={Paper} sx={{ mt: 2, border: `1px solid ${tableBorderColor}` }}>
|
|
96
|
+
<Table>
|
|
97
|
+
<TableHead sx={{ borderTop: 0, borderBottom: `1px solid ${tableBorderColor}` }}>
|
|
98
|
+
<TableRow>
|
|
99
|
+
{/** @ts-ignore */}
|
|
100
|
+
{Children.map(children, (input: ReactElement, index) => {
|
|
101
|
+
if (!React.isValidElement<any>(input)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const { source, label = '' } = input.props;
|
|
105
|
+
return (
|
|
106
|
+
<TableCell key={index}>
|
|
107
|
+
<Typography display={'flex'} variant="subtitle1" fontWeight={500} color="text.primary" textTransform="none">
|
|
108
|
+
{label || source}
|
|
109
|
+
</Typography>
|
|
110
|
+
</TableCell>
|
|
111
|
+
);
|
|
112
|
+
})}
|
|
113
|
+
|
|
114
|
+
{!disableActions && (
|
|
115
|
+
<TableCell sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }} key={'actions'}>
|
|
116
|
+
<Typography display={'flex'} variant="subtitle1" fontWeight={500} color="text.primary" textTransform="none">
|
|
117
|
+
<MoreHoriz />
|
|
118
|
+
</Typography>
|
|
119
|
+
</TableCell>
|
|
120
|
+
)}
|
|
121
|
+
</TableRow>
|
|
122
|
+
</TableHead>
|
|
123
|
+
|
|
124
|
+
<TableBody>
|
|
125
|
+
{fields.length === 0 && (
|
|
126
|
+
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
|
|
127
|
+
<TableCell colSpan={4} align="center">
|
|
128
|
+
<Typography variant="body1" color="text.secondary">
|
|
129
|
+
-
|
|
130
|
+
</Typography>
|
|
131
|
+
</TableCell>
|
|
132
|
+
</TableRow>
|
|
133
|
+
)}
|
|
134
|
+
|
|
135
|
+
{fields.length > 0 &&
|
|
136
|
+
fields.map((member, index) => (
|
|
137
|
+
<TableRow sx={{ borderBottom: `1px solid ${tableBorderColor}}` }} key={member.id}>
|
|
138
|
+
<TableFormIteratorItem
|
|
139
|
+
disableRemove={disableRemove}
|
|
140
|
+
disableActions={disableActions}
|
|
141
|
+
index={index}
|
|
142
|
+
member={`${source}.${index}`}
|
|
143
|
+
onRemoveField={removeField}
|
|
144
|
+
record={(records && records[index]) || {}}
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
resource={resource}
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
source={source}
|
|
149
|
+
>
|
|
150
|
+
{children}
|
|
151
|
+
</TableFormIteratorItem>
|
|
152
|
+
</TableRow>
|
|
153
|
+
))}
|
|
154
|
+
</TableBody>
|
|
155
|
+
</Table>
|
|
156
|
+
</TableContainer>
|
|
157
|
+
|
|
158
|
+
{fields.length > 0 && (
|
|
159
|
+
<Confirm
|
|
160
|
+
isOpen={confirmIsOpen}
|
|
161
|
+
title={translate('ra.action.clear_array_input')}
|
|
162
|
+
content={translate('ra.message.clear_array_input')}
|
|
163
|
+
onConfirm={handleArrayClear}
|
|
164
|
+
onClose={() => setConfirmIsOpen(false)}
|
|
165
|
+
/>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
</TableFormIteratorContext.Provider>
|
|
169
|
+
) : null;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const AddTableRow = (props: any) => {
|
|
173
|
+
const { label, disableAdd } = props;
|
|
174
|
+
const { append } = useArrayInput(props);
|
|
175
|
+
const theme = useTheme();
|
|
176
|
+
const tableBorderColor = theme.palette.mode === 'dark' ? theme.palette.grey.A400 : theme.palette.grey.A800;
|
|
177
|
+
const iconColor = theme.palette.mode === 'light' ? '#000000' : '#FFFFFF';
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<Stack justifyContent={'space-between'} alignItems={'center'} flexDirection={'row'}>
|
|
181
|
+
<Typography>{label}</Typography>
|
|
182
|
+
{!disableAdd && (
|
|
183
|
+
<IconButton size="small" color="secondary" sx={{ border: `1px solid ${tableBorderColor}` }} onClick={() => append({})}>
|
|
184
|
+
<PlusCircleOutlined style={{ color: iconColor }} />
|
|
185
|
+
</IconButton>
|
|
186
|
+
)}
|
|
187
|
+
</Stack>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const StyledTableFormIterator = styled(TableFormIterator, {
|
|
192
|
+
name: 'RaApplicaTableFormIterator',
|
|
193
|
+
slot: 'Root'
|
|
194
|
+
})(({ theme }) => ({
|
|
195
|
+
'& > div.MuiPaper-root': {
|
|
196
|
+
overflowX: 'auto',
|
|
197
|
+
[theme.breakpoints.down('sm')]: {
|
|
198
|
+
width: `calc(100vw - ${theme.spacing(8)})`
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}));
|
|
202
|
+
|
|
203
|
+
AddTableRow.propTypes = {
|
|
204
|
+
label: PropTypes.string.isRequired,
|
|
205
|
+
source: PropTypes.string.isRequired
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
TableFormIterator.propTypes = {
|
|
209
|
+
addButton: PropTypes.element,
|
|
210
|
+
children: PropTypes.node,
|
|
211
|
+
className: PropTypes.string,
|
|
212
|
+
field: PropTypes.object,
|
|
213
|
+
fields: PropTypes.array,
|
|
214
|
+
fieldState: PropTypes.object,
|
|
215
|
+
formState: PropTypes.object,
|
|
216
|
+
record: PropTypes.object,
|
|
217
|
+
source: PropTypes.string,
|
|
218
|
+
label: PropTypes.string,
|
|
219
|
+
resource: PropTypes.string,
|
|
220
|
+
translate: PropTypes.func,
|
|
221
|
+
disableAdd: PropTypes.bool,
|
|
222
|
+
disableRemove: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
|
|
223
|
+
TransitionProps: PropTypes.shape({})
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
export interface TableFormIteratorProps extends Partial<UseFieldArrayReturn> {
|
|
227
|
+
addButton?: ReactElement;
|
|
228
|
+
children?: ReactNode;
|
|
229
|
+
className?: string;
|
|
230
|
+
disableAdd?: boolean;
|
|
231
|
+
disableActions?: boolean;
|
|
232
|
+
disableRemove?: boolean;
|
|
233
|
+
meta?: {
|
|
234
|
+
// the type defined in FieldArrayRenderProps says error is boolean, which is wrong.
|
|
235
|
+
error?: any;
|
|
236
|
+
submitFailed?: boolean;
|
|
237
|
+
};
|
|
238
|
+
record?: RaRecord;
|
|
239
|
+
label?: string;
|
|
240
|
+
resource?: string;
|
|
241
|
+
source?: string;
|
|
242
|
+
sx?: SxProps;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export default StyledTableFormIterator;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A React context that provides access to a TableFormIterator data (the total number of items) and mutators (add, reorder and remove).
|
|
5
|
+
* Useful to create custom array input iterators.
|
|
6
|
+
* @see {TableFormIterator}
|
|
7
|
+
* @see {ArrayInput}
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
export const TableFormIteratorContext = createContext<TableFormIteratorContextValue>(undefined);
|
|
12
|
+
|
|
13
|
+
export type TableFormIteratorContextValue = {
|
|
14
|
+
add: () => void;
|
|
15
|
+
remove: (index: number) => void;
|
|
16
|
+
reOrder: (index: number, newIndex: number) => void;
|
|
17
|
+
source: string;
|
|
18
|
+
total: number;
|
|
19
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Children, ReactElement, ReactNode, cloneElement, isValidElement, useMemo } from 'react';
|
|
4
|
+
import { Confirm, useTranslate } from 'react-admin';
|
|
5
|
+
import { TableCell, Typography } from '@mui/material';
|
|
6
|
+
import { TableFormIteratorItemContext, TableFormIteratorItemContextValue } from './TableFormIteratorItemContext';
|
|
7
|
+
|
|
8
|
+
import ActionsMenu from '../../ActionsMenu';
|
|
9
|
+
import { RaRecord } from 'ra-core';
|
|
10
|
+
import { useTableFormIterator } from './useTableFormIterator';
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
|
+
export const TableFormIteratorItem = React.forwardRef((props: TableFormIteratorItemProps, ref: any) => {
|
|
14
|
+
const { children, disabled, disableActions = false, index, member, resource } = props;
|
|
15
|
+
const translate = useTranslate();
|
|
16
|
+
const [confirmIsOpen, setConfirmIsOpen] = React.useState<boolean>(false);
|
|
17
|
+
const { total, remove } = useTableFormIterator();
|
|
18
|
+
|
|
19
|
+
const handleRowDelete = React.useCallback(() => {
|
|
20
|
+
setConfirmIsOpen(false);
|
|
21
|
+
remove(index);
|
|
22
|
+
}, [index, remove]);
|
|
23
|
+
|
|
24
|
+
const context = useMemo<TableFormIteratorItemContextValue>(
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
() => ({
|
|
27
|
+
index,
|
|
28
|
+
total,
|
|
29
|
+
remove: () => remove(index)
|
|
30
|
+
}),
|
|
31
|
+
[index, total, remove]
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<TableFormIteratorItemContext.Provider value={context}>
|
|
36
|
+
{/** @ts-ignore */}
|
|
37
|
+
{Children.map(children, (input: ReactElement, index2) => {
|
|
38
|
+
if (!isValidElement<any>(input)) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const { source, ...inputProps } = input.props;
|
|
42
|
+
return (
|
|
43
|
+
<TableCell sx={{ border: 0 }}>
|
|
44
|
+
{cloneElement(input, {
|
|
45
|
+
source: source ? `${member}.${source}` : member,
|
|
46
|
+
index: source ? undefined : index2,
|
|
47
|
+
resource,
|
|
48
|
+
disabled,
|
|
49
|
+
...inputProps,
|
|
50
|
+
label: false
|
|
51
|
+
})}
|
|
52
|
+
</TableCell>
|
|
53
|
+
);
|
|
54
|
+
})}
|
|
55
|
+
|
|
56
|
+
{!disableActions && (
|
|
57
|
+
<TableCell sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', border: 0, pt: 2 }}>
|
|
58
|
+
<ActionsMenu horizontal>
|
|
59
|
+
<Typography color="error" onClick={() => setConfirmIsOpen(true)}>
|
|
60
|
+
{translate('ra.action.delete')}
|
|
61
|
+
</Typography>
|
|
62
|
+
</ActionsMenu>
|
|
63
|
+
</TableCell>
|
|
64
|
+
)}
|
|
65
|
+
{/** @ts-ignore */}
|
|
66
|
+
{children.length > 0 && (
|
|
67
|
+
<Confirm
|
|
68
|
+
isOpen={confirmIsOpen}
|
|
69
|
+
title={translate('ra.action.remove_item')}
|
|
70
|
+
content={translate('ra.message.remove_item')}
|
|
71
|
+
onConfirm={handleRowDelete}
|
|
72
|
+
onClose={() => setConfirmIsOpen(false)}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
</TableFormIteratorItemContext.Provider>
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export type TableFormIteratorItemProps = {
|
|
80
|
+
children?: ReactNode;
|
|
81
|
+
disabled?: boolean;
|
|
82
|
+
disableRemove?: boolean;
|
|
83
|
+
disableActions?: boolean;
|
|
84
|
+
index: number;
|
|
85
|
+
member: string;
|
|
86
|
+
onRemoveField: (index: number) => void;
|
|
87
|
+
record: RaRecord;
|
|
88
|
+
removeButton?: ReactElement;
|
|
89
|
+
resource: string;
|
|
90
|
+
source: string;
|
|
91
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A React context that provides access to a TableFormIterator item meta (its index and the total number of items) and mutators (reorder and remove this remove).
|
|
5
|
+
* Useful to create custom array input iterators.
|
|
6
|
+
* @see {TableFormIterator}
|
|
7
|
+
* @see {ArrayInput}
|
|
8
|
+
*/
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
export const TableFormIteratorItemContext = createContext<TableFormIteratorItemContextValue>(undefined);
|
|
11
|
+
|
|
12
|
+
export type TableFormIteratorItemContextValue = {
|
|
13
|
+
index: number;
|
|
14
|
+
total: number;
|
|
15
|
+
remove: () => void;
|
|
16
|
+
reOrder: (newIndex: number) => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import TableFormIterator from './TableFormIterator';
|
|
2
|
+
export * from './TableFormIteratorContext';
|
|
3
|
+
export * from './TableFormIteratorItem';
|
|
4
|
+
export * from './TableFormIteratorItemContext';
|
|
5
|
+
export * from './useTableFormIterator';
|
|
6
|
+
|
|
7
|
+
export default TableFormIterator;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { TableFormIteratorContext } from './TableFormIteratorContext';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A hook that provides access to a TableFormIterator data (the total number of items) and mutators (add, reorder and remove).
|
|
6
|
+
* Useful to create custom array input iterators.
|
|
7
|
+
* @see {TableFormIterator}
|
|
8
|
+
* @see {ArrayInput}
|
|
9
|
+
*/
|
|
10
|
+
export const useTableFormIterator = () => useContext(TableFormIteratorContext);
|
|
@@ -7,5 +7,18 @@ import LongForm from './LongForm';
|
|
|
7
7
|
import SimpleForm from './SimpleForm';
|
|
8
8
|
import SimpleFormIterator from './SimpleFormIterator';
|
|
9
9
|
import TabbedForm from './TabbedForm';
|
|
10
|
+
import TableFormIterator from './TableForm';
|
|
10
11
|
import Toolbar from './Toolbar';
|
|
11
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
Create,
|
|
14
|
+
CardForm,
|
|
15
|
+
ChangePasswordForm,
|
|
16
|
+
Edit,
|
|
17
|
+
FormHeader,
|
|
18
|
+
LongForm,
|
|
19
|
+
SimpleForm,
|
|
20
|
+
SimpleFormIterator,
|
|
21
|
+
TabbedForm,
|
|
22
|
+
TableFormIterator,
|
|
23
|
+
Toolbar
|
|
24
|
+
};
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ArrayInput,
|
|
3
|
+
BooleanInput,
|
|
4
|
+
ImageInput,
|
|
5
|
+
SelectArrayInput,
|
|
6
|
+
SimpleForm,
|
|
7
|
+
TableFormIterator,
|
|
8
|
+
TextInput,
|
|
9
|
+
useThemeConfig
|
|
10
|
+
} from '@applica-software-guru/react-admin';
|
|
2
11
|
|
|
3
12
|
import { Grid } from '@mui/material';
|
|
4
13
|
import PropTypes from 'prop-types';
|
|
@@ -23,6 +32,15 @@ const UserForm = ({ configuredRoles }) => {
|
|
|
23
32
|
<Grid item lg={12} xs={12}>
|
|
24
33
|
<ImageInput source="image" accept="image/*" multiple={false} fullWidth />
|
|
25
34
|
</Grid>
|
|
35
|
+
<Grid item lg={12} xs={12}>
|
|
36
|
+
<ArrayInput source="items" label={false}>
|
|
37
|
+
<TableFormIterator label="Informazioni utente">
|
|
38
|
+
<TextInput source="name" label="Name" sx={{ minWidth: 200 }} />
|
|
39
|
+
<TextInput source="surname" label="Surname" sx={{ minWidth: 150 }} />
|
|
40
|
+
<SelectArrayInput source="roles" label="Ruoli" choices={configuredRoles} />
|
|
41
|
+
</TableFormIterator>
|
|
42
|
+
</ArrayInput>
|
|
43
|
+
</Grid>
|
|
26
44
|
</Grid>
|
|
27
45
|
|
|
28
46
|
<BooleanInput source="active" />
|
|
@@ -2,4 +2,3 @@ export { default as user } from './user';
|
|
|
2
2
|
export { default as notification } from './notification';
|
|
3
3
|
export { default as i18nMessage } from './i18n-message';
|
|
4
4
|
export { default as device } from './device';
|
|
5
|
-
// export { default as order } from './order'; # Just for local tests.
|
package/src/playground/menu.jsx
CHANGED
|
@@ -52,6 +52,13 @@ const config = [
|
|
|
52
52
|
url: '/entities/i18n-message',
|
|
53
53
|
icon: FlagOutlined
|
|
54
54
|
},
|
|
55
|
+
{
|
|
56
|
+
id: 'entities/category',
|
|
57
|
+
title: 'ra.menu.item.entities/category',
|
|
58
|
+
type: 'item',
|
|
59
|
+
url: '/entities/category',
|
|
60
|
+
icon: FlagOutlined
|
|
61
|
+
},
|
|
55
62
|
{
|
|
56
63
|
id: 'entities/user',
|
|
57
64
|
title: 'ra.menu.item.entities/user',
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ArrayInput,
|
|
3
|
-
AttachmentInput,
|
|
4
|
-
LongForm,
|
|
5
|
-
MainCard,
|
|
6
|
-
SaveButton,
|
|
7
|
-
SimpleFormIterator,
|
|
8
|
-
TextInput,
|
|
9
|
-
Toolbar
|
|
10
|
-
} from '@applica-software-guru/react-admin';
|
|
11
|
-
|
|
12
|
-
import { Grid } from '@mui/material';
|
|
13
|
-
|
|
14
|
-
const OrderForm = () => (
|
|
15
|
-
<LongForm>
|
|
16
|
-
<LongForm.Tab label="Test">
|
|
17
|
-
<MainCard title="Foo">
|
|
18
|
-
<Grid container>
|
|
19
|
-
<Grid item xs={12}>
|
|
20
|
-
<TextInput source="name" />
|
|
21
|
-
<AttachmentInput source="attachment" title="name" multiple={false} />
|
|
22
|
-
<AttachmentInput source="attachments" title="name" multiple={true} />
|
|
23
|
-
</Grid>
|
|
24
|
-
<Grid item xs={12}>
|
|
25
|
-
<ArrayInput source="items">
|
|
26
|
-
<SimpleFormIterator>
|
|
27
|
-
<TextInput source="name" />
|
|
28
|
-
<AttachmentInput source="attachment" multiple={false} title="attachment.name" />
|
|
29
|
-
<ArrayInput source="subItems">
|
|
30
|
-
<SimpleFormIterator>
|
|
31
|
-
<TextInput source="name" />
|
|
32
|
-
<AttachmentInput source="attachment" multiple={false} title="attachment.name" />
|
|
33
|
-
<AttachmentInput source="subAttachments" multiple title="attachment.name" />
|
|
34
|
-
</SimpleFormIterator>
|
|
35
|
-
</ArrayInput>
|
|
36
|
-
</SimpleFormIterator>
|
|
37
|
-
</ArrayInput>
|
|
38
|
-
</Grid>
|
|
39
|
-
</Grid>
|
|
40
|
-
<Toolbar>
|
|
41
|
-
<SaveButton />
|
|
42
|
-
</Toolbar>
|
|
43
|
-
</MainCard>
|
|
44
|
-
</LongForm.Tab>
|
|
45
|
-
</LongForm>
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
export default OrderForm;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Datagrid, DateField, EditButton, List, TextField } from '@applica-software-guru/react-admin';
|
|
2
|
-
const OrderList = () => (
|
|
3
|
-
<List perPage={25}>
|
|
4
|
-
<Datagrid>
|
|
5
|
-
<TextField source="name" />
|
|
6
|
-
<DateField source="updated" showTime />
|
|
7
|
-
<EditButton />
|
|
8
|
-
</Datagrid>
|
|
9
|
-
</List>
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
export default OrderList;
|