form-craft-package 1.8.2-dev.1 → 1.8.2-dev.2
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/package.json +1 -1
- package/src/components/common/custom-hooks/index.ts +1 -0
- package/src/components/common/custom-hooks/use-login-handler.ts +3 -3
- package/src/components/common/custom-hooks/use-node-condition.hook/use-disabled-elements.hook.ts +62 -22
- package/src/components/common/custom-hooks/use-node-condition.hook/use-hidden-elements.hook.ts +54 -42
- package/src/components/common/custom-hooks/use-set-persistent-domain.hook.ts +20 -0
- package/src/components/companies/3-config-provider/index.tsx +27 -2
- package/src/components/form/2-details/index.tsx +14 -5
- package/src/components/form/layout-renderer/1-row/index.tsx +5 -1
- package/src/components/form/layout-renderer/1-row/repeatable-render.tsx +69 -28
- package/src/components/form/layout-renderer/3-element/10-currency.tsx +4 -2
- package/src/components/form/layout-renderer/3-element/11-breadcrumb.tsx +4 -2
- package/src/components/form/layout-renderer/3-element/12-picker-field.tsx +4 -7
- package/src/components/form/layout-renderer/3-element/2-field-element.tsx +203 -225
- package/src/components/form/layout-renderer/3-element/3-read-field-data.tsx +4 -6
- package/src/components/form/layout-renderer/3-element/4-rich-text-editor.tsx +4 -1
- package/src/components/form/layout-renderer/3-element/5-re-captcha.tsx +4 -7
- package/src/components/form/layout-renderer/3-element/6-signature.tsx +4 -2
- package/src/components/form/layout-renderer/3-element/7-file-upload.tsx +78 -26
- package/src/components/form/layout-renderer/3-element/8-fields-with-options.tsx +4 -2
- package/src/components/form/layout-renderer/3-element/9-form-data-render.tsx +4 -2
- package/src/components/form/layout-renderer/3-element/index.tsx +125 -86
- package/src/enums/form.enum.ts +4 -0
- package/src/enums/index.ts +1 -0
- package/src/functions/companies/index.tsx +12 -0
- package/src/functions/companies/use-company-config.tsx +14 -10
- package/src/functions/forms/data-render-functions.tsx +0 -1
- package/src/functions/forms/get-element-props.ts +2 -2
- package/src/functions/forms/index.ts +3 -1
- package/src/types/companies/site-layout/authenticated/index.tsx +5 -2
- package/src/types/forms/index.ts +9 -4
- package/src/types/forms/layout-elements/button.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Key, ReactNode, Fragment } from 'react'
|
|
1
|
+
import { Key, ReactNode, Fragment, memo } from 'react'
|
|
2
2
|
import { FaCaretDown } from 'react-icons/fa'
|
|
3
3
|
import dayjs, { Dayjs } from 'dayjs'
|
|
4
4
|
import { CountryEnum, DataSanitizationTypeEnum, ElementTypeEnum } from '../../../../enums'
|
|
@@ -15,22 +15,24 @@ interface ILayoutRenderer_FieldElement {
|
|
|
15
15
|
formRef?: FormInstance
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export const LayoutRenderer_FieldElement = ({ children, formRef }: ILayoutRenderer_FieldElement): JSX.Element => {
|
|
19
|
-
|
|
18
|
+
export const LayoutRenderer_FieldElement = memo(({ children, formRef }: ILayoutRenderer_FieldElement): JSX.Element => {
|
|
19
|
+
const elems = children()
|
|
20
|
+
if (Array.isArray(elems)) {
|
|
20
21
|
return (
|
|
21
22
|
<>
|
|
22
|
-
{
|
|
23
|
+
{elems
|
|
23
24
|
.filter(({ isHidden = false }) => !isHidden)
|
|
24
|
-
.map((field: IMapperFieldObj,
|
|
25
|
-
<FieldFormItemWrapper field={field} fieldIdx={
|
|
25
|
+
.map((field: IMapperFieldObj, idx: Key) => (
|
|
26
|
+
<FieldFormItemWrapper key={idx} field={field} fieldIdx={idx} formRef={formRef} />
|
|
26
27
|
))}
|
|
27
28
|
</>
|
|
28
29
|
)
|
|
30
|
+
}
|
|
29
31
|
|
|
30
|
-
if (
|
|
32
|
+
if (elems.isHidden) return <></>
|
|
31
33
|
|
|
32
|
-
return <FieldFormItemWrapper field={
|
|
33
|
-
}
|
|
34
|
+
return <FieldFormItemWrapper field={elems} fieldIdx={1} formRef={formRef} />
|
|
35
|
+
})
|
|
34
36
|
|
|
35
37
|
const FieldFormItemWrapper = ({
|
|
36
38
|
field,
|
|
@@ -40,231 +42,204 @@ const FieldFormItemWrapper = ({
|
|
|
40
42
|
field: IMapperFieldObj
|
|
41
43
|
fieldIdx: Key
|
|
42
44
|
formRef?: FormInstance
|
|
43
|
-
}) =>
|
|
44
|
-
|
|
45
|
-
<Form.Item
|
|
46
|
-
key={fieldIdx}
|
|
47
|
-
name={field.name}
|
|
48
|
-
label={field.hasNoLabel ? '' : field.label}
|
|
49
|
-
labelAlign="left"
|
|
50
|
-
messageVariables={{ [field.name as string]: formRef?.getFieldValue(field.name) }}
|
|
51
|
-
valuePropName={
|
|
52
|
-
field.type && [ElementTypeEnum.Checkbox, ElementTypeEnum.Switch].includes(field.type) ? 'checked' : 'value'
|
|
53
|
-
}
|
|
54
|
-
rules={mapToFormItemRules(field.validations ?? [], field.name as string)}
|
|
55
|
-
normalize={(value) => {
|
|
56
|
-
const sanitizationRule = field.sanitization
|
|
57
|
-
if (!sanitizationRule || sanitizationRule.type === DataSanitizationTypeEnum.Default) return value
|
|
45
|
+
}) => {
|
|
46
|
+
const { name, nameFullPath, label, hasNoLabel, type, validations, sanitization, disabled } = field
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
return (
|
|
49
|
+
<Fragment key={fieldIdx}>
|
|
50
|
+
<Form.Item
|
|
51
|
+
name={name}
|
|
52
|
+
label={hasNoLabel ? '' : label}
|
|
53
|
+
labelAlign="left"
|
|
54
|
+
messageVariables={{ [String(name)]: formRef?.getFieldValue(name) }}
|
|
55
|
+
valuePropName={type && [ElementTypeEnum.Checkbox, ElementTypeEnum.Switch].includes(type) ? 'checked' : 'value'}
|
|
56
|
+
rules={mapToFormItemRules(validations ?? [], String(name))}
|
|
57
|
+
normalize={(value) => {
|
|
58
|
+
if (!sanitization || sanitization.type === DataSanitizationTypeEnum.Default) return value
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{field.type === ElementTypeEnum.ColorPicker ? (
|
|
67
|
-
<CustomColorField formRef={formRef} name={field.name} disabled={field.disabled} />
|
|
68
|
-
) : (
|
|
69
|
-
getField(field)
|
|
70
|
-
)}
|
|
71
|
-
</Form.Item>
|
|
72
|
-
{field.disabled && field.type !== ElementTypeEnum.Checkbox && <DisabledFieldIndicator />}
|
|
73
|
-
</Fragment>
|
|
74
|
-
)
|
|
60
|
+
// Predefined or Custom both use pattern
|
|
61
|
+
if (sanitization.pattern) {
|
|
62
|
+
return formatByPattern(value, sanitization.pattern)
|
|
63
|
+
}
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
decimalPoint = 0,
|
|
90
|
-
mode,
|
|
91
|
-
disabledDate,
|
|
92
|
-
}: Partial<IMapperFieldObj>): JSX.Element => {
|
|
93
|
-
switch (type) {
|
|
94
|
-
case ElementTypeEnum.LongInput:
|
|
95
|
-
return (
|
|
96
|
-
<Input.TextArea
|
|
97
|
-
autoSize={{ minRows }}
|
|
98
|
-
placeholder={placeholder as string}
|
|
99
|
-
disabled={disabled}
|
|
100
|
-
autoComplete="off"
|
|
101
|
-
className={ELEMENTS_DEFAULT_CLASS.Input}
|
|
102
|
-
/>
|
|
103
|
-
)
|
|
104
|
-
case ElementTypeEnum.Select:
|
|
105
|
-
return (
|
|
106
|
-
<Select
|
|
107
|
-
placeholder={placeholder}
|
|
108
|
-
suffixIcon={<FaCaretDown />}
|
|
109
|
-
options={options}
|
|
110
|
-
disabled={disabled}
|
|
111
|
-
showSearch
|
|
112
|
-
optionFilterProp="label"
|
|
113
|
-
filterOption={(input, option) => {
|
|
114
|
-
const noOtherField = !option?.field2 && !option?.field3 && !option?.field4
|
|
115
|
-
const text = option
|
|
116
|
-
? typeof option.label === 'string' && noOtherField
|
|
117
|
-
? option.label
|
|
118
|
-
: [option.label, option.field2 ?? '', option.field3 ?? '', option.field4 ?? ''].join(' ')
|
|
119
|
-
: ''
|
|
120
|
-
|
|
121
|
-
return text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
122
|
-
}}
|
|
123
|
-
optionRender={(option: any) => {
|
|
124
|
-
const opData = option.data || {}
|
|
125
|
-
const noOtherField = !opData.field2 && !opData.field3 && !opData.field4
|
|
65
|
+
return value
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
{type === ElementTypeEnum.ColorPicker ? (
|
|
69
|
+
<CustomColorField formRef={formRef} name={nameFullPath} disabled={disabled} />
|
|
70
|
+
) : (
|
|
71
|
+
getField(field)
|
|
72
|
+
)}
|
|
73
|
+
</Form.Item>
|
|
74
|
+
{disabled && type !== ElementTypeEnum.Checkbox && <DisabledFieldIndicator />}
|
|
75
|
+
</Fragment>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
126
78
|
|
|
127
|
-
|
|
79
|
+
// Map each ElementTypeEnum to a renderer function
|
|
80
|
+
type FieldRenderer = (field: Partial<IMapperFieldObj>) => JSX.Element
|
|
128
81
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<div className={`${ELEMENTS_DEFAULT_CLASS.SwitchContainer} flex items-center gap-2`}>
|
|
162
|
-
<Switch disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.Switch} />
|
|
163
|
-
{label}
|
|
164
|
-
</div>
|
|
165
|
-
)
|
|
166
|
-
case ElementTypeEnum.Radio:
|
|
167
|
-
if (isMultiValue)
|
|
82
|
+
const fieldRenderers: Partial<Record<ElementTypeEnum, FieldRenderer>> = {
|
|
83
|
+
[ElementTypeEnum.LongInput]: ({ placeholder, disabled, minRows }) => (
|
|
84
|
+
<Input.TextArea
|
|
85
|
+
autoSize={{ minRows: minRows! }}
|
|
86
|
+
placeholder={placeholder as string}
|
|
87
|
+
disabled={disabled}
|
|
88
|
+
autoComplete="off"
|
|
89
|
+
className={ELEMENTS_DEFAULT_CLASS.Input}
|
|
90
|
+
/>
|
|
91
|
+
),
|
|
92
|
+
[ElementTypeEnum.Select]: ({ placeholder, options = [], disabled, allowClear = true, mode }) => (
|
|
93
|
+
<Select
|
|
94
|
+
placeholder={placeholder}
|
|
95
|
+
suffixIcon={<FaCaretDown />}
|
|
96
|
+
options={options}
|
|
97
|
+
disabled={disabled}
|
|
98
|
+
showSearch
|
|
99
|
+
optionFilterProp="label"
|
|
100
|
+
filterOption={(input, option) => {
|
|
101
|
+
const noOther = !option?.field2 && !option?.field3 && !option?.field4
|
|
102
|
+
const text = option
|
|
103
|
+
? typeof option.label === 'string' && noOther
|
|
104
|
+
? option.label
|
|
105
|
+
: [option.label, option.field2 ?? '', option.field3 ?? '', option.field4 ?? ''].join(' ')
|
|
106
|
+
: ''
|
|
107
|
+
return text.toLowerCase().includes(input.toLowerCase())
|
|
108
|
+
}}
|
|
109
|
+
optionRender={(opt: any) => {
|
|
110
|
+
const data = opt.data || {}
|
|
111
|
+
const simple = !data.field2 && !data.field3 && !data.field4
|
|
112
|
+
if (simple) return opt.label
|
|
168
113
|
return (
|
|
169
|
-
<
|
|
170
|
-
<div className="
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
114
|
+
<div className="flex flex-col gap-0.5" key={data.value}>
|
|
115
|
+
<div className="space-x-2">
|
|
116
|
+
<span className="text-primary font-bold">{data.label}</span>
|
|
117
|
+
{data.field2 && (
|
|
118
|
+
<span className="text-12 italic font-normal">
|
|
119
|
+
({data.field2_RC ? renderData(data.field2, data.field2_RC) : data.field2})
|
|
120
|
+
</span>
|
|
121
|
+
)}
|
|
176
122
|
</div>
|
|
177
|
-
|
|
123
|
+
{data.field3 && (
|
|
124
|
+
<div className="text-12">{data.field3_RC ? renderData(data.field3, data.field3_RC) : data.field3}</div>
|
|
125
|
+
)}
|
|
126
|
+
{data.field4 && (data.field4_RC ? renderData(data.field4, data.field4_RC) : data.field4)}
|
|
127
|
+
</div>
|
|
178
128
|
)
|
|
129
|
+
}}
|
|
130
|
+
allowClear={allowClear}
|
|
131
|
+
className={`${ELEMENTS_DEFAULT_CLASS.Select} w-full`}
|
|
132
|
+
mode={mode}
|
|
133
|
+
/>
|
|
134
|
+
),
|
|
135
|
+
[ElementTypeEnum.Checkbox]: ({ label, disabled }) => (
|
|
136
|
+
<Checkbox disabled={disabled} className={ElementTypeEnum.Checkbox}>
|
|
137
|
+
{label}
|
|
138
|
+
</Checkbox>
|
|
139
|
+
),
|
|
140
|
+
[ElementTypeEnum.Switch]: ({ label, disabled }) => (
|
|
141
|
+
<div className={`${ELEMENTS_DEFAULT_CLASS.SwitchContainer} flex items-center gap-2`}>
|
|
142
|
+
<Switch disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.Switch} />
|
|
143
|
+
{label}
|
|
144
|
+
</div>
|
|
145
|
+
),
|
|
146
|
+
[ElementTypeEnum.Radio]: ({ options = [], disabled, isMultiValue, isCustom }) =>
|
|
147
|
+
isMultiValue ? (
|
|
148
|
+
<Checkbox.Group disabled={disabled} className={ELEMENTS_DEFAULT_CLASS.CheckboxGroup}>
|
|
149
|
+
<div className="flex items-center gap-1">
|
|
150
|
+
{options.map((o, i) => (
|
|
151
|
+
<Checkbox key={i} value={o.value}>
|
|
152
|
+
{o.label}
|
|
153
|
+
</Checkbox>
|
|
154
|
+
))}
|
|
155
|
+
</div>
|
|
156
|
+
</Checkbox.Group>
|
|
157
|
+
) : (
|
|
158
|
+
<Radio.Group
|
|
159
|
+
disabled={disabled}
|
|
160
|
+
className={`${ELEMENTS_DEFAULT_CLASS.RadioGroup} w-full ${isCustom ? 'fc-custom' : ''}`}
|
|
161
|
+
>
|
|
162
|
+
<div className="flex items-center gap-1">
|
|
163
|
+
{options.map((o, i) => (
|
|
164
|
+
<Radio key={i} value={o.value}>
|
|
165
|
+
{o.label}
|
|
166
|
+
</Radio>
|
|
167
|
+
))}
|
|
168
|
+
</div>
|
|
169
|
+
</Radio.Group>
|
|
170
|
+
),
|
|
171
|
+
[ElementTypeEnum.NumberInput]: ({ placeholder, disabled, numberFieldMin, numberFieldMax }) => (
|
|
172
|
+
<InputNumber
|
|
173
|
+
placeholder={placeholder as string}
|
|
174
|
+
disabled={disabled}
|
|
175
|
+
className={`${ELEMENTS_DEFAULT_CLASS.NumberInput} w-full`}
|
|
176
|
+
min={numberFieldMin}
|
|
177
|
+
max={numberFieldMax}
|
|
178
|
+
/>
|
|
179
|
+
),
|
|
180
|
+
[ElementTypeEnum.CurrencyInput]: ({ placeholder, disabled, country, decimalPoint }) => (
|
|
181
|
+
<CurrencyField
|
|
182
|
+
placeholder={placeholder as string}
|
|
183
|
+
disabled={disabled}
|
|
184
|
+
country={country!}
|
|
185
|
+
decimalPoint={decimalPoint!}
|
|
186
|
+
/>
|
|
187
|
+
),
|
|
188
|
+
[ElementTypeEnum.Password]: ({ placeholder, disabled }) => (
|
|
189
|
+
<Input.Password
|
|
190
|
+
className={ELEMENTS_DEFAULT_CLASS.PasswordInput}
|
|
191
|
+
placeholder={placeholder as string}
|
|
192
|
+
disabled={disabled}
|
|
193
|
+
/>
|
|
194
|
+
),
|
|
195
|
+
[ElementTypeEnum.DatePicker]: ({ placeholder, disabled, disabledDate }) => (
|
|
196
|
+
<DatePicker
|
|
197
|
+
format={datepickerFormats}
|
|
198
|
+
placeholder={placeholder as string}
|
|
199
|
+
disabled={disabled}
|
|
200
|
+
disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now).isBefore(dayjs('1900-01-01')))}
|
|
201
|
+
allowClear
|
|
202
|
+
className={`${ELEMENTS_DEFAULT_CLASS.DatePicker} w-full`}
|
|
203
|
+
onChange={(e) => {
|
|
204
|
+
if (dayjs(e).isBefore(dayjs('1900-01-01')))
|
|
205
|
+
Modal.error({ title: 'Invalid Date!', content: 'The year cannot be less than 1900!', centered: true })
|
|
206
|
+
}}
|
|
207
|
+
/>
|
|
208
|
+
),
|
|
209
|
+
[ElementTypeEnum.RangePicker]: ({ placeholder, disabled, disabledDate }) => (
|
|
210
|
+
<DatePicker.RangePicker
|
|
211
|
+
format={datepickerFormats}
|
|
212
|
+
placeholder={placeholder as [string, string]}
|
|
213
|
+
disabled={disabled}
|
|
214
|
+
disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now).isBefore(dayjs('1900-01-01')))}
|
|
215
|
+
allowClear
|
|
216
|
+
className={`${ELEMENTS_DEFAULT_CLASS.RangePicker} w-full`}
|
|
217
|
+
allowEmpty
|
|
218
|
+
/>
|
|
219
|
+
),
|
|
220
|
+
[ElementTypeEnum.TimePicker]: ({ disabled }) => (
|
|
221
|
+
<DatePicker.TimePicker
|
|
222
|
+
format={datepickerFormats}
|
|
223
|
+
disabled={disabled}
|
|
224
|
+
className={`${ELEMENTS_DEFAULT_CLASS.TimePicker} w-full`}
|
|
225
|
+
allowClear
|
|
226
|
+
/>
|
|
227
|
+
),
|
|
228
|
+
[ElementTypeEnum.ShortInput]: ({ placeholder, disabled, name }) => (
|
|
229
|
+
<Input
|
|
230
|
+
id={name as string}
|
|
231
|
+
className={ELEMENTS_DEFAULT_CLASS.Input}
|
|
232
|
+
placeholder={placeholder as string}
|
|
233
|
+
disabled={disabled}
|
|
234
|
+
autoComplete="off"
|
|
235
|
+
/>
|
|
236
|
+
),
|
|
237
|
+
}
|
|
179
238
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
>
|
|
185
|
-
<div className="flex items-center gap-1">
|
|
186
|
-
{options?.map((o, oIdx) => (
|
|
187
|
-
<Radio key={oIdx} value={o.value}>
|
|
188
|
-
{o.label}
|
|
189
|
-
</Radio>
|
|
190
|
-
))}
|
|
191
|
-
</div>
|
|
192
|
-
</Radio.Group>
|
|
193
|
-
)
|
|
194
|
-
case ElementTypeEnum.NumberInput:
|
|
195
|
-
return (
|
|
196
|
-
<InputNumber
|
|
197
|
-
placeholder={placeholder as string}
|
|
198
|
-
disabled={disabled}
|
|
199
|
-
className={`${ELEMENTS_DEFAULT_CLASS.NumberInput} w-full`}
|
|
200
|
-
min={numberFieldMin}
|
|
201
|
-
max={numberFieldMax}
|
|
202
|
-
/>
|
|
203
|
-
)
|
|
204
|
-
case ElementTypeEnum.CurrencyInput:
|
|
205
|
-
return (
|
|
206
|
-
<CurrencyField
|
|
207
|
-
placeholder={placeholder as string}
|
|
208
|
-
disabled={disabled}
|
|
209
|
-
country={country}
|
|
210
|
-
decimalPoint={decimalPoint}
|
|
211
|
-
/>
|
|
212
|
-
)
|
|
213
|
-
case ElementTypeEnum.Password:
|
|
214
|
-
return (
|
|
215
|
-
<Input.Password
|
|
216
|
-
className={ELEMENTS_DEFAULT_CLASS.PasswordInput}
|
|
217
|
-
placeholder={placeholder as string}
|
|
218
|
-
disabled={disabled}
|
|
219
|
-
/>
|
|
220
|
-
)
|
|
221
|
-
case ElementTypeEnum.DatePicker:
|
|
222
|
-
return (
|
|
223
|
-
<DatePicker
|
|
224
|
-
format={datepickerFormats}
|
|
225
|
-
placeholder={placeholder as string}
|
|
226
|
-
disabled={disabled}
|
|
227
|
-
disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now) < dayjs('01/01/1900'))}
|
|
228
|
-
allowClear={allowClear}
|
|
229
|
-
className={`${ELEMENTS_DEFAULT_CLASS.DatePicker} w-full`}
|
|
230
|
-
onChange={(e) => {
|
|
231
|
-
if (dayjs(e) < dayjs('01/01/1900'))
|
|
232
|
-
Modal.error({ title: 'Invalid Date!', content: 'The year cannot be less than 1900!', centered: true })
|
|
233
|
-
}}
|
|
234
|
-
/>
|
|
235
|
-
)
|
|
236
|
-
case ElementTypeEnum.RangePicker:
|
|
237
|
-
return (
|
|
238
|
-
<DatePicker.RangePicker
|
|
239
|
-
format={datepickerFormats}
|
|
240
|
-
placeholder={placeholder as [string, string] | undefined}
|
|
241
|
-
disabled={disabled}
|
|
242
|
-
disabledDate={(now) => (disabledDate ? disabledDate(now) : dayjs(now) < dayjs('01/01/1900'))}
|
|
243
|
-
allowClear={allowClear}
|
|
244
|
-
className={`${ELEMENTS_DEFAULT_CLASS.RangePicker} w-full`}
|
|
245
|
-
allowEmpty
|
|
246
|
-
/>
|
|
247
|
-
)
|
|
248
|
-
case ElementTypeEnum.TimePicker:
|
|
249
|
-
return (
|
|
250
|
-
<DatePicker.TimePicker
|
|
251
|
-
format={datepickerFormats}
|
|
252
|
-
disabled={disabled}
|
|
253
|
-
className={`${ELEMENTS_DEFAULT_CLASS.TimePicker} w-full`}
|
|
254
|
-
allowClear={allowClear}
|
|
255
|
-
/>
|
|
256
|
-
)
|
|
257
|
-
case ElementTypeEnum.ShortInput:
|
|
258
|
-
default:
|
|
259
|
-
return (
|
|
260
|
-
<Input
|
|
261
|
-
className={ELEMENTS_DEFAULT_CLASS.Input}
|
|
262
|
-
placeholder={placeholder as string}
|
|
263
|
-
disabled={disabled}
|
|
264
|
-
autoComplete="off"
|
|
265
|
-
/>
|
|
266
|
-
)
|
|
267
|
-
}
|
|
239
|
+
const getField = (field: Partial<IMapperFieldObj>): JSX.Element => {
|
|
240
|
+
const type = field.type ?? ElementTypeEnum.ShortInput
|
|
241
|
+
const renderer = fieldRenderers[type] || fieldRenderers[ElementTypeEnum.ShortInput]
|
|
242
|
+
return renderer!(field)
|
|
268
243
|
}
|
|
269
244
|
|
|
270
245
|
interface IMapperFieldObj {
|
|
@@ -272,6 +247,7 @@ interface IMapperFieldObj {
|
|
|
272
247
|
validations?: IValidationRule[]
|
|
273
248
|
isHidden?: boolean
|
|
274
249
|
name: string | (string | number)[]
|
|
250
|
+
nameFullPath?: string | (string | number)[]
|
|
275
251
|
label?: string | ReactNode
|
|
276
252
|
description?: string
|
|
277
253
|
placeholder?: string | [string, string]
|
|
@@ -290,11 +266,13 @@ interface IMapperFieldObj {
|
|
|
290
266
|
mode?: 'multiple' | 'tags'
|
|
291
267
|
disabledDate?: (date: Dayjs) => boolean
|
|
292
268
|
}
|
|
269
|
+
|
|
293
270
|
interface ISelectOption {
|
|
294
271
|
value: number | boolean | string
|
|
295
272
|
label: string | ReactNode
|
|
296
273
|
[key: string]: any
|
|
297
274
|
}
|
|
275
|
+
|
|
298
276
|
const datepickerFormats = [
|
|
299
277
|
'MM/DD/YYYY',
|
|
300
278
|
'MM/DD/YY',
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { Form } from 'antd'
|
|
2
2
|
import { renderData } from '../../../../functions/forms'
|
|
3
3
|
import { useFormPreservedItemValues } from '../../../common/custom-hooks/use-preserved-form-items.hook'
|
|
4
|
-
import { useMemo } from 'react'
|
|
4
|
+
import { memo, useMemo } from 'react'
|
|
5
5
|
import { DataRenderTypeEnum, ReadFieldDataValueTypeEnum } from '../../../../enums'
|
|
6
6
|
import { IReadFieldDataElementProps } from '../../../../types'
|
|
7
7
|
import { IFormContext } from '../1-row'
|
|
8
8
|
import { evaluateValue } from '../../../../functions/forms/evaluate-value'
|
|
9
9
|
import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
formContext,
|
|
13
|
-
elementProps,
|
|
14
|
-
style = {},
|
|
15
|
-
}: ILayoutRenderer_ReadFieldData) {
|
|
11
|
+
function LayoutRenderer_ReadFieldData({ formContext, elementProps, style = {} }: ILayoutRenderer_ReadFieldData) {
|
|
16
12
|
const { formRef, companyKey } = formContext
|
|
17
13
|
const fieldValue =
|
|
18
14
|
elementProps.valueType === ReadFieldDataValueTypeEnum.Evaluated
|
|
@@ -54,6 +50,8 @@ export default function LayoutRenderer_ReadFieldData({
|
|
|
54
50
|
)
|
|
55
51
|
}
|
|
56
52
|
|
|
53
|
+
export default memo(LayoutRenderer_ReadFieldData)
|
|
54
|
+
|
|
57
55
|
type ILayoutRenderer_ReadFieldData = {
|
|
58
56
|
formContext: IFormContext
|
|
59
57
|
elementProps: IReadFieldDataElementProps
|
|
@@ -7,8 +7,9 @@ import { IFormContext } from '../1-row'
|
|
|
7
7
|
import { mapToFormItemRules } from '../../../../functions'
|
|
8
8
|
import { FieldValidationEnum } from '../../../../enums'
|
|
9
9
|
import { ELEMENTS_DEFAULT_CLASS, REGEX_PATTERNS } from '../../../../constants'
|
|
10
|
+
import { memo } from 'react'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
function LayoutRenderer_RichEditor({
|
|
12
13
|
formContext,
|
|
13
14
|
elementProps,
|
|
14
15
|
formItem,
|
|
@@ -53,6 +54,8 @@ export default function LayoutRenderer_RichEditor({
|
|
|
53
54
|
)
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
export default memo(LayoutRenderer_RichEditor)
|
|
58
|
+
|
|
56
59
|
const formats = ['header', 'bold', 'italic', 'underline', 'align', 'list', 'indent', 'clean']
|
|
57
60
|
const modules = {
|
|
58
61
|
toolbar: [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
1
|
+
import { memo, useCallback, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import ReCAPTCHA from 'react-google-recaptcha'
|
|
3
3
|
import { cancelableClient } from '../../../../api/client'
|
|
4
4
|
import { IElementBaseProps } from '.'
|
|
@@ -6,12 +6,7 @@ import { IReCaptchaElementProps } from '../../../../types'
|
|
|
6
6
|
import { IFormContext } from '../1-row'
|
|
7
7
|
import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
formContext,
|
|
11
|
-
elementProps,
|
|
12
|
-
formItem,
|
|
13
|
-
isDisabled,
|
|
14
|
-
}: ILayoutRenderer_RichEditor) {
|
|
9
|
+
function LayoutRenderer_ReCaptcha({ formContext, elementProps, formItem, isDisabled }: ILayoutRenderer_RichEditor) {
|
|
15
10
|
const { formRef, formKey } = formContext
|
|
16
11
|
const [tokenVerificationFailed, setTokenVerificationFailed] = useState(false)
|
|
17
12
|
const verifyApiCancelFuncRef = useRef<() => void | undefined>()
|
|
@@ -57,6 +52,8 @@ export default function LayoutRenderer_ReCaptcha({
|
|
|
57
52
|
)
|
|
58
53
|
}
|
|
59
54
|
|
|
55
|
+
export default memo(LayoutRenderer_ReCaptcha)
|
|
56
|
+
|
|
60
57
|
type ILayoutRenderer_RichEditor = {
|
|
61
58
|
elementProps: IReCaptchaElementProps
|
|
62
59
|
formContext: IFormContext
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Form } from 'antd'
|
|
2
|
-
import { useEffect, useMemo, useRef } from 'react'
|
|
2
|
+
import { memo, useEffect, useMemo, useRef } from 'react'
|
|
3
3
|
import SignatureCanvas from 'react-signature-canvas'
|
|
4
4
|
import { FormPreservedItemKeys } from '../../../../enums'
|
|
5
5
|
import { Button_FillerPortal } from '../../../common/button'
|
|
@@ -10,7 +10,7 @@ import { IFormContext } from '../1-row'
|
|
|
10
10
|
import { isNewFormDataPage, mapToFormItemRules } from '../../../../functions'
|
|
11
11
|
import { ELEMENTS_DEFAULT_CLASS } from '../../../../constants'
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
function LayoutRenderer_Signature({
|
|
14
14
|
formItem,
|
|
15
15
|
elementProps,
|
|
16
16
|
isDisabled,
|
|
@@ -81,6 +81,8 @@ export default function LayoutRenderer_Signature({
|
|
|
81
81
|
)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
export default memo(LayoutRenderer_Signature)
|
|
85
|
+
|
|
84
86
|
type ILayoutRenderer_Signature = {
|
|
85
87
|
elementProps: ISignatureElementProps
|
|
86
88
|
formContext: IFormContext
|