@dashadmin/dash-auto-admin 1.3.25 → 1.3.26
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/DashAutoAdminComponentRegistry.js +64 -1
- package/dist/DashAutoAdminForm.js +137 -1
- package/dist/DashAutoAdminResizableDrawer.js +63 -1
- package/dist/DashAutoAdminSaveButton.js +57 -1
- package/dist/DashAutoCreate.js +102 -1
- package/dist/DashAutoDrawer.js +256 -1
- package/dist/DashAutoEdit.js +99 -1
- package/dist/DashAutoFiltersGenerator.js +193 -1
- package/dist/DashAutoFormGroups.js +118 -1
- package/dist/DashAutoFormLayout.js +68 -1
- package/dist/DashAutoFormMuiTabs.js +291 -1
- package/dist/DashAutoFormTabs.js +132 -1
- package/dist/DashAutoGroup.js +27 -1
- package/dist/DashAutoLayout.js +31 -1
- package/dist/DashAutoList.js +218 -1
- package/dist/DashAutoPostFilterForm.js +47 -1
- package/dist/DashAutoReferenceTab.js +10 -1
- package/dist/DashAutoResource.js +77 -1
- package/dist/DashAutoResourceLayout.js +16 -1
- package/dist/DashAutoShow.js +195 -1
- package/dist/DashAutoTabbedForm.js +244 -1
- package/dist/DashAutoTabbedForm.review.js +221 -1
- package/dist/DashAutoTabs.js +11 -1
- package/dist/DashFilterWrapper.js +62 -1
- package/dist/DashRedirect.js +56 -1
- package/dist/TabbedLayout.js +38 -1
- package/dist/common/DashAutoTitle.js +33 -1
- package/dist/common/components/FabButton.js +59 -1
- package/dist/common/components/TranslatedLabel.js +60 -1
- package/dist/common/settings/Settings.js +196 -1
- package/dist/common/settings/SettingsBarIcons.js +61 -1
- package/dist/context/DashAutoAdminFormContext.js +15 -1
- package/dist/hooks/useAutoAdminLoadingStateMediator.js +36 -1
- package/dist/hooks/useAutoAdminTranslate.js +61 -1
- package/dist/hooks/useHash.js +24 -1
- package/dist/hooks/useLogger.js +20 -1
- package/dist/hooks/useRoutePathPattern.js +20 -1
- package/dist/hooks/useVirtualHash.js +28 -1
- package/dist/index.js +77 -3406
- package/dist/list/DashAutoListActions.js +57 -1
- package/dist/list/DashAutoListDatagridWrapper.js +68 -1
- package/dist/list/DashAutoListDefaultActionsWrapper.js +14 -1
- package/dist/list/DashAutoListFilterFormWithButton.js +80 -1
- package/dist/list/DashAutoListTopToolbar.js +180 -1
- package/dist/mui/AttributeToField.js +576 -1
- package/dist/mui/AttributeToInput.js +630 -1
- package/dist/mui/AutoAdminResizableDrawer.js +63 -1
- package/dist/mui/AutoDataGrid.js +120 -1
- package/dist/mui/AutoReferenceFormTab.js +53 -1
- package/dist/mui/AutoReferenceTab.js +46 -1
- package/dist/mui/AutoTabs.js +19 -1
- package/dist/mui/components/ExtendedPagination.js +34 -1
- package/dist/mui/components/ListStringField.js +25 -1
- package/dist/providers/DashAuthProvider.js +215 -1
- package/dist/providers/DashDataProvider.js +310 -1
- package/dist/providers/index.js +10 -1
- package/dist/react-admin.d.js +0 -0
- package/dist/toolbar/buttons/BottomToolbarButtons.js +65 -1
- package/dist/toolbar/buttons/DashResourceButton.js +181 -1
- package/dist/toolbar/buttons/ListButtons.js +80 -1
- package/dist/toolbar/buttons/ToolbarButtons.js +135 -1
- package/dist/types/ActionCallback.d.js +0 -0
- package/dist/utils/SimpleLogger.js +52 -1
- package/dist/utils/enumToChoices.js +5 -1
- package/dist/utils/evalActionPermission.js +11 -1
- package/dist/utils/groupByTabs.js +21 -1
- package/dist/utils/hashedGroupByTabs.js +12 -1
- package/dist/utils/invertMap.js +12 -1
- package/dist/utils/isClassComponent.js +7 -1
- package/dist/utils/isComponent.js +29 -1
- package/dist/utils/isEnum.js +5 -1
- package/dist/utils/isFC.js +8 -1
- package/dist/utils/replaceParams.js +9 -1
- package/dist/utils/validate.js +19 -1
- package/dist/wrappers/UserAction.js +60 -1
- package/dist/wrappers/index.js +4 -1
- package/package.json +135 -120
- package/src/DashAutoAdminComponentRegistry.tsx +75 -0
- package/src/DashAutoAdminForm.tsx +155 -0
- package/src/DashAutoAdminResizableDrawer.tsx +69 -0
- package/src/DashAutoAdminSaveButton.tsx +116 -0
- package/src/DashAutoCreate.tsx +118 -0
- package/src/DashAutoDrawer.tsx +288 -0
- package/src/DashAutoEdit.tsx +109 -0
- package/src/DashAutoFiltersGenerator.tsx +208 -0
- package/src/DashAutoFormGroups.tsx +146 -0
- package/src/DashAutoFormLayout.tsx.review +113 -0
- package/src/DashAutoFormMuiTabs.tsx +368 -0
- package/src/DashAutoFormTabs.tsx +177 -0
- package/src/DashAutoGroup.tsx +42 -0
- package/src/DashAutoLayout.tsx +57 -0
- package/src/DashAutoList.tsx +237 -0
- package/src/DashAutoPostFilterForm.tsx +35 -0
- package/src/DashAutoReferenceTab.tsx +9 -0
- package/src/DashAutoResource.tsx +85 -0
- package/src/DashAutoResourceLayout.tsx +50 -0
- package/src/DashAutoShow.tsx +200 -0
- package/src/DashAutoTabbedForm.review.tsx +262 -0
- package/src/DashAutoTabbedForm.tsx +324 -0
- package/src/DashAutoTabs.tsx +19 -0
- package/src/DashFilterWrapper.tsx +43 -0
- package/src/DashRedirect.tsx +46 -0
- package/src/TabbedLayout.tsx +29 -0
- package/src/common/DashAutoTitle.tsx +24 -0
- package/src/common/components/FabButton.tsx +40 -0
- package/src/common/components/TranslatedLabel.tsx +81 -0
- package/src/common/settings/Settings.tsx +236 -0
- package/src/common/settings/SettingsBarIcons.tsx +72 -0
- package/src/context/DashAutoAdminFormContext.tsx +31 -0
- package/src/hooks/useAutoAdminLoadingStateMediator.tsx +42 -0
- package/src/hooks/useAutoAdminTranslate.tsx +106 -0
- package/src/hooks/useHash.tsx +27 -0
- package/src/hooks/useLogger.tsx +23 -0
- package/src/hooks/useRoutePathPattern.tsx +24 -0
- package/src/hooks/useVirtualHash.tsx +34 -0
- package/src/index.ts +85 -0
- package/src/interfaces/ICustomResourceSubComponent.ts +11 -0
- package/src/interfaces/IDashApplicationLayoutMainAction.ts +37 -0
- package/src/interfaces/IDashApplicationLayoutMenuItem.ts +24 -0
- package/src/interfaces/IDashAutoAdminAttribute.ts +104 -0
- package/src/interfaces/IDashAutoAdminCustomFieldComponent.ts +18 -0
- package/src/interfaces/IDashAutoAdminFormOptions.ts +22 -0
- package/src/interfaces/IDashAutoAdminListActions.ts +13 -0
- package/src/interfaces/IDashAutoAdminReference.ts +16 -0
- package/src/interfaces/IDashAutoAdminResourceConfig.ts +360 -0
- package/src/interfaces/IDashAutoForm.ts +24 -0
- package/src/interfaces/IDashAutoGridButton.ts +35 -0
- package/src/interfaces/IDashAutoShow.ts +12 -0
- package/src/interfaces/IGroupExtraData.ts +8 -0
- package/src/interfaces/IRecord.ts +7 -0
- package/src/interfaces/IReferenceFilter.ts +55 -0
- package/src/interfaces/IResourceComponent.ts +8 -0
- package/src/interfaces/IToolbarButton.ts +11 -0
- package/src/list/DashAutoListActions.tsx +88 -0
- package/src/list/DashAutoListDatagridWrapper.tsx +74 -0
- package/src/list/DashAutoListDefaultActionsWrapper.tsx +31 -0
- package/src/list/DashAutoListFilterFormWithButton.tsx +93 -0
- package/src/list/DashAutoListTopToolbar.tsx +240 -0
- package/src/mui/AttributeToField.tsx +657 -0
- package/src/mui/AttributeToInput.tsx +728 -0
- package/src/mui/AutoAdminResizableDrawer.tsx +69 -0
- package/src/mui/AutoDataGrid.tsx +127 -0
- package/src/mui/AutoReferenceFormTab.tsx +51 -0
- package/src/mui/AutoReferenceTab.tsx +45 -0
- package/src/mui/AutoTabs.tsx +32 -0
- package/src/mui/components/ExtendedPagination.tsx +23 -0
- package/src/mui/components/ListStringField.tsx +32 -0
- package/src/providers/DashAuthProvider.ts +341 -0
- package/src/providers/DashDataProvider.ts +466 -0
- package/src/providers/index.ts +17 -0
- package/src/toolbar/buttons/BottomToolbarButtons.tsx +59 -0
- package/src/toolbar/buttons/DashResourceButton.tsx +223 -0
- package/src/toolbar/buttons/ListButtons.tsx +137 -0
- package/src/toolbar/buttons/ToolbarButtons.tsx +186 -0
- package/src/utils/SimpleLogger.tsx +46 -0
- package/src/utils/enumToChoices.tsx +3 -0
- package/src/utils/evalActionPermission.tsx +14 -0
- package/src/utils/groupByTabs.tsx +23 -0
- package/src/utils/hashedGroupByTabs.tsx +16 -0
- package/src/utils/invertMap.tsx +10 -0
- package/src/utils/isClassComponent.tsx +9 -0
- package/src/utils/isComponent.tsx +45 -0
- package/src/utils/isEnum.tsx +3 -0
- package/src/utils/isFC.tsx +6 -0
- package/src/utils/replaceParams.tsx +6 -0
- package/src/utils/validate.tsx +24 -0
- package/src/wrappers/UserAction.tsx +67 -0
- package/src/wrappers/index.tsx +1 -0
- /package/{dist → src}/DashAutoAdminSaveButton.tsx.bkup +0 -0
- /package/{dist/DashAutoFormLayout.tsx.review → src/DashAutoFormLayout.tsx} +0 -0
- /package/{dist → src}/DashAutoFormTabs.review +0 -0
- /package/{dist → src}/DashAutoFormTabs.tsx.formcontext.wip +0 -0
- /package/{dist → src}/mui/AttributeToField.tsx.review +0 -0
- /package/{dist → src}/mui/AttributeToInput.tsx.review +0 -0
- /package/{dist → src}/react-admin.d.ts +0 -0
- /package/{dist → src}/types/ActionCallback.d.ts +0 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArrayInput,
|
|
3
|
+
ImageInput,
|
|
4
|
+
FileInput,
|
|
5
|
+
BooleanInput,
|
|
6
|
+
DateInput,
|
|
7
|
+
DateTimeInput,
|
|
8
|
+
NumberInput,
|
|
9
|
+
SelectArrayInput,
|
|
10
|
+
SelectInput,
|
|
11
|
+
ChipField,
|
|
12
|
+
ImageField,
|
|
13
|
+
PasswordInput,
|
|
14
|
+
ReferenceArrayInput,
|
|
15
|
+
ReferenceInput,
|
|
16
|
+
SimpleFormIterator,
|
|
17
|
+
SingleFieldList,
|
|
18
|
+
TextInput,
|
|
19
|
+
useRecordContext,
|
|
20
|
+
} from 'react-admin';
|
|
21
|
+
import { ErrorMessage } from "@hookform/error-message"
|
|
22
|
+
|
|
23
|
+
import { InputAdornment, InputLabel, TextField, Typography } from '@mui/material';
|
|
24
|
+
import Visibility from '@mui/icons-material/Visibility';
|
|
25
|
+
|
|
26
|
+
import IDashAutoAdminAttribute from '../interfaces/IDashAutoAdminAttribute';
|
|
27
|
+
import IDashAutoAdminFormOptions from '../interfaces/IDashAutoAdminFormOptions';
|
|
28
|
+
|
|
29
|
+
import { UserAction } from '../wrappers';
|
|
30
|
+
import { FunctionField } from 'react-admin';
|
|
31
|
+
import { FileField } from 'react-admin';
|
|
32
|
+
|
|
33
|
+
import React, { JSX, useEffect } from 'react';
|
|
34
|
+
import IDashAutoAdminResourceConfig from '../interfaces/IDashAutoAdminResourceConfig';
|
|
35
|
+
import IDashAutoAdminCustomFieldComponent from '../interfaces/IDashAutoAdminCustomFieldComponent';
|
|
36
|
+
import enumToChoices from '../utils/enumToChoices';
|
|
37
|
+
import isEnum from '../utils/isEnum';
|
|
38
|
+
import { useLocation, useParams } from 'react-router';
|
|
39
|
+
import replaceParams from '../utils/replaceParams';
|
|
40
|
+
import { useSelector } from 'react-redux';
|
|
41
|
+
//import { IDASHAppState } from 'dash-admin-state';
|
|
42
|
+
import { useEditContext } from 'react-admin';
|
|
43
|
+
import { useFormContext } from 'react-hook-form';
|
|
44
|
+
import { useComponentRegistry } from '../DashAutoAdminComponentRegistry';
|
|
45
|
+
|
|
46
|
+
export interface IGroupExtraData {
|
|
47
|
+
name: string;
|
|
48
|
+
icon?: JSX.Element;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface IFieldWrapper {
|
|
52
|
+
method: 'list' | 'view' | 'create' | 'edit';
|
|
53
|
+
index: React.Key;
|
|
54
|
+
input: IDashAutoAdminAttribute;
|
|
55
|
+
children: JSX.Element;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
const FunctionFieldWrapper = ({
|
|
60
|
+
index,
|
|
61
|
+
method,
|
|
62
|
+
input,
|
|
63
|
+
children,
|
|
64
|
+
..._props
|
|
65
|
+
}: IFieldWrapper): JSX.Element => {
|
|
66
|
+
const sortable = input?.sortable === true ? true : false;
|
|
67
|
+
|
|
68
|
+
const {
|
|
69
|
+
formState: { errors },
|
|
70
|
+
} = useFormContext()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if (method === 'edit') {
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
className={`auto-admin-field auto-admin-field-${method}`}
|
|
77
|
+
key={index}
|
|
78
|
+
>
|
|
79
|
+
<FunctionField
|
|
80
|
+
//key={index}
|
|
81
|
+
label={input?.label || input.attribute}
|
|
82
|
+
sortable={sortable}
|
|
83
|
+
{...(sortable && { sortBy: input.listAttribute || input.attribute })}
|
|
84
|
+
render={(record) => {
|
|
85
|
+
return React.cloneElement(children, { record: record });
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
|
|
89
|
+
{!input?.hideErrorMessage || input?.custom && <ErrorMessage
|
|
90
|
+
errors={errors}
|
|
91
|
+
name={input.attribute}
|
|
92
|
+
render={(error) => {
|
|
93
|
+
return error ? <Typography className='dash-admin-field-error' color="error" >{typeof error.message === 'string' ? error.message : typeof (error as any).message?.message === 'string' ? (error as any).message?.message : JSON.stringify(error)}</Typography> : null;
|
|
94
|
+
}}
|
|
95
|
+
/>}
|
|
96
|
+
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return (
|
|
101
|
+
<div className={`auto-admin-field auto-admin-field-${method}`} key={index}>
|
|
102
|
+
{children}
|
|
103
|
+
</div>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The `AttributeToInput` function is a React component that renders an input field based on the provided `IDashAutoAdminAttribute` object.
|
|
109
|
+
* It handles various input types, including strings, numbers, booleans, dates, and enums. The function also supports custom components, reference inputs, and array inputs.
|
|
110
|
+
*
|
|
111
|
+
* The function takes the following parameters:
|
|
112
|
+
* - `method`: The current operation mode, such as 'list', 'view', 'create', or 'edit'.
|
|
113
|
+
* - `resourceConfig`: The configuration object for the current resource.
|
|
114
|
+
* - `input`: The `IDashAutoAdminAttribute` object that defines the input field.
|
|
115
|
+
* - `index`: An optional index value for the input field.
|
|
116
|
+
* - `options`: An optional object that provides additional configuration and field options.
|
|
117
|
+
*
|
|
118
|
+
* The function returns a JSX element that represents the input field, wrapped in a `FunctionFieldWrapper` component. The `FunctionFieldWrapper` component handles the rendering of the input field based on the current operation mode.
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
// Safe hook to get edit context only when available
|
|
122
|
+
const useSafeEditContext = () => {
|
|
123
|
+
try {
|
|
124
|
+
return useEditContext();
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// EditContext is not available (e.g., in create mode)
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Safe hook to get record context
|
|
132
|
+
const useSafeRecordContext = () => {
|
|
133
|
+
try {
|
|
134
|
+
return useRecordContext();
|
|
135
|
+
} catch (error) {
|
|
136
|
+
// RecordContext is not available
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Custom hook to get the appropriate record context
|
|
142
|
+
const useRecordByMethod = (method: string, mode?: string) => {
|
|
143
|
+
// Always call both hooks, but handle when they're not available
|
|
144
|
+
const editContext = useSafeEditContext();
|
|
145
|
+
const recordContext = useSafeRecordContext();
|
|
146
|
+
|
|
147
|
+
// Return the appropriate context based on method
|
|
148
|
+
if (method === 'edit' || mode === 'edit') {
|
|
149
|
+
return editContext;
|
|
150
|
+
}
|
|
151
|
+
return recordContext;
|
|
152
|
+
};
|
|
153
|
+
const AttributeToInput = (
|
|
154
|
+
method: 'list' | 'view' | 'create' | 'edit',
|
|
155
|
+
resourceConfig: IDashAutoAdminResourceConfig,
|
|
156
|
+
input: IDashAutoAdminAttribute,
|
|
157
|
+
index?: number,
|
|
158
|
+
options?: IDashAutoAdminFormOptions,
|
|
159
|
+
) => {
|
|
160
|
+
|
|
161
|
+
const DEBUG = false;
|
|
162
|
+
// Get the component registry
|
|
163
|
+
const { components } = useComponentRegistry();
|
|
164
|
+
|
|
165
|
+
// Move all hook calls to the top level, before any conditional logic
|
|
166
|
+
const mode = options?.mode || 'view';
|
|
167
|
+
const record = useRecordByMethod(method, options?.mode);
|
|
168
|
+
const location = useLocation();
|
|
169
|
+
const params = useParams();
|
|
170
|
+
|
|
171
|
+
const typeComponentMapper = (type: string) => {
|
|
172
|
+
const component = components[type];
|
|
173
|
+
|
|
174
|
+
if (component) {
|
|
175
|
+
return { custom: true, type: "component", component };
|
|
176
|
+
}
|
|
177
|
+
return { custom: true, type: "component", component: () => <>No component for {type}</> };
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const ComponentWrapper =
|
|
181
|
+
resourceConfig?.fieldWrapper &&
|
|
182
|
+
typeof resourceConfig.fieldWrapper === 'function'
|
|
183
|
+
? resourceConfig.fieldWrapper
|
|
184
|
+
: ({
|
|
185
|
+
_record,
|
|
186
|
+
_method,
|
|
187
|
+
_attribute,
|
|
188
|
+
_resourceConfig,
|
|
189
|
+
children,
|
|
190
|
+
}: IDashAutoAdminCustomFieldComponent) => children;
|
|
191
|
+
|
|
192
|
+
/*
|
|
193
|
+
input.type != 'custom'
|
|
194
|
+
input.type does not contains dots
|
|
195
|
+
input.type dies not represents an Enum or Array.
|
|
196
|
+
*/
|
|
197
|
+
|
|
198
|
+
if (typeof input.type === "string" && !input.type.includes(".") && !Array.isArray(input.type)) {
|
|
199
|
+
switch (input.type) {
|
|
200
|
+
case 'string':
|
|
201
|
+
case 'text':
|
|
202
|
+
case 'String':
|
|
203
|
+
input.type = String;
|
|
204
|
+
input.slotProps = {
|
|
205
|
+
fullWidth: input?.fieldProps?.fullWidth ?? true,
|
|
206
|
+
};
|
|
207
|
+
break;
|
|
208
|
+
case 'textarea':
|
|
209
|
+
input.type = String;
|
|
210
|
+
input.multiple = true;
|
|
211
|
+
|
|
212
|
+
input.slotProps = {
|
|
213
|
+
fullWidth: input?.fieldProps?.fullWidth ?? true,
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
input.fieldProps = {
|
|
217
|
+
...(input.fieldProps || {}),
|
|
218
|
+
multiline: input?.fieldProps?.multiline ?? true,
|
|
219
|
+
rows: input?.fieldProps?.rows ?? 4,
|
|
220
|
+
};
|
|
221
|
+
break;
|
|
222
|
+
case 'number':
|
|
223
|
+
case 'Number':
|
|
224
|
+
case 'integer':
|
|
225
|
+
input.type = Number;
|
|
226
|
+
break;
|
|
227
|
+
case 'boolean':
|
|
228
|
+
case 'Boolean':
|
|
229
|
+
input.type = Boolean;
|
|
230
|
+
break;
|
|
231
|
+
case 'date':
|
|
232
|
+
case 'Date':
|
|
233
|
+
input.type = Date;
|
|
234
|
+
break;
|
|
235
|
+
case 'custom':
|
|
236
|
+
default:
|
|
237
|
+
input.custom = true;
|
|
238
|
+
DEBUG && console.log('🔧 AttributeToInput - custom type detected, input.component:', input?.component);
|
|
239
|
+
DEBUG && console.log('🔧 AttributeToInput - components available:', Object.keys(components));
|
|
240
|
+
|
|
241
|
+
if(typeof input?.component === "string") {
|
|
242
|
+
const mappedResult = typeComponentMapper( input.component );
|
|
243
|
+
DEBUG && console.log('🔧 AttributeToInput - typeComponentMapper result:', mappedResult);
|
|
244
|
+
input = { ...input, ...mappedResult };
|
|
245
|
+
DEBUG && console.log('🔧 AttributeToInput - after merge, input.component:', input.component);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (options && options.useReadOnlyInputAsTextField && input.readOnly) {
|
|
252
|
+
return (
|
|
253
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
254
|
+
<ComponentWrapper
|
|
255
|
+
key={index}
|
|
256
|
+
label={input.label}
|
|
257
|
+
source={input.listAttribute || input.attribute}
|
|
258
|
+
{...(record && { record: record })}
|
|
259
|
+
method={method}
|
|
260
|
+
attribute={input}
|
|
261
|
+
resourceConfig={resourceConfig}
|
|
262
|
+
>
|
|
263
|
+
<TextInput
|
|
264
|
+
fullWidth
|
|
265
|
+
{...(record && { record: record })}
|
|
266
|
+
key={index}
|
|
267
|
+
label={input.label}
|
|
268
|
+
source={input.listAttribute || input.attribute}
|
|
269
|
+
{...{
|
|
270
|
+
...input.fieldProps,
|
|
271
|
+
editable: false,
|
|
272
|
+
InputProps: {
|
|
273
|
+
readOnly: true,
|
|
274
|
+
endAdornment: (
|
|
275
|
+
<InputAdornment position='start'>
|
|
276
|
+
<Visibility />
|
|
277
|
+
</InputAdornment>
|
|
278
|
+
),
|
|
279
|
+
},
|
|
280
|
+
}}
|
|
281
|
+
/>
|
|
282
|
+
</ComponentWrapper>
|
|
283
|
+
</FunctionFieldWrapper>
|
|
284
|
+
);
|
|
285
|
+
} else if (options && options.readOnlyComponent && input.readOnly) {
|
|
286
|
+
return (
|
|
287
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
288
|
+
<ComponentWrapper
|
|
289
|
+
{...(record && { record: record })}
|
|
290
|
+
method={method}
|
|
291
|
+
attribute={input}
|
|
292
|
+
key={index}
|
|
293
|
+
label={input.label}
|
|
294
|
+
source={input.listAttribute || input.attribute}
|
|
295
|
+
resourceConfig={resourceConfig}
|
|
296
|
+
>
|
|
297
|
+
<options.readOnlyComponent
|
|
298
|
+
fullWidth
|
|
299
|
+
key={index}
|
|
300
|
+
{...(record && { record: record })}
|
|
301
|
+
input={input}
|
|
302
|
+
label={input.label}
|
|
303
|
+
source={input.listAttribute || input.attribute}
|
|
304
|
+
{...{
|
|
305
|
+
...input.fieldProps,
|
|
306
|
+
editable: false,
|
|
307
|
+
InputProps: { readOnly: true },
|
|
308
|
+
}}
|
|
309
|
+
/>
|
|
310
|
+
</ComponentWrapper>
|
|
311
|
+
</FunctionFieldWrapper>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* Force the attribute name to be the label, if not label provided */
|
|
316
|
+
if (!input.label) input.label = input.attribute;
|
|
317
|
+
|
|
318
|
+
if (
|
|
319
|
+
(input.custom && input.component) ||
|
|
320
|
+
(input.type === 'component' && input.component)
|
|
321
|
+
) {
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
325
|
+
<UserAction
|
|
326
|
+
record={record}
|
|
327
|
+
key={index}
|
|
328
|
+
method={mode}
|
|
329
|
+
attribute={input}
|
|
330
|
+
resourceConfig={resourceConfig}
|
|
331
|
+
/>
|
|
332
|
+
</FunctionFieldWrapper>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (Array.isArray(input.type) && input.type.length > 0) {
|
|
337
|
+
const inputType: string | IDashAutoAdminAttribute = input.type[0];
|
|
338
|
+
/* Array of enum values – We use a SelectArrayInput */
|
|
339
|
+
if (isEnum(inputType)) {
|
|
340
|
+
return (
|
|
341
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
342
|
+
<SelectArrayInput
|
|
343
|
+
key={index}
|
|
344
|
+
fullWidth
|
|
345
|
+
label={input.label}
|
|
346
|
+
source={input.attribute}
|
|
347
|
+
choices={enumToChoices(inputType)}
|
|
348
|
+
{...input?.fieldProps}
|
|
349
|
+
onChange={e => {
|
|
350
|
+
if (options?.handleChange) {
|
|
351
|
+
options.handleChange(e);
|
|
352
|
+
}
|
|
353
|
+
if (input.fieldProps?.onChange) {
|
|
354
|
+
input.fieldProps.onChange(e)
|
|
355
|
+
}
|
|
356
|
+
}}
|
|
357
|
+
/>
|
|
358
|
+
</FunctionFieldWrapper>
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
/* Recurse */
|
|
362
|
+
|
|
363
|
+
if (typeof inputType === 'string') {
|
|
364
|
+
const _params = {
|
|
365
|
+
...params, ...(location.hash.match(/\d+/g) || []).map(Number).reduce((acc, curr, currentIndex) => {
|
|
366
|
+
acc[currentIndex] = curr;
|
|
367
|
+
return acc;
|
|
368
|
+
}, {})
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const _inputType = replaceParams(_params, inputType);
|
|
372
|
+
const [reference, sourceName] = _inputType.split('.');
|
|
373
|
+
const safeIfNull = (choice: any) =>
|
|
374
|
+
(choice ? choice[sourceName] : '?') || '??';
|
|
375
|
+
|
|
376
|
+
if (input && input.multiple === false && input.component) {
|
|
377
|
+
const CustomComponent = input.component;
|
|
378
|
+
return (
|
|
379
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
380
|
+
<ReferenceInput
|
|
381
|
+
key={index}
|
|
382
|
+
fullWidth
|
|
383
|
+
allowEmpty
|
|
384
|
+
filter
|
|
385
|
+
pagination={false}
|
|
386
|
+
label={input.label}
|
|
387
|
+
reference={reference}
|
|
388
|
+
source={input.attribute}
|
|
389
|
+
{...input.componentProps}
|
|
390
|
+
>
|
|
391
|
+
<CustomComponent
|
|
392
|
+
optionText={safeIfNull}
|
|
393
|
+
method={method} // edit because its AttributeToInput we need to assure is edit or create
|
|
394
|
+
attribute={input}
|
|
395
|
+
onChange={e => {
|
|
396
|
+
if (options?.handleChange) {
|
|
397
|
+
options.handleChange(e);
|
|
398
|
+
}
|
|
399
|
+
if (input.fieldProps?.onChange) {
|
|
400
|
+
input.fieldProps.onChange(e)
|
|
401
|
+
}
|
|
402
|
+
}}
|
|
403
|
+
resourceConfig={resourceConfig}
|
|
404
|
+
/>
|
|
405
|
+
</ReferenceInput>
|
|
406
|
+
</FunctionFieldWrapper>
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return (
|
|
411
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
412
|
+
<ReferenceArrayInput
|
|
413
|
+
key={index}
|
|
414
|
+
fullWidth
|
|
415
|
+
filter
|
|
416
|
+
pagination={false}
|
|
417
|
+
label={input.label}
|
|
418
|
+
reference={reference}
|
|
419
|
+
source={input.attribute}
|
|
420
|
+
{...input.componentProps}
|
|
421
|
+
>
|
|
422
|
+
<SingleFieldList {...input.fieldProps}>
|
|
423
|
+
<ChipField source={sourceName} />
|
|
424
|
+
</SingleFieldList>
|
|
425
|
+
</ReferenceArrayInput>
|
|
426
|
+
</FunctionFieldWrapper>
|
|
427
|
+
);
|
|
428
|
+
} else {
|
|
429
|
+
const inputTypeArray = input.type as IDashAutoAdminAttribute[];
|
|
430
|
+
|
|
431
|
+
return (
|
|
432
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
433
|
+
<ArrayInput
|
|
434
|
+
key={index}
|
|
435
|
+
label={input.label}
|
|
436
|
+
source={input.attribute}
|
|
437
|
+
{...input.componentProps}
|
|
438
|
+
>
|
|
439
|
+
<SimpleFormIterator>
|
|
440
|
+
{inputTypeArray.map((attribute, idx) =>
|
|
441
|
+
AttributeToInput(method, resourceConfig, attribute, idx),
|
|
442
|
+
)}
|
|
443
|
+
</SimpleFormIterator>
|
|
444
|
+
</ArrayInput>
|
|
445
|
+
</FunctionFieldWrapper>
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (input && input.type === ImageInput) {
|
|
451
|
+
return (
|
|
452
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
453
|
+
<ImageInput
|
|
454
|
+
key={index}
|
|
455
|
+
placeholder={'Arrástre una imágen o haga click aquí para seleccionar'}
|
|
456
|
+
source={input.attribute}
|
|
457
|
+
label={input.label}
|
|
458
|
+
accept='image/*'
|
|
459
|
+
{...input.fieldProps}
|
|
460
|
+
>
|
|
461
|
+
<ImageField source='src' title='title' />
|
|
462
|
+
</ImageInput>
|
|
463
|
+
</FunctionFieldWrapper>
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (input && input.type === FileInput) {
|
|
468
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
469
|
+
<FileInput
|
|
470
|
+
key={index}
|
|
471
|
+
placeholder={'Arrástre un archivo o haga click aquí para seleccionar'}
|
|
472
|
+
source={input.attribute}
|
|
473
|
+
label={input.label}
|
|
474
|
+
{...input.fieldProps}
|
|
475
|
+
>
|
|
476
|
+
<FileField source='src' title='title' />
|
|
477
|
+
</FileInput>
|
|
478
|
+
</FunctionFieldWrapper>;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/* Special cases – Passing strings, passing enums */
|
|
482
|
+
if (typeof input.type === 'string') {
|
|
483
|
+
// Handle 'select' type with static options (no API call needed)
|
|
484
|
+
if (input.type === 'select' && Array.isArray(input.options) && input.options.length > 0) {
|
|
485
|
+
const choices = input.options.map((opt: { id: any; name: any }) => ({
|
|
486
|
+
id: opt.id,
|
|
487
|
+
name: opt.name,
|
|
488
|
+
}));
|
|
489
|
+
|
|
490
|
+
return (
|
|
491
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
492
|
+
<SelectInput
|
|
493
|
+
key={index}
|
|
494
|
+
fullWidth
|
|
495
|
+
label={input.label}
|
|
496
|
+
source={input.listAttribute || input.attribute}
|
|
497
|
+
choices={choices}
|
|
498
|
+
{...input.fieldProps}
|
|
499
|
+
onChange={e => {
|
|
500
|
+
if (options?.handleChange) {
|
|
501
|
+
options.handleChange(e);
|
|
502
|
+
}
|
|
503
|
+
if (input.fieldProps?.onChange) {
|
|
504
|
+
input.fieldProps.onChange(e);
|
|
505
|
+
}
|
|
506
|
+
}}
|
|
507
|
+
{...input.componentProps}
|
|
508
|
+
/>
|
|
509
|
+
</FunctionFieldWrapper>
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Handle 'select' type without options - skip rendering to avoid API errors
|
|
514
|
+
if (input.type === 'select' && (!input.options || input.options.length === 0)) {
|
|
515
|
+
console.warn(`Select field "${input.attribute}" has no options defined. Skipping render.`);
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const _params = {
|
|
520
|
+
...params, ...(location.pathname.match(/\d+/g) || []).map(Number).reduce((acc, curr, currentIndex) => {
|
|
521
|
+
acc[currentIndex] = curr;
|
|
522
|
+
return acc;
|
|
523
|
+
}, {})
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
const _inputType = replaceParams(_params, input.type);
|
|
527
|
+
const [reference, sourceName] = _inputType.split('.');
|
|
528
|
+
const CustomComponent = input.component || SelectInput;
|
|
529
|
+
|
|
530
|
+
if (input && input.multiple === false) {
|
|
531
|
+
return (
|
|
532
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
533
|
+
<ReferenceInput
|
|
534
|
+
key={index}
|
|
535
|
+
allowEmpty
|
|
536
|
+
filters
|
|
537
|
+
label={input.label}
|
|
538
|
+
source={input.listAttribute || input.attribute}
|
|
539
|
+
reference={reference}
|
|
540
|
+
sort={{ field: sourceName, order: 'ASC' }}
|
|
541
|
+
{...input.componentProps}
|
|
542
|
+
>
|
|
543
|
+
<CustomComponent
|
|
544
|
+
optionText={sourceName}
|
|
545
|
+
method={method} // edit because its AttributeToInput
|
|
546
|
+
attribute={input}
|
|
547
|
+
label={input?.label || ''}
|
|
548
|
+
{...input.fieldProps}
|
|
549
|
+
onChange={e => {
|
|
550
|
+
if (options?.handleChange) {
|
|
551
|
+
options.handleChange(e);
|
|
552
|
+
}
|
|
553
|
+
if (input.fieldProps?.onChange) {
|
|
554
|
+
input.fieldProps.onChange(e)
|
|
555
|
+
}
|
|
556
|
+
}}
|
|
557
|
+
resourceConfig={resourceConfig}
|
|
558
|
+
/>
|
|
559
|
+
</ReferenceInput>
|
|
560
|
+
</FunctionFieldWrapper>
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return (
|
|
565
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
566
|
+
<ReferenceArrayInput
|
|
567
|
+
key={index}
|
|
568
|
+
reference={reference}
|
|
569
|
+
source={input.listAttribute || input.attribute}
|
|
570
|
+
{...input.componentProps}
|
|
571
|
+
>
|
|
572
|
+
<SelectArrayInput
|
|
573
|
+
optionText={sourceName}
|
|
574
|
+
fullWidth
|
|
575
|
+
label={input?.label || ''}
|
|
576
|
+
{...input.fieldProps}
|
|
577
|
+
onChange={e => {
|
|
578
|
+
if (options?.handleChange) {
|
|
579
|
+
options.handleChange(e);
|
|
580
|
+
}
|
|
581
|
+
if (input.fieldProps?.onChange) {
|
|
582
|
+
input.fieldProps.onChange(e)
|
|
583
|
+
}
|
|
584
|
+
}}
|
|
585
|
+
/>
|
|
586
|
+
</ReferenceArrayInput>
|
|
587
|
+
</FunctionFieldWrapper>
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
switch (input.type) {
|
|
592
|
+
case Number:
|
|
593
|
+
return (
|
|
594
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
595
|
+
<NumberInput
|
|
596
|
+
key={index}
|
|
597
|
+
fullWidth
|
|
598
|
+
label={input.label}
|
|
599
|
+
source={input.attribute}
|
|
600
|
+
{...input.fieldProps}
|
|
601
|
+
onChange={e => {
|
|
602
|
+
if (options?.handleChange) {
|
|
603
|
+
options.handleChange(e);
|
|
604
|
+
}
|
|
605
|
+
if (input.fieldProps?.onChange) {
|
|
606
|
+
input.fieldProps.onChange(e)
|
|
607
|
+
}
|
|
608
|
+
}}
|
|
609
|
+
/>
|
|
610
|
+
</FunctionFieldWrapper>
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
case Boolean:
|
|
614
|
+
return <FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
615
|
+
<div>
|
|
616
|
+
{input?.showLabel !== false && (
|
|
617
|
+
<InputLabel htmlFor={input.listAttribute || input.attribute}>
|
|
618
|
+
{input.label}
|
|
619
|
+
</InputLabel>
|
|
620
|
+
)}
|
|
621
|
+
<BooleanInput
|
|
622
|
+
record={record}
|
|
623
|
+
key={index}
|
|
624
|
+
id={input.listAttribute || input.attribute}
|
|
625
|
+
label={input.label}
|
|
626
|
+
source={input.listAttribute || input.attribute}
|
|
627
|
+
{...input.fieldProps}
|
|
628
|
+
onChange={e => {
|
|
629
|
+
if (options?.handleChange) {
|
|
630
|
+
options.handleChange(e);
|
|
631
|
+
}
|
|
632
|
+
if (input.fieldProps?.onChange) {
|
|
633
|
+
input.fieldProps.onChange(e)
|
|
634
|
+
}
|
|
635
|
+
}}
|
|
636
|
+
/>
|
|
637
|
+
</div>
|
|
638
|
+
</FunctionFieldWrapper>
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
case Date:
|
|
642
|
+
return input.fieldProps && input.fieldProps.showTime ? (
|
|
643
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
644
|
+
<DateTimeInput
|
|
645
|
+
key={index}
|
|
646
|
+
label={input.label}
|
|
647
|
+
source={input.attribute}
|
|
648
|
+
{...input.fieldProps}
|
|
649
|
+
/>
|
|
650
|
+
</FunctionFieldWrapper>
|
|
651
|
+
) : (
|
|
652
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
653
|
+
<DateInput
|
|
654
|
+
key={index}
|
|
655
|
+
label={input.label}
|
|
656
|
+
source={input.attribute}
|
|
657
|
+
{...input.fieldProps}
|
|
658
|
+
onChange={e => {
|
|
659
|
+
if (options?.handleChange) {
|
|
660
|
+
options.handleChange(e);
|
|
661
|
+
}
|
|
662
|
+
if (input.fieldProps?.onChange) {
|
|
663
|
+
input.fieldProps.onChange(e)
|
|
664
|
+
}
|
|
665
|
+
}}
|
|
666
|
+
/>
|
|
667
|
+
</FunctionFieldWrapper>
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
if (isEnum(input.type)) {
|
|
671
|
+
return (
|
|
672
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
673
|
+
<SelectInput
|
|
674
|
+
key={index}
|
|
675
|
+
label={input.label}
|
|
676
|
+
source={input.attribute}
|
|
677
|
+
choices={enumToChoices(input.type)}
|
|
678
|
+
InputProps={input.fieldOptions}
|
|
679
|
+
onChange={e => {
|
|
680
|
+
if (options?.handleChange) {
|
|
681
|
+
options.handleChange(e);
|
|
682
|
+
}
|
|
683
|
+
if (input.fieldProps?.onChange) {
|
|
684
|
+
input.fieldProps.onChange(e)
|
|
685
|
+
}
|
|
686
|
+
}}
|
|
687
|
+
/>
|
|
688
|
+
</FunctionFieldWrapper>
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (input.isPassword) {
|
|
693
|
+
const passwordProps = {
|
|
694
|
+
key: index,
|
|
695
|
+
label: input.label,
|
|
696
|
+
source: input.attribute,
|
|
697
|
+
...(input.slotProps ? { slotProps: input.slotProps } : {})
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
return (
|
|
701
|
+
<FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
702
|
+
<PasswordInput {...passwordProps} />
|
|
703
|
+
</FunctionFieldWrapper>
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
const textFieldProps = {
|
|
707
|
+
label: input.label,
|
|
708
|
+
source: input.listAttribute || input.attribute,
|
|
709
|
+
...input.fieldProps,
|
|
710
|
+
...input.slotProps ? { slotProps: input.slotProps } : {},
|
|
711
|
+
onChange: (e) => {
|
|
712
|
+
if (options?.handleChange) {
|
|
713
|
+
options.handleChange(e);
|
|
714
|
+
}
|
|
715
|
+
if (input.fieldProps?.onChange) {
|
|
716
|
+
input.fieldProps.onChange(e)
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
return <FunctionFieldWrapper index={index} method={mode} input={input}>
|
|
722
|
+
<TextInput
|
|
723
|
+
{...textFieldProps}
|
|
724
|
+
/>
|
|
725
|
+
</FunctionFieldWrapper>
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
export default AttributeToInput;
|