@fovestta2/web-react 1.2.1 → 1.2.3
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/AddUpdateForm.d.ts +9 -0
- package/dist/components/AddUpdateForm.js +458 -89
- package/dist/components/FvDropdown.js +17 -16
- package/dist/components/FvEmailField.js +12 -14
- package/dist/components/FvEntryField.js +12 -17
- package/dist/components/FvMasterScreen.d.ts +78 -0
- package/dist/components/FvMasterScreen.js +317 -0
- package/dist/components/FvNumberField.js +12 -16
- package/dist/components/FvPasswordField.js +12 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +3 -3
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// import React, { useState, useEffect } from 'react';
|
|
3
|
+
// import { ValidationSchema } from '@fovestta2/validation-engine';
|
|
2
4
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
5
|
if (k2 === undefined) k2 = k;
|
|
4
6
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -24,6 +26,308 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
26
|
};
|
|
25
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
28
|
exports.AddUpdateForm = void 0;
|
|
29
|
+
// // Import all Fv controls
|
|
30
|
+
// import { FvEntryField } from './FvEntryField';
|
|
31
|
+
// import { FvDropdown } from './FvDropdown';
|
|
32
|
+
// import { FvNumberField } from './FvNumberField';
|
|
33
|
+
// import { FvDateField } from './FvDateField';
|
|
34
|
+
// import { FvMonthYearField } from './FvMonthYearField';
|
|
35
|
+
// import { FvFileSelector } from './FvFileSelector';
|
|
36
|
+
// import { FvImageSelector } from './FvImageSelector';
|
|
37
|
+
// import { FvRichTextEditor } from './FvRichTextEditor';
|
|
38
|
+
// import { FvNameCode } from './FvNameCode';
|
|
39
|
+
// import { FvPhoneField } from './FvPhoneField';
|
|
40
|
+
// import { FvUanField } from './FvUanField';
|
|
41
|
+
// import { FvPfField } from './FvPfField';
|
|
42
|
+
// import { FvEsiField } from './FvEsiField';
|
|
43
|
+
// import { FvIfscField } from './FvIfscField';
|
|
44
|
+
// import { FvMicrField } from './FvMicrField';
|
|
45
|
+
// import { FvIbanField } from './FvIbanField';
|
|
46
|
+
// import { FvEmailField } from './FvEmailField';
|
|
47
|
+
// import { FvPasswordField } from './FvPasswordField';
|
|
48
|
+
// import { FvToggle } from './FvToggle';
|
|
49
|
+
// import { FvCheckbox } from './FvCheckbox';
|
|
50
|
+
// import { FvRadioGroup } from './FvRadioGroup';
|
|
51
|
+
// import { FvServicePeriod } from './FvServicePeriod';
|
|
52
|
+
// import { FvDocumentField } from './FvDocumentField';
|
|
53
|
+
// import { FvTimeField } from './FvTimeField';
|
|
54
|
+
// export type FieldType = 'text' | 'email' | 'number' | 'select' | 'name-code' | 'checkbox' | 'textarea' | 'date' | 'password' | 'radio' | 'file' | 'month-year' | 'phone' | 'uan' | 'pf' | 'esi' | 'ifsc' | 'micr' | 'iban' | 'service-period' | 'scan' | 'document' | 'time' | 'toggle';
|
|
55
|
+
// export type ValidationType = 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'min' | 'max' | 'custom' | 'duplicate' | 'passwordComplexity';
|
|
56
|
+
// export interface FieldValidation {
|
|
57
|
+
// type: ValidationType;
|
|
58
|
+
// value?: any;
|
|
59
|
+
// message?: string;
|
|
60
|
+
// errorKey?: string;
|
|
61
|
+
// params?: any;
|
|
62
|
+
// }
|
|
63
|
+
// export interface FormColumn {
|
|
64
|
+
// name: string;
|
|
65
|
+
// label: string;
|
|
66
|
+
// type: FieldType;
|
|
67
|
+
// placeholder?: string;
|
|
68
|
+
// required?: boolean;
|
|
69
|
+
// options?: { label: string; value: any }[];
|
|
70
|
+
// validations?: FieldValidation[];
|
|
71
|
+
// value?: any;
|
|
72
|
+
// disabled?: boolean | ((formData: any) => boolean);
|
|
73
|
+
// className?: string;
|
|
74
|
+
// hidden?: boolean;
|
|
75
|
+
// hint?: string;
|
|
76
|
+
// colSpan?: number;
|
|
77
|
+
// onChange?: (value: any, formData: any) => void;
|
|
78
|
+
// accept?: string;
|
|
79
|
+
// filePreview?: boolean;
|
|
80
|
+
// showTimePicker?: boolean;
|
|
81
|
+
// allowAlphabetsOnly?: boolean;
|
|
82
|
+
// maxLength?: number;
|
|
83
|
+
// layout?: 'vertical' | 'horizontal';
|
|
84
|
+
// servicePeriodConfig?: { startField: string; endField: string };
|
|
85
|
+
// }
|
|
86
|
+
// export interface FormSection {
|
|
87
|
+
// title?: string;
|
|
88
|
+
// fields: FormColumn[];
|
|
89
|
+
// isRepeatable?: boolean;
|
|
90
|
+
// sectionKey?: string;
|
|
91
|
+
// }
|
|
92
|
+
// export interface FormConfig {
|
|
93
|
+
// sections: FormSection[];
|
|
94
|
+
// submitLabel?: string;
|
|
95
|
+
// resetLabel?: string;
|
|
96
|
+
// onSubmit: (data: any) => void;
|
|
97
|
+
// onReset?: () => void;
|
|
98
|
+
// onCancel: () => void;
|
|
99
|
+
// cancelLabel?: string;
|
|
100
|
+
// formTitle?: string;
|
|
101
|
+
// maxColsPerRow?: number;
|
|
102
|
+
// disableSubmit?: boolean;
|
|
103
|
+
// disableCancel?: boolean;
|
|
104
|
+
// hideSubmit?: boolean;
|
|
105
|
+
// hideCancel?: boolean;
|
|
106
|
+
// }
|
|
107
|
+
// export interface AddUpdateFormProps {
|
|
108
|
+
// config: FormConfig;
|
|
109
|
+
// }
|
|
110
|
+
// export const AddUpdateForm: React.FC<AddUpdateFormProps> = ({ config }) => {
|
|
111
|
+
// const [formData, setFormData] = useState<Record<string, any>>({});
|
|
112
|
+
// useEffect(() => {
|
|
113
|
+
// // Initialize form structure
|
|
114
|
+
// const initialData: Record<string, any> = {};
|
|
115
|
+
// config.sections.forEach((section) => {
|
|
116
|
+
// if (section.isRepeatable && section.sectionKey) {
|
|
117
|
+
// // Init as array with one empty object
|
|
118
|
+
// const groupObj: Record<string, any> = {};
|
|
119
|
+
// section.fields.forEach((col) => {
|
|
120
|
+
// groupObj[col.name] = col.value || '';
|
|
121
|
+
// });
|
|
122
|
+
// initialData[section.sectionKey] = [groupObj];
|
|
123
|
+
// } else {
|
|
124
|
+
// section.fields.forEach((col) => {
|
|
125
|
+
// initialData[col.name] = col.value || '';
|
|
126
|
+
// });
|
|
127
|
+
// }
|
|
128
|
+
// });
|
|
129
|
+
// setFormData(initialData);
|
|
130
|
+
// }, [config]);
|
|
131
|
+
// const handleFieldChange = (name: string, value: any, sectionKey?: string, index?: number) => {
|
|
132
|
+
// setFormData((prev) => {
|
|
133
|
+
// const copy = { ...prev };
|
|
134
|
+
// if (sectionKey && index !== undefined) {
|
|
135
|
+
// copy[sectionKey] = [...(copy[sectionKey] || [])];
|
|
136
|
+
// copy[sectionKey][index] = { ...copy[sectionKey][index], [name]: value };
|
|
137
|
+
// } else {
|
|
138
|
+
// copy[name] = value;
|
|
139
|
+
// }
|
|
140
|
+
// return copy;
|
|
141
|
+
// });
|
|
142
|
+
// // We do a delayed trigger to on change to simulate reactive form passing state
|
|
143
|
+
// setTimeout(() => {
|
|
144
|
+
// const col = findColumn(name, sectionKey);
|
|
145
|
+
// if (col && col.onChange) {
|
|
146
|
+
// // Needs recent state
|
|
147
|
+
// setFormData((latestState) => {
|
|
148
|
+
// col.onChange!(value, latestState);
|
|
149
|
+
// return latestState;
|
|
150
|
+
// });
|
|
151
|
+
// }
|
|
152
|
+
// }, 0);
|
|
153
|
+
// };
|
|
154
|
+
// const findColumn = (name: string, sectionKey?: string): FormColumn | undefined => {
|
|
155
|
+
// for (const section of config.sections) {
|
|
156
|
+
// if (sectionKey && section.sectionKey !== sectionKey) continue;
|
|
157
|
+
// const col = section.fields.find(c => c.name === name);
|
|
158
|
+
// if (col) return col;
|
|
159
|
+
// }
|
|
160
|
+
// return undefined;
|
|
161
|
+
// };
|
|
162
|
+
// const addSectionItem = (sectionKey: string, fields: FormColumn[]) => {
|
|
163
|
+
// setFormData((prev) => {
|
|
164
|
+
// const copy = { ...prev };
|
|
165
|
+
// const groupObj: Record<string, any> = {};
|
|
166
|
+
// fields.forEach((col) => { groupObj[col.name] = col.value || ''; });
|
|
167
|
+
// copy[sectionKey] = [...(copy[sectionKey] || []), groupObj];
|
|
168
|
+
// return copy;
|
|
169
|
+
// });
|
|
170
|
+
// };
|
|
171
|
+
// const removeSectionItem = (sectionKey: string, index: number) => {
|
|
172
|
+
// setFormData((prev) => {
|
|
173
|
+
// const copy = { ...prev };
|
|
174
|
+
// if (copy[sectionKey] && copy[sectionKey].length > 1) {
|
|
175
|
+
// const arr = [...copy[sectionKey]];
|
|
176
|
+
// arr.splice(index, 1);
|
|
177
|
+
// copy[sectionKey] = arr;
|
|
178
|
+
// }
|
|
179
|
+
// return copy;
|
|
180
|
+
// });
|
|
181
|
+
// };
|
|
182
|
+
// const handleSubmit = (e: React.FormEvent) => {
|
|
183
|
+
// e.preventDefault();
|
|
184
|
+
// config.onSubmit(formData);
|
|
185
|
+
// };
|
|
186
|
+
// const getSchema = (column: FormColumn): ValidationSchema => {
|
|
187
|
+
// const rules: any[] = [];
|
|
188
|
+
// const errorPriority: string[] = [];
|
|
189
|
+
// if (column.validations) {
|
|
190
|
+
// column.validations.forEach((v) => {
|
|
191
|
+
// if (v.type === 'required') { rules.push({ name: 'required', params: { enabled: true }, errorKey: 'ERR_REQUIRED', message: v.message }); errorPriority.push('required'); }
|
|
192
|
+
// if (v.type === 'email') { rules.push({ name: 'regex', params: { pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' }, errorKey: 'ERR_REGEX_MISMATCH', message: v.message }); errorPriority.push('regex'); }
|
|
193
|
+
// if (v.type === 'minLength') { rules.push({ name: 'minLength', params: { value: v.value }, errorKey: 'ERR_MIN_LENGTH', message: v.message }); errorPriority.push('minLength'); }
|
|
194
|
+
// if (v.type === 'maxLength') { rules.push({ name: 'maxLength', params: { value: v.value }, errorKey: 'ERR_MAX_LENGTH', message: v.message }); errorPriority.push('maxLength'); }
|
|
195
|
+
// if (v.type === 'pattern') { rules.push({ name: 'regex', params: { pattern: v.value }, errorKey: 'ERR_REGEX_MISMATCH', message: v.message }); errorPriority.push('regex'); }
|
|
196
|
+
// });
|
|
197
|
+
// }
|
|
198
|
+
// return { controlType: 'EntryField' as any, rules, errorPriority };
|
|
199
|
+
// };
|
|
200
|
+
// const isFieldDisabled = (column: FormColumn): boolean => {
|
|
201
|
+
// if (typeof column.disabled === 'function') {
|
|
202
|
+
// return column.disabled(formData);
|
|
203
|
+
// }
|
|
204
|
+
// return column.disabled || false;
|
|
205
|
+
// };
|
|
206
|
+
// const renderField = (column: FormColumn, value: any, sectionKey?: string, index?: number) => {
|
|
207
|
+
// const disabled = isFieldDisabled(column);
|
|
208
|
+
// const schema = getSchema(column);
|
|
209
|
+
// const onChange = (val: any) => handleFieldChange(column.name, val, sectionKey, index);
|
|
210
|
+
// if (column.hidden) return null;
|
|
211
|
+
// switch (column.type) {
|
|
212
|
+
// case 'text':
|
|
213
|
+
// return <FvEntryField label={column.label} placeholder={column.placeholder} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
214
|
+
// case 'email':
|
|
215
|
+
// return <FvEmailField label={column.label} placeholder={column.placeholder} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
216
|
+
// case 'password':
|
|
217
|
+
// return <FvPasswordField label={column.label} placeholder={column.placeholder} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
218
|
+
// case 'number':
|
|
219
|
+
// return <FvNumberField label={column.label} placeholder={column.placeholder} value={value || null} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
220
|
+
// case 'select':
|
|
221
|
+
// return <FvDropdown label={column.label} placeholder={column.placeholder} options={column.options || []} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
222
|
+
// case 'checkbox':
|
|
223
|
+
// return <FvCheckbox label={column.label} value={value || false} disabled={disabled} onChange={onChange} />;
|
|
224
|
+
// case 'toggle':
|
|
225
|
+
// return <FvToggle label={column.label} value={value || false} disabled={disabled} onChange={onChange} />;
|
|
226
|
+
// case 'radio':
|
|
227
|
+
// return <FvRadioGroup label={column.label} options={column.options || []} value={value || ''} disabled={disabled} layout={column.layout} onChange={onChange} />;
|
|
228
|
+
// case 'date':
|
|
229
|
+
// return <FvDateField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
230
|
+
// case 'month-year':
|
|
231
|
+
// return <FvMonthYearField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
232
|
+
// case 'textarea':
|
|
233
|
+
// return <FvRichTextEditor label={column.label} placeholder={column.placeholder} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
234
|
+
// case 'file':
|
|
235
|
+
// if (column.accept?.startsWith('image') || column.filePreview) {
|
|
236
|
+
// return <FvImageSelector label={column.label} placeholder={column.placeholder} value={value || null} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
237
|
+
// }
|
|
238
|
+
// return <FvFileSelector label={column.label} placeholder={column.placeholder} accept={column.accept} value={value || null} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
239
|
+
// case 'name-code':
|
|
240
|
+
// return <FvNameCode label={column.label} placeholder={column.placeholder} options={column.options?.map(o => ({ code: o.value, name: o.label, value: o.value })) || []} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
241
|
+
// case 'phone':
|
|
242
|
+
// return <FvPhoneField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
243
|
+
// case 'uan':
|
|
244
|
+
// return <FvUanField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
245
|
+
// case 'pf':
|
|
246
|
+
// return <FvPfField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
247
|
+
// case 'esi':
|
|
248
|
+
// return <FvEsiField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
249
|
+
// case 'ifsc':
|
|
250
|
+
// return <FvIfscField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
251
|
+
// case 'micr':
|
|
252
|
+
// return <FvMicrField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
253
|
+
// case 'iban':
|
|
254
|
+
// return <FvIbanField label={column.label} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
255
|
+
// case 'document':
|
|
256
|
+
// return <FvDocumentField label={column.label} placeholder={column.placeholder} accept={column.accept} value={value || null} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
257
|
+
// case 'time':
|
|
258
|
+
// return <FvTimeField label={column.label} placeholder={column.placeholder} value={value || ''} schema={schema} disabled={disabled} onChange={onChange} />;
|
|
259
|
+
// case 'service-period':
|
|
260
|
+
// // Not perfectly mapped due to pure group dependency, simple implementation shown for continuity
|
|
261
|
+
// return <FvEntryField label={column.label} value={value || ''} disabled={true} onChange={onChange} />;
|
|
262
|
+
// default:
|
|
263
|
+
// return null; // unsupported
|
|
264
|
+
// }
|
|
265
|
+
// };
|
|
266
|
+
// return (
|
|
267
|
+
// <div style={{ background: '#f5f5f5', padding: '15px 20px', borderRadius: '8px', maxWidth: '100%', boxSizing: 'border-box' }}>
|
|
268
|
+
// {config.formTitle && (
|
|
269
|
+
// <div style={{ marginBottom: '15px' }}>
|
|
270
|
+
// <h2 style={{ margin: 0, fontSize: '20px', fontWeight: 700, color: '#303030' }}>{config.formTitle}</h2>
|
|
271
|
+
// </div>
|
|
272
|
+
// )}
|
|
273
|
+
// <form onSubmit={handleSubmit} style={{ background: '#fff', padding: '15px', borderRadius: '6px', boxShadow: '0 1px 3px rgba(0,0,0,0.1)' }}>
|
|
274
|
+
// {config.sections.map((section, sIdx) => (
|
|
275
|
+
// <div key={sIdx} style={{ marginBottom: '20px' }}>
|
|
276
|
+
// {section.title && <h3 style={{ fontSize: '16px', fontWeight: 700, color: '#303030', marginBottom: '16px', textTransform: 'uppercase' }}>{section.title}</h3>}
|
|
277
|
+
// {section.isRepeatable && section.sectionKey ? (
|
|
278
|
+
// (formData[section.sectionKey] || []).map((group: any, idx: number) => (
|
|
279
|
+
// <div key={idx} style={{ position: 'relative', border: '1px solid #eee', borderRadius: '8px', padding: '20px 80px 20px 20px', marginBottom: '15px', background: '#fafafa' }}>
|
|
280
|
+
// <div style={{ position: 'absolute', top: '15px', right: '15px', display: 'flex', gap: '8px' }}>
|
|
281
|
+
// <button type="button" onClick={() => addSectionItem(section.sectionKey!, section.fields)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: '20px', color: '#2ecc71' }}>⊕</button>
|
|
282
|
+
// {(formData[section.sectionKey!] || []).length > 1 && (
|
|
283
|
+
// <button type="button" onClick={() => removeSectionItem(section.sectionKey!, idx)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: '20px', color: '#e74c3c' }}>⊗</button>
|
|
284
|
+
// )}
|
|
285
|
+
// </div>
|
|
286
|
+
// <div style={{ display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(200px, 1fr))`, gap: '16px' }}>
|
|
287
|
+
// {section.fields.map((col, cIdx) => (
|
|
288
|
+
// <div key={cIdx} style={{ gridColumn: `span ${col.colSpan || 1}` }}>
|
|
289
|
+
// {renderField(col, group[col.name], section.sectionKey, idx)}
|
|
290
|
+
// </div>
|
|
291
|
+
// ))}
|
|
292
|
+
// </div>
|
|
293
|
+
// </div>
|
|
294
|
+
// ))
|
|
295
|
+
// ) : (
|
|
296
|
+
// <div style={{ display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(200px, 1fr))`, gap: '16px' }}>
|
|
297
|
+
// {section.fields.map((col, cIdx) => (
|
|
298
|
+
// <div key={cIdx} style={{ gridColumn: `span ${col.colSpan || 1}` }}>
|
|
299
|
+
// {renderField(col, formData[col.name])}
|
|
300
|
+
// </div>
|
|
301
|
+
// ))}
|
|
302
|
+
// </div>
|
|
303
|
+
// )}
|
|
304
|
+
// </div>
|
|
305
|
+
// ))}
|
|
306
|
+
// <div style={{ display: 'flex', justifyContent: 'space-between', gap: '12px', marginTop: '20px' }}>
|
|
307
|
+
// {!config.hideSubmit && (
|
|
308
|
+
// <button
|
|
309
|
+
// type="submit"
|
|
310
|
+
// disabled={config.disableSubmit}
|
|
311
|
+
// style={{ padding: '8px 24px', background: config.disableSubmit ? '#bdc3c7' : '#006aff', color: '#fff', border: 'none', borderRadius: '7px', fontWeight: 600, cursor: config.disableSubmit ? 'not-allowed' : 'pointer' }}
|
|
312
|
+
// >
|
|
313
|
+
// {config.submitLabel || 'Save'}
|
|
314
|
+
// </button>
|
|
315
|
+
// )}
|
|
316
|
+
// {!config.hideCancel && (
|
|
317
|
+
// <button
|
|
318
|
+
// type="button"
|
|
319
|
+
// disabled={config.disableCancel}
|
|
320
|
+
// onClick={config.onCancel}
|
|
321
|
+
// style={{ padding: '8px 24px', background: '#303030', color: '#fff', border: 'none', borderRadius: '7px', fontWeight: 600, cursor: config.disableCancel ? 'not-allowed' : 'pointer' }}
|
|
322
|
+
// >
|
|
323
|
+
// {config.cancelLabel || 'Cancel'}
|
|
324
|
+
// </button>
|
|
325
|
+
// )}
|
|
326
|
+
// </div>
|
|
327
|
+
// </form>
|
|
328
|
+
// </div>
|
|
329
|
+
// );
|
|
330
|
+
// };
|
|
27
331
|
const react_1 = __importStar(require("react"));
|
|
28
332
|
// Import all Fv controls
|
|
29
333
|
const FvEntryField_1 = require("./FvEntryField");
|
|
@@ -49,24 +353,90 @@ const FvCheckbox_1 = require("./FvCheckbox");
|
|
|
49
353
|
const FvRadioGroup_1 = require("./FvRadioGroup");
|
|
50
354
|
const FvDocumentField_1 = require("./FvDocumentField");
|
|
51
355
|
const FvTimeField_1 = require("./FvTimeField");
|
|
52
|
-
|
|
356
|
+
// ─── Modal overlay styles ────────────────────────────────────────────────────
|
|
357
|
+
const overlayStyle = {
|
|
358
|
+
position: 'fixed',
|
|
359
|
+
inset: 0,
|
|
360
|
+
background: 'rgba(0, 0, 0, 0.4)',
|
|
361
|
+
display: 'flex',
|
|
362
|
+
alignItems: 'center',
|
|
363
|
+
justifyContent: 'center',
|
|
364
|
+
zIndex: 1000,
|
|
365
|
+
};
|
|
366
|
+
const modalBoxStyle = {
|
|
367
|
+
background: '#ffffff',
|
|
368
|
+
borderRadius: '12px',
|
|
369
|
+
boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
|
|
370
|
+
width: '100%',
|
|
371
|
+
maxWidth: '540px',
|
|
372
|
+
backgroundColor: '#fff',
|
|
373
|
+
position: 'relative',
|
|
374
|
+
padding: '30px 24px',
|
|
375
|
+
};
|
|
376
|
+
const closeBtnStyle = {
|
|
377
|
+
position: 'absolute',
|
|
378
|
+
top: '16px',
|
|
379
|
+
right: '16px',
|
|
380
|
+
background: 'none',
|
|
381
|
+
border: 'none',
|
|
382
|
+
cursor: 'pointer',
|
|
383
|
+
fontSize: '20px',
|
|
384
|
+
color: '#666',
|
|
385
|
+
padding: '4px',
|
|
386
|
+
};
|
|
387
|
+
const modalTitleStyle = {
|
|
388
|
+
margin: '0 0 24px 0',
|
|
389
|
+
fontSize: '22px',
|
|
390
|
+
fontWeight: 700,
|
|
391
|
+
color: '#1a1a1a',
|
|
392
|
+
};
|
|
393
|
+
const getSubmitButtonStyle = (disabled) => ({
|
|
394
|
+
width: '100%',
|
|
395
|
+
padding: '12px',
|
|
396
|
+
background: disabled ? '#8cc1f7' : '#005bb5',
|
|
397
|
+
color: '#ffffff',
|
|
398
|
+
border: 'none',
|
|
399
|
+
borderRadius: '8px',
|
|
400
|
+
fontWeight: 600,
|
|
401
|
+
fontSize: '16px',
|
|
402
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
403
|
+
marginTop: '24px',
|
|
404
|
+
});
|
|
405
|
+
// ── Standalone (non-modal) wrapper styles ───────────────────────────────────
|
|
406
|
+
const standaloneWrapStyle = {
|
|
407
|
+
background: '#ffffff',
|
|
408
|
+
borderRadius: '8px',
|
|
409
|
+
boxShadow: '0 1px 4px rgba(0,0,0,0.08)',
|
|
410
|
+
padding: '24px',
|
|
411
|
+
};
|
|
412
|
+
// ── Section title ────────────────────────────────────────────────────────────
|
|
413
|
+
const sectionTitleStyle = {
|
|
414
|
+
fontSize: '14px',
|
|
415
|
+
fontWeight: 600,
|
|
416
|
+
color: '#555',
|
|
417
|
+
marginBottom: '16px',
|
|
418
|
+
};
|
|
419
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
420
|
+
const buildGridStyle = (maxCols) => ({
|
|
421
|
+
display: 'grid',
|
|
422
|
+
gridTemplateColumns: `repeat(${maxCols}, minmax(0, 1fr))`,
|
|
423
|
+
gap: '16px',
|
|
424
|
+
});
|
|
425
|
+
// ── Component ────────────────────────────────────────────────────────────────
|
|
426
|
+
const AddUpdateForm = ({ config, asModal = false, }) => {
|
|
427
|
+
var _a;
|
|
53
428
|
const [formData, setFormData] = (0, react_1.useState)({});
|
|
429
|
+
const maxCols = (_a = config.maxColsPerRow) !== null && _a !== void 0 ? _a : 3;
|
|
54
430
|
(0, react_1.useEffect)(() => {
|
|
55
|
-
// Initialize form structure
|
|
56
431
|
const initialData = {};
|
|
57
432
|
config.sections.forEach((section) => {
|
|
58
433
|
if (section.isRepeatable && section.sectionKey) {
|
|
59
|
-
// Init as array with one empty object
|
|
60
434
|
const groupObj = {};
|
|
61
|
-
section.fields.forEach((col) => {
|
|
62
|
-
groupObj[col.name] = col.value || '';
|
|
63
|
-
});
|
|
435
|
+
section.fields.forEach((col) => { var _a; groupObj[col.name] = (_a = col.value) !== null && _a !== void 0 ? _a : ''; });
|
|
64
436
|
initialData[section.sectionKey] = [groupObj];
|
|
65
437
|
}
|
|
66
438
|
else {
|
|
67
|
-
section.fields.forEach((col) => {
|
|
68
|
-
initialData[col.name] = col.value || '';
|
|
69
|
-
});
|
|
439
|
+
section.fields.forEach((col) => { var _a; initialData[col.name] = (_a = col.value) !== null && _a !== void 0 ? _a : ''; });
|
|
70
440
|
}
|
|
71
441
|
});
|
|
72
442
|
setFormData(initialData);
|
|
@@ -83,11 +453,9 @@ const AddUpdateForm = ({ config }) => {
|
|
|
83
453
|
}
|
|
84
454
|
return copy;
|
|
85
455
|
});
|
|
86
|
-
// We do a delayed trigger to on change to simulate reactive form passing state
|
|
87
456
|
setTimeout(() => {
|
|
88
457
|
const col = findColumn(name, sectionKey);
|
|
89
|
-
if (col
|
|
90
|
-
// Needs recent state
|
|
458
|
+
if (col === null || col === void 0 ? void 0 : col.onChange) {
|
|
91
459
|
setFormData((latestState) => {
|
|
92
460
|
col.onChange(value, latestState);
|
|
93
461
|
return latestState;
|
|
@@ -99,7 +467,7 @@ const AddUpdateForm = ({ config }) => {
|
|
|
99
467
|
for (const section of config.sections) {
|
|
100
468
|
if (sectionKey && section.sectionKey !== sectionKey)
|
|
101
469
|
continue;
|
|
102
|
-
const col = section.fields.find(c => c.name === name);
|
|
470
|
+
const col = section.fields.find((c) => c.name === name);
|
|
103
471
|
if (col)
|
|
104
472
|
return col;
|
|
105
473
|
}
|
|
@@ -109,15 +477,16 @@ const AddUpdateForm = ({ config }) => {
|
|
|
109
477
|
setFormData((prev) => {
|
|
110
478
|
const copy = { ...prev };
|
|
111
479
|
const groupObj = {};
|
|
112
|
-
fields.forEach((col) => { groupObj[col.name] = col.value
|
|
480
|
+
fields.forEach((col) => { var _a; groupObj[col.name] = (_a = col.value) !== null && _a !== void 0 ? _a : ''; });
|
|
113
481
|
copy[sectionKey] = [...(copy[sectionKey] || []), groupObj];
|
|
114
482
|
return copy;
|
|
115
483
|
});
|
|
116
484
|
};
|
|
117
485
|
const removeSectionItem = (sectionKey, index) => {
|
|
118
486
|
setFormData((prev) => {
|
|
487
|
+
var _a;
|
|
119
488
|
const copy = { ...prev };
|
|
120
|
-
if (copy[sectionKey]
|
|
489
|
+
if (((_a = copy[sectionKey]) === null || _a === void 0 ? void 0 : _a.length) > 1) {
|
|
121
490
|
const arr = [...copy[sectionKey]];
|
|
122
491
|
arr.splice(index, 1);
|
|
123
492
|
copy[sectionKey] = arr;
|
|
@@ -143,102 +512,102 @@ const AddUpdateForm = ({ config }) => {
|
|
|
143
512
|
errorPriority.push('regex');
|
|
144
513
|
}
|
|
145
514
|
if (v.type === 'minLength') {
|
|
146
|
-
rules.push({ name: 'minLength', params: { value: v.value }, errorKey: 'ERR_MIN_LENGTH', message: v.message });
|
|
515
|
+
rules.push({ name: 'minLength', params: { value: v.value }, errorKey: v.errorKey || 'ERR_MIN_LENGTH', message: v.message });
|
|
147
516
|
errorPriority.push('minLength');
|
|
148
517
|
}
|
|
149
518
|
if (v.type === 'maxLength') {
|
|
150
|
-
rules.push({ name: 'maxLength', params: { value: v.value }, errorKey: 'ERR_MAX_LENGTH', message: v.message });
|
|
519
|
+
rules.push({ name: 'maxLength', params: { value: v.value }, errorKey: v.errorKey || 'ERR_MAX_LENGTH', message: v.message });
|
|
151
520
|
errorPriority.push('maxLength');
|
|
152
521
|
}
|
|
153
522
|
if (v.type === 'pattern') {
|
|
154
|
-
rules.push({ name: 'regex', params: { pattern: v.value }, errorKey: 'ERR_REGEX_MISMATCH', message: v.message });
|
|
523
|
+
rules.push({ name: 'regex', params: { pattern: v.value }, errorKey: v.errorKey || 'ERR_REGEX_MISMATCH', message: v.message });
|
|
155
524
|
errorPriority.push('regex');
|
|
156
525
|
}
|
|
526
|
+
if (v.type === 'min') {
|
|
527
|
+
rules.push({ name: 'min', params: { value: v.value }, errorKey: v.errorKey || 'ERR_MIN_VALUE', message: v.message });
|
|
528
|
+
errorPriority.push('min');
|
|
529
|
+
}
|
|
530
|
+
if (v.type === 'max') {
|
|
531
|
+
rules.push({ name: 'max', params: { value: v.value }, errorKey: v.errorKey || 'ERR_MAX_VALUE', message: v.message });
|
|
532
|
+
errorPriority.push('max');
|
|
533
|
+
}
|
|
534
|
+
if (v.type === 'custom') {
|
|
535
|
+
rules.push({ name: 'custom', params: { validator: v.value }, errorKey: v.errorKey || 'ERR_CUSTOM_INVALID', message: v.message });
|
|
536
|
+
errorPriority.push('custom');
|
|
537
|
+
}
|
|
538
|
+
if (v.type === 'duplicate') {
|
|
539
|
+
rules.push({ name: 'duplicate', params: v.params, errorKey: v.errorKey || 'ERR_DUPLICATE', message: v.message });
|
|
540
|
+
errorPriority.push('duplicate');
|
|
541
|
+
}
|
|
542
|
+
if (v.type === 'passwordComplexity') {
|
|
543
|
+
rules.push({ name: 'passwordComplexity', params: v.params, errorKey: v.errorKey || 'ERR_PASSWORD_COMPLEXITY', message: v.message });
|
|
544
|
+
errorPriority.push('passwordComplexity');
|
|
545
|
+
}
|
|
157
546
|
});
|
|
158
547
|
}
|
|
159
548
|
return { controlType: 'EntryField', rules, errorPriority };
|
|
160
549
|
};
|
|
161
|
-
const isFieldDisabled = (column) =>
|
|
162
|
-
if (typeof column.disabled === 'function') {
|
|
163
|
-
return column.disabled(formData);
|
|
164
|
-
}
|
|
165
|
-
return column.disabled || false;
|
|
166
|
-
};
|
|
550
|
+
const isFieldDisabled = (column) => typeof column.disabled === 'function' ? column.disabled(formData) : column.disabled || false;
|
|
167
551
|
const renderField = (column, value, sectionKey, index) => {
|
|
168
552
|
var _a, _b;
|
|
553
|
+
if (column.hidden)
|
|
554
|
+
return null;
|
|
169
555
|
const disabled = isFieldDisabled(column);
|
|
170
556
|
const schema = getSchema(column);
|
|
171
557
|
const onChange = (val) => handleFieldChange(column.name, val, sectionKey, index);
|
|
172
|
-
if (column.hidden)
|
|
173
|
-
return null;
|
|
174
558
|
switch (column.type) {
|
|
175
|
-
case 'text':
|
|
176
|
-
|
|
177
|
-
case '
|
|
178
|
-
|
|
179
|
-
case '
|
|
180
|
-
|
|
181
|
-
case '
|
|
182
|
-
|
|
183
|
-
case '
|
|
184
|
-
|
|
185
|
-
case '
|
|
186
|
-
return react_1.default.createElement(FvCheckbox_1.FvCheckbox, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
|
|
187
|
-
case 'toggle':
|
|
188
|
-
return react_1.default.createElement(FvToggle_1.FvToggle, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
|
|
189
|
-
case 'radio':
|
|
190
|
-
return react_1.default.createElement(FvRadioGroup_1.FvRadioGroup, { label: column.label, options: column.options || [], value: value || '', disabled: disabled, layout: column.layout, onChange: onChange });
|
|
191
|
-
case 'date':
|
|
192
|
-
return react_1.default.createElement(FvDateField_1.FvDateField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
193
|
-
case 'month-year':
|
|
194
|
-
return react_1.default.createElement(FvMonthYearField_1.FvMonthYearField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
195
|
-
case 'textarea':
|
|
196
|
-
return react_1.default.createElement(FvRichTextEditor_1.FvRichTextEditor, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
559
|
+
case 'text': return react_1.default.createElement(FvEntryField_1.FvEntryField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
560
|
+
case 'email': return react_1.default.createElement(FvEmailField_1.FvEmailField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
561
|
+
case 'password': return react_1.default.createElement(FvPasswordField_1.FvPasswordField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
562
|
+
case 'number': return react_1.default.createElement(FvNumberField_1.FvNumberField, { label: column.label, placeholder: column.placeholder, value: value !== null && value !== void 0 ? value : null, schema: schema, disabled: disabled, onChange: onChange });
|
|
563
|
+
case 'select': return react_1.default.createElement(FvDropdown_1.FvDropdown, { label: column.label, placeholder: column.placeholder, options: column.options || [], value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
564
|
+
case 'checkbox': return react_1.default.createElement(FvCheckbox_1.FvCheckbox, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
|
|
565
|
+
case 'toggle': return react_1.default.createElement(FvToggle_1.FvToggle, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
|
|
566
|
+
case 'radio': return react_1.default.createElement(FvRadioGroup_1.FvRadioGroup, { label: column.label, options: column.options || [], value: value || '', disabled: disabled, layout: column.layout, onChange: onChange });
|
|
567
|
+
case 'date': return react_1.default.createElement(FvDateField_1.FvDateField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
568
|
+
case 'month-year': return react_1.default.createElement(FvMonthYearField_1.FvMonthYearField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
569
|
+
case 'textarea': return react_1.default.createElement(FvRichTextEditor_1.FvRichTextEditor, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
197
570
|
case 'file':
|
|
198
571
|
if (((_a = column.accept) === null || _a === void 0 ? void 0 : _a.startsWith('image')) || column.filePreview) {
|
|
199
|
-
return react_1.default.createElement(FvImageSelector_1.FvImageSelector, { label: column.label, placeholder: column.placeholder, value: value
|
|
572
|
+
return react_1.default.createElement(FvImageSelector_1.FvImageSelector, { label: column.label, placeholder: column.placeholder, value: value !== null && value !== void 0 ? value : null, schema: schema, disabled: disabled, onChange: onChange });
|
|
200
573
|
}
|
|
201
|
-
return react_1.default.createElement(FvFileSelector_1.FvFileSelector, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value
|
|
202
|
-
case 'name-code':
|
|
203
|
-
|
|
204
|
-
case '
|
|
205
|
-
|
|
206
|
-
case '
|
|
207
|
-
|
|
208
|
-
case '
|
|
209
|
-
|
|
210
|
-
case '
|
|
211
|
-
|
|
212
|
-
case '
|
|
213
|
-
|
|
214
|
-
case 'micr':
|
|
215
|
-
return react_1.default.createElement(FvMicrField_1.FvMicrField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
216
|
-
case 'iban':
|
|
217
|
-
return react_1.default.createElement(FvIbanField_1.FvIbanField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
218
|
-
case 'document':
|
|
219
|
-
return react_1.default.createElement(FvDocumentField_1.FvDocumentField, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value || null, schema: schema, disabled: disabled, onChange: onChange });
|
|
220
|
-
case 'time':
|
|
221
|
-
return react_1.default.createElement(FvTimeField_1.FvTimeField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
222
|
-
case 'service-period':
|
|
223
|
-
// Not perfectly mapped due to pure group dependency, simple implementation shown for continuity
|
|
224
|
-
return react_1.default.createElement(FvEntryField_1.FvEntryField, { label: column.label, value: value || '', disabled: true, onChange: onChange });
|
|
225
|
-
default:
|
|
226
|
-
return null; // unsupported
|
|
574
|
+
return react_1.default.createElement(FvFileSelector_1.FvFileSelector, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value !== null && value !== void 0 ? value : null, schema: schema, disabled: disabled, onChange: onChange });
|
|
575
|
+
case 'name-code': return react_1.default.createElement(FvNameCode_1.FvNameCode, { label: column.label, placeholder: column.placeholder, options: ((_b = column.options) === null || _b === void 0 ? void 0 : _b.map((o) => ({ code: o.value, name: o.label, value: o.value }))) || [], value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
576
|
+
case 'phone': return react_1.default.createElement(FvPhoneField_1.FvPhoneField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
577
|
+
case 'uan': return react_1.default.createElement(FvUanField_1.FvUanField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
578
|
+
case 'pf': return react_1.default.createElement(FvPfField_1.FvPfField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
579
|
+
case 'esi': return react_1.default.createElement(FvEsiField_1.FvEsiField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
580
|
+
case 'ifsc': return react_1.default.createElement(FvIfscField_1.FvIfscField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
581
|
+
case 'micr': return react_1.default.createElement(FvMicrField_1.FvMicrField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
582
|
+
case 'iban': return react_1.default.createElement(FvIbanField_1.FvIbanField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
583
|
+
case 'document': return react_1.default.createElement(FvDocumentField_1.FvDocumentField, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value !== null && value !== void 0 ? value : null, schema: schema, disabled: disabled, onChange: onChange });
|
|
584
|
+
case 'time': return react_1.default.createElement(FvTimeField_1.FvTimeField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
|
|
585
|
+
case 'service-period': return react_1.default.createElement(FvEntryField_1.FvEntryField, { label: column.label, value: value || '', disabled: true, onChange: onChange });
|
|
586
|
+
default: return null;
|
|
227
587
|
}
|
|
228
588
|
};
|
|
229
|
-
|
|
230
|
-
config.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
section.title && react_1.default.createElement("
|
|
235
|
-
section.isRepeatable && section.sectionKey ? ((formData[section.sectionKey] || []).map((group, idx) => (react_1.default.createElement("div", { key: idx, style: { position: 'relative', border: '1px solid #eee', borderRadius: '8px', padding: '
|
|
236
|
-
react_1.default.createElement("div", { style: { position: 'absolute', top: '
|
|
237
|
-
react_1.default.createElement("button", { type: "button", onClick: () => addSectionItem(section.sectionKey, section.fields), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '
|
|
238
|
-
(formData[section.sectionKey] || []).length > 1 && (react_1.default.createElement("button", { type: "button", onClick: () => removeSectionItem(section.sectionKey, idx), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '
|
|
239
|
-
react_1.default.createElement("div", { style:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
589
|
+
const formBody = (react_1.default.createElement("form", { onSubmit: handleSubmit, className: `fv-add-update-form ${config.className || ''}`.trim() },
|
|
590
|
+
config.sections.map((section, sIdx) => {
|
|
591
|
+
var _a;
|
|
592
|
+
const sectionMaxCols = (_a = section.maxColsPerRow) !== null && _a !== void 0 ? _a : maxCols;
|
|
593
|
+
return (react_1.default.createElement("div", { key: sIdx, style: { marginBottom: '16px' }, className: `fv-form-section ${section.className || ''}`.trim() },
|
|
594
|
+
section.title && react_1.default.createElement("div", { style: sectionTitleStyle, className: "fv-form-section-title" }, section.title),
|
|
595
|
+
section.isRepeatable && section.sectionKey ? ((formData[section.sectionKey] || []).map((group, idx) => (react_1.default.createElement("div", { key: idx, style: { position: 'relative', border: '1px solid #eee', borderRadius: '8px', padding: '12px', marginBottom: '12px', background: '#fafafa' }, className: "fv-form-repeatable-item" },
|
|
596
|
+
react_1.default.createElement("div", { style: { position: 'absolute', top: '8px', right: '8px', display: 'flex', gap: '4px' }, className: "fv-form-repeatable-actions" },
|
|
597
|
+
react_1.default.createElement("button", { type: "button", onClick: () => addSectionItem(section.sectionKey, section.fields), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '18px', color: '#2ecc71' }, className: "fv-form-add-btn" }, "\u2295"),
|
|
598
|
+
(formData[section.sectionKey] || []).length > 1 && (react_1.default.createElement("button", { type: "button", onClick: () => removeSectionItem(section.sectionKey, idx), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '18px', color: '#e74c3c' }, className: "fv-form-remove-btn" }, "\u2297"))),
|
|
599
|
+
react_1.default.createElement("div", { style: buildGridStyle(sectionMaxCols), className: "fv-form-grid" }, section.fields.map((col, cIdx) => (react_1.default.createElement("div", { key: cIdx, style: { gridColumn: `span ${col.colSpan || 1}`, minWidth: 0 }, className: `fv-form-field-wrapper ${col.className || ''}`.trim() }, renderField(col, group[col.name], section.sectionKey, idx))))))))) : (react_1.default.createElement("div", { style: buildGridStyle(sectionMaxCols), className: "fv-form-grid" }, section.fields.map((col, cIdx) => (react_1.default.createElement("div", { key: cIdx, style: { gridColumn: `span ${col.colSpan || 1}`, minWidth: 0 }, className: `fv-form-field-wrapper ${col.className || ''}`.trim() }, renderField(col, formData[col.name]))))))));
|
|
600
|
+
}),
|
|
601
|
+
react_1.default.createElement("div", { style: { display: 'flex', gap: '12px', marginTop: '8px' }, className: "fv-form-footer" }, !config.hideSubmit && (react_1.default.createElement("button", { type: "submit", disabled: config.disableSubmit, style: getSubmitButtonStyle(!!config.disableSubmit), className: "fv-form-submit-btn" }, config.submitLabel || 'Save')))));
|
|
602
|
+
if (asModal) {
|
|
603
|
+
return (react_1.default.createElement("div", { style: overlayStyle, className: "fv-form-overlay" },
|
|
604
|
+
react_1.default.createElement("div", { style: modalBoxStyle, className: "fv-modal-container" },
|
|
605
|
+
react_1.default.createElement("button", { type: "button", style: closeBtnStyle, onClick: config.onCancel, className: "fv-modal-close-btn" }, "\u2715"),
|
|
606
|
+
config.formTitle && react_1.default.createElement("h2", { style: modalTitleStyle, className: "fv-modal-title" }, config.formTitle),
|
|
607
|
+
react_1.default.createElement("div", { className: "fv-modal-body" }, formBody))));
|
|
608
|
+
}
|
|
609
|
+
return (react_1.default.createElement("div", { style: { background: '#f5f5f5', padding: '16px', borderRadius: '8px' }, className: "fv-standalone-form-container" },
|
|
610
|
+
config.formTitle && react_1.default.createElement("h2", { style: { margin: '0 0 16px', fontSize: '20px', fontWeight: 700 }, className: "fv-form-title" }, config.formTitle),
|
|
611
|
+
react_1.default.createElement("div", { style: standaloneWrapStyle, className: "fv-form-body-wrapper" }, formBody)));
|
|
243
612
|
};
|
|
244
613
|
exports.AddUpdateForm = AddUpdateForm;
|