@bsol-oss/react-datatable5 12.0.0-beta.72 → 12.0.0-beta.74
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/README.md +67 -40
- package/dist/index.d.ts +15 -2
- package/dist/index.js +230 -155
- package/dist/index.mjs +230 -155
- package/dist/types/components/Form/SchemaFormContext.d.ts +4 -1
- package/dist/types/components/Form/components/core/FormRoot.d.ts +4 -2
- package/dist/types/components/Form/components/fields/DatePicker.d.ts +1 -1
- package/dist/types/components/Form/components/fields/EnumPicker.d.ts +1 -1
- package/dist/types/components/Form/components/fields/NumberInputField.d.ts +1 -1
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +11 -0
- package/dist/types/components/Form/components/viewers/NumberViewer.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3691,16 +3691,14 @@ const SchemaFormContext = React.createContext({
|
|
|
3691
3691
|
showResetButton: true,
|
|
3692
3692
|
showTitle: true,
|
|
3693
3693
|
},
|
|
3694
|
+
requireConfirmation: false,
|
|
3695
|
+
onFormSubmit: async () => { },
|
|
3694
3696
|
});
|
|
3695
3697
|
|
|
3696
3698
|
const useSchemaContext = () => {
|
|
3697
3699
|
return React.useContext(SchemaFormContext);
|
|
3698
3700
|
};
|
|
3699
3701
|
|
|
3700
|
-
const clearEmptyString = (object) => {
|
|
3701
|
-
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3702
|
-
};
|
|
3703
|
-
|
|
3704
3702
|
const validateData = (data, schema) => {
|
|
3705
3703
|
const ajv = new Ajv({
|
|
3706
3704
|
strict: false,
|
|
@@ -3719,6 +3717,10 @@ const validateData = (data, schema) => {
|
|
|
3719
3717
|
};
|
|
3720
3718
|
};
|
|
3721
3719
|
|
|
3720
|
+
const clearEmptyString = (object) => {
|
|
3721
|
+
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3722
|
+
};
|
|
3723
|
+
|
|
3722
3724
|
const idPickerSanityCheck = (column, foreign_key) => {
|
|
3723
3725
|
if (!!foreign_key == false) {
|
|
3724
3726
|
throw new Error(`The key foreign_key does not exist in properties of column ${column} when using id-picker.`);
|
|
@@ -3738,13 +3740,88 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3738
3740
|
showSubmitButton: true,
|
|
3739
3741
|
showResetButton: true,
|
|
3740
3742
|
showTitle: true,
|
|
3741
|
-
}, dateTimePickerLabels, idPickerLabels, }) => {
|
|
3743
|
+
}, requireConfirmation = false, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }) => {
|
|
3742
3744
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
3743
3745
|
const [isError, setIsError] = React.useState(false);
|
|
3744
3746
|
const [isSubmiting, setIsSubmiting] = React.useState(false);
|
|
3745
3747
|
const [isConfirming, setIsConfirming] = React.useState(false);
|
|
3746
3748
|
const [validatedData, setValidatedData] = React.useState();
|
|
3747
3749
|
const [error, setError] = React.useState();
|
|
3750
|
+
const onBeforeSubmit = () => {
|
|
3751
|
+
setIsSubmiting(true);
|
|
3752
|
+
};
|
|
3753
|
+
const onAfterSubmit = () => {
|
|
3754
|
+
setIsSubmiting(false);
|
|
3755
|
+
};
|
|
3756
|
+
const onSubmitError = (error) => {
|
|
3757
|
+
setIsError(true);
|
|
3758
|
+
setError(error);
|
|
3759
|
+
};
|
|
3760
|
+
const onSubmitSuccess = () => {
|
|
3761
|
+
setIsSuccess(true);
|
|
3762
|
+
};
|
|
3763
|
+
const validateFormData = (data) => {
|
|
3764
|
+
try {
|
|
3765
|
+
const { isValid, errors } = validateData(data, schema);
|
|
3766
|
+
return {
|
|
3767
|
+
isValid,
|
|
3768
|
+
errors,
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
catch (error) {
|
|
3772
|
+
return {
|
|
3773
|
+
isValid: false,
|
|
3774
|
+
errors: [
|
|
3775
|
+
{
|
|
3776
|
+
field: 'validation',
|
|
3777
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
3778
|
+
},
|
|
3779
|
+
],
|
|
3780
|
+
};
|
|
3781
|
+
}
|
|
3782
|
+
};
|
|
3783
|
+
const defaultOnSubmit = async (promise) => {
|
|
3784
|
+
try {
|
|
3785
|
+
onBeforeSubmit();
|
|
3786
|
+
await promise;
|
|
3787
|
+
onSubmitSuccess();
|
|
3788
|
+
}
|
|
3789
|
+
catch (error) {
|
|
3790
|
+
onSubmitError(error);
|
|
3791
|
+
}
|
|
3792
|
+
finally {
|
|
3793
|
+
onAfterSubmit();
|
|
3794
|
+
}
|
|
3795
|
+
};
|
|
3796
|
+
const defaultSubmitPromise = (data) => {
|
|
3797
|
+
const options = {
|
|
3798
|
+
method: 'POST',
|
|
3799
|
+
url: `${requestUrl}`,
|
|
3800
|
+
data: clearEmptyString(data),
|
|
3801
|
+
...requestOptions,
|
|
3802
|
+
};
|
|
3803
|
+
return axios.request(options);
|
|
3804
|
+
};
|
|
3805
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3806
|
+
const onFormSubmit = async (data) => {
|
|
3807
|
+
// Validate data using AJV before submission
|
|
3808
|
+
const validationResult = validateFormData(data);
|
|
3809
|
+
if (!validationResult.isValid) {
|
|
3810
|
+
// Set validation errors
|
|
3811
|
+
const validationErrorMessage = {
|
|
3812
|
+
type: 'validation',
|
|
3813
|
+
errors: validationResult.errors,
|
|
3814
|
+
message: translate.t('validation_error'),
|
|
3815
|
+
};
|
|
3816
|
+
onSubmitError(validationErrorMessage);
|
|
3817
|
+
return;
|
|
3818
|
+
}
|
|
3819
|
+
if (onSubmit === undefined) {
|
|
3820
|
+
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
3821
|
+
return;
|
|
3822
|
+
}
|
|
3823
|
+
await defaultOnSubmit(onSubmit(data));
|
|
3824
|
+
};
|
|
3748
3825
|
return (jsxRuntime.jsx(SchemaFormContext.Provider, { value: {
|
|
3749
3826
|
schema,
|
|
3750
3827
|
serverUrl,
|
|
@@ -3774,8 +3851,11 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3774
3851
|
customErrorRenderer,
|
|
3775
3852
|
customSuccessRenderer,
|
|
3776
3853
|
displayConfig,
|
|
3854
|
+
requireConfirmation,
|
|
3855
|
+
onFormSubmit,
|
|
3777
3856
|
dateTimePickerLabels,
|
|
3778
3857
|
idPickerLabels,
|
|
3858
|
+
enumPickerLabels,
|
|
3779
3859
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
|
|
3780
3860
|
};
|
|
3781
3861
|
|
|
@@ -4034,14 +4114,16 @@ dayjs.extend(utc);
|
|
|
4034
4114
|
dayjs.extend(timezone);
|
|
4035
4115
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
4036
4116
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4037
|
-
const { timezone } = useSchemaContext();
|
|
4117
|
+
const { timezone, dateTimePickerLabels } = useSchemaContext();
|
|
4038
4118
|
const formI18n = useFormI18n(column, prefix);
|
|
4039
|
-
const { required, gridColumn =
|
|
4119
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD', dateFormat = 'YYYY-MM-DD', } = schema;
|
|
4040
4120
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4041
4121
|
const colLabel = formI18n.colLabel;
|
|
4042
4122
|
const [open, setOpen] = React.useState(false);
|
|
4043
4123
|
const selectedDate = watch(colLabel);
|
|
4044
|
-
const displayDate = dayjs(selectedDate)
|
|
4124
|
+
const displayDate = dayjs(selectedDate)
|
|
4125
|
+
.tz(timezone)
|
|
4126
|
+
.format(displayDateFormat);
|
|
4045
4127
|
React.useEffect(() => {
|
|
4046
4128
|
try {
|
|
4047
4129
|
if (selectedDate) {
|
|
@@ -4065,45 +4147,83 @@ const DatePicker = ({ column, schema, prefix }) => {
|
|
|
4065
4147
|
console.error(e);
|
|
4066
4148
|
}
|
|
4067
4149
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4068
|
-
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems:
|
|
4150
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4069
4151
|
gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
4070
4152
|
setOpen(true);
|
|
4071
|
-
}, justifyContent:
|
|
4153
|
+
}, justifyContent: 'start', children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ''] }) }), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DatePicker$1, { selected: new Date(selectedDate), onDateSelected: ({ date }) => {
|
|
4072
4154
|
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
4073
4155
|
setOpen(false);
|
|
4074
4156
|
}, labels: {
|
|
4075
|
-
monthNamesShort: [
|
|
4076
|
-
formI18n.translate.t(`common.month_1`, {
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
formI18n.translate.t(`common.
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
formI18n.translate.t(`common.
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
formI18n.translate.t(`common.
|
|
4086
|
-
|
|
4087
|
-
|
|
4157
|
+
monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
|
|
4158
|
+
formI18n.translate.t(`common.month_1`, {
|
|
4159
|
+
defaultValue: 'January',
|
|
4160
|
+
}),
|
|
4161
|
+
formI18n.translate.t(`common.month_2`, {
|
|
4162
|
+
defaultValue: 'February',
|
|
4163
|
+
}),
|
|
4164
|
+
formI18n.translate.t(`common.month_3`, {
|
|
4165
|
+
defaultValue: 'March',
|
|
4166
|
+
}),
|
|
4167
|
+
formI18n.translate.t(`common.month_4`, {
|
|
4168
|
+
defaultValue: 'April',
|
|
4169
|
+
}),
|
|
4170
|
+
formI18n.translate.t(`common.month_5`, {
|
|
4171
|
+
defaultValue: 'May',
|
|
4172
|
+
}),
|
|
4173
|
+
formI18n.translate.t(`common.month_6`, {
|
|
4174
|
+
defaultValue: 'June',
|
|
4175
|
+
}),
|
|
4176
|
+
formI18n.translate.t(`common.month_7`, {
|
|
4177
|
+
defaultValue: 'July',
|
|
4178
|
+
}),
|
|
4179
|
+
formI18n.translate.t(`common.month_8`, {
|
|
4180
|
+
defaultValue: 'August',
|
|
4181
|
+
}),
|
|
4182
|
+
formI18n.translate.t(`common.month_9`, {
|
|
4183
|
+
defaultValue: 'September',
|
|
4184
|
+
}),
|
|
4185
|
+
formI18n.translate.t(`common.month_10`, {
|
|
4186
|
+
defaultValue: 'October',
|
|
4187
|
+
}),
|
|
4188
|
+
formI18n.translate.t(`common.month_11`, {
|
|
4189
|
+
defaultValue: 'November',
|
|
4190
|
+
}),
|
|
4191
|
+
formI18n.translate.t(`common.month_12`, {
|
|
4192
|
+
defaultValue: 'December',
|
|
4193
|
+
}),
|
|
4088
4194
|
],
|
|
4089
|
-
weekdayNamesShort: [
|
|
4090
|
-
formI18n.translate.t(`common.weekday_1`, {
|
|
4091
|
-
|
|
4092
|
-
|
|
4195
|
+
weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
|
|
4196
|
+
formI18n.translate.t(`common.weekday_1`, {
|
|
4197
|
+
defaultValue: 'Sun',
|
|
4198
|
+
}),
|
|
4199
|
+
formI18n.translate.t(`common.weekday_2`, {
|
|
4200
|
+
defaultValue: 'Mon',
|
|
4201
|
+
}),
|
|
4202
|
+
formI18n.translate.t(`common.weekday_3`, {
|
|
4203
|
+
defaultValue: 'Tue',
|
|
4204
|
+
}),
|
|
4093
4205
|
formI18n.translate.t(`common.weekday_4`, {
|
|
4094
|
-
defaultValue:
|
|
4206
|
+
defaultValue: 'Wed',
|
|
4207
|
+
}),
|
|
4208
|
+
formI18n.translate.t(`common.weekday_5`, {
|
|
4209
|
+
defaultValue: 'Thu',
|
|
4210
|
+
}),
|
|
4211
|
+
formI18n.translate.t(`common.weekday_6`, {
|
|
4212
|
+
defaultValue: 'Fri',
|
|
4213
|
+
}),
|
|
4214
|
+
formI18n.translate.t(`common.weekday_7`, {
|
|
4215
|
+
defaultValue: 'Sat',
|
|
4095
4216
|
}),
|
|
4096
|
-
formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4097
|
-
formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4098
|
-
formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4099
4217
|
],
|
|
4100
|
-
backButtonLabel:
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4218
|
+
backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
|
|
4219
|
+
formI18n.translate.t(`common.back_button`, {
|
|
4220
|
+
defaultValue: 'Back',
|
|
4221
|
+
}),
|
|
4222
|
+
forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
|
|
4223
|
+
formI18n.translate.t(`common.forward_button`, {
|
|
4224
|
+
defaultValue: 'Forward',
|
|
4225
|
+
}),
|
|
4226
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: formI18n.required() }))] }));
|
|
4107
4227
|
};
|
|
4108
4228
|
|
|
4109
4229
|
function filterArray(array, searchTerm) {
|
|
@@ -4118,10 +4238,10 @@ function filterArray(array, searchTerm) {
|
|
|
4118
4238
|
|
|
4119
4239
|
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
4120
4240
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4121
|
-
const { translate } = useSchemaContext();
|
|
4241
|
+
const { translate, enumPickerLabels } = useSchemaContext();
|
|
4122
4242
|
const { required, variant } = schema;
|
|
4123
4243
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4124
|
-
const { gridColumn =
|
|
4244
|
+
const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
|
|
4125
4245
|
const [searchText, setSearchText] = React.useState();
|
|
4126
4246
|
const [limit, setLimit] = React.useState(10);
|
|
4127
4247
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
@@ -4136,9 +4256,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4136
4256
|
setSearchText(event.target.value);
|
|
4137
4257
|
setLimit(10);
|
|
4138
4258
|
};
|
|
4139
|
-
if (variant ===
|
|
4140
|
-
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems:
|
|
4141
|
-
gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ??
|
|
4259
|
+
if (variant === 'radio') {
|
|
4260
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4261
|
+
gridRow, children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4142
4262
|
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4143
4263
|
if (!isMultiple) {
|
|
4144
4264
|
setOpenSearchResult(false);
|
|
@@ -4152,8 +4272,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4152
4272
|
: translate.t(removeIndex(`${colLabel}.${item}`)) })] }, `${colLabel}-${item}`));
|
|
4153
4273
|
}) }) }) }));
|
|
4154
4274
|
}
|
|
4155
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems:
|
|
4156
|
-
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow:
|
|
4275
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4276
|
+
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4157
4277
|
const item = enumValue;
|
|
4158
4278
|
if (!!item === false) {
|
|
4159
4279
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
@@ -4163,18 +4283,20 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4163
4283
|
}, children: !!renderDisplay === true
|
|
4164
4284
|
? renderDisplay(item)
|
|
4165
4285
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, item));
|
|
4166
|
-
}), jsxRuntime.jsx(Tag, { size: "lg", cursor:
|
|
4286
|
+
}), jsxRuntime.jsx(Tag, { size: "lg", cursor: 'pointer', onClick: () => {
|
|
4167
4287
|
setOpenSearchResult(true);
|
|
4168
|
-
}, children:
|
|
4288
|
+
}, children: enumPickerLabels?.addMore ??
|
|
4289
|
+
translate.t(removeIndex(`${colLabel}.add_more`)) }, `${colLabel}-add-more-tag`)] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: 'outline', onClick: () => {
|
|
4169
4290
|
setOpenSearchResult(true);
|
|
4170
|
-
}, justifyContent:
|
|
4171
|
-
?
|
|
4172
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum ??
|
|
4291
|
+
}, justifyContent: 'start', children: !!watchEnum === false
|
|
4292
|
+
? ''
|
|
4293
|
+
: translate.t(removeIndex(`${colLabel}.${watchEnum ?? 'null'}`)) })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: enumPickerLabels?.typeToSearch ??
|
|
4294
|
+
translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
4173
4295
|
onSearchChange(event);
|
|
4174
4296
|
setOpenSearchResult(true);
|
|
4175
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(removeIndex(`${colLabel}.total`))}: ${count}, ${translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` })), jsxRuntime.jsxs(react.Grid, { overflow:
|
|
4297
|
+
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${enumPickerLabels?.total ?? translate.t(removeIndex(`${colLabel}.total`))}: ${count}, ${enumPickerLabels?.showing ?? translate.t(removeIndex(`${colLabel}.showing`))} ${limit}` })), jsxRuntime.jsxs(react.Grid, { overflow: 'auto', maxHeight: '20rem', children: [jsxRuntime.jsx(react.Flex, { flexFlow: 'column wrap', children: dataList
|
|
4176
4298
|
.filter((item) => {
|
|
4177
|
-
const searchTerm = (searchText ||
|
|
4299
|
+
const searchTerm = (searchText || '').toLowerCase();
|
|
4178
4300
|
if (!searchTerm)
|
|
4179
4301
|
return true;
|
|
4180
4302
|
// Check if the original enum value contains the search text
|
|
@@ -4194,7 +4316,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4194
4316
|
const selected = isMultiple
|
|
4195
4317
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
4196
4318
|
: watchEnum == item;
|
|
4197
|
-
return (jsxRuntime.jsx(react.Box, { cursor:
|
|
4319
|
+
return (jsxRuntime.jsx(react.Box, { cursor: 'pointer', onClick: () => {
|
|
4198
4320
|
if (!isMultiple) {
|
|
4199
4321
|
setOpenSearchResult(false);
|
|
4200
4322
|
setValue(colLabel, item);
|
|
@@ -4202,10 +4324,11 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4202
4324
|
}
|
|
4203
4325
|
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4204
4326
|
setValue(colLabel, [...newSet]);
|
|
4205
|
-
}, ...(selected ? { color:
|
|
4327
|
+
}, ...(selected ? { color: 'colorPalette.400/50' } : {}), children: !!renderDisplay === true
|
|
4206
4328
|
? renderDisplay(item)
|
|
4207
4329
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
|
|
4208
|
-
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children:
|
|
4330
|
+
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4331
|
+
translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4209
4332
|
};
|
|
4210
4333
|
|
|
4211
4334
|
function isEnteringWindow(_ref) {
|
|
@@ -4830,13 +4953,13 @@ react.NumberInput.Label;
|
|
|
4830
4953
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4831
4954
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4832
4955
|
const { translate } = useSchemaContext();
|
|
4833
|
-
const { required, gridColumn =
|
|
4956
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
4834
4957
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4835
4958
|
const colLabel = `${prefix}${column}`;
|
|
4836
4959
|
const value = watch(`${colLabel}`);
|
|
4837
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(NumberInputRoot, {
|
|
4838
|
-
|
|
4839
|
-
|
|
4960
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
|
|
4961
|
+
setValue(`${colLabel}`, details.value); // Store as string to avoid floating-point precision issues
|
|
4962
|
+
}, min: schema.minimum, max: schema.maximum, step: schema.multipleOf || 0.01, allowOverflow: false, clampValueOnBlur: false, inputMode: "decimal", formatOptions: schema.formatOptions, children: jsxRuntime.jsx(NumberInputField$1, { required: isRequired }) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4840
4963
|
};
|
|
4841
4964
|
|
|
4842
4965
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
@@ -5778,11 +5901,29 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5778
5901
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
5779
5902
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5780
5903
|
const { translate } = useSchemaContext();
|
|
5781
|
-
const { required, gridColumn =
|
|
5904
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5782
5905
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5783
5906
|
const colLabel = `${prefix}${column}`;
|
|
5784
5907
|
const value = watch(colLabel);
|
|
5785
|
-
|
|
5908
|
+
// Format the value for display if formatOptions are provided
|
|
5909
|
+
const formatValue = (val) => {
|
|
5910
|
+
if (val === undefined || val === null || val === '')
|
|
5911
|
+
return '';
|
|
5912
|
+
const numValue = typeof val === 'string' ? parseFloat(val) : val;
|
|
5913
|
+
if (isNaN(numValue))
|
|
5914
|
+
return String(val);
|
|
5915
|
+
// Use formatOptions if available, otherwise display as-is
|
|
5916
|
+
if (schema.formatOptions) {
|
|
5917
|
+
try {
|
|
5918
|
+
return new Intl.NumberFormat(undefined, schema.formatOptions).format(numValue);
|
|
5919
|
+
}
|
|
5920
|
+
catch {
|
|
5921
|
+
return String(val);
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
return String(val);
|
|
5925
|
+
};
|
|
5926
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(react.Text, { children: formatValue(value) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5786
5927
|
};
|
|
5787
5928
|
|
|
5788
5929
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
@@ -6074,112 +6215,46 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
6074
6215
|
};
|
|
6075
6216
|
|
|
6076
6217
|
const SubmitButton = () => {
|
|
6077
|
-
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
6218
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, requireConfirmation, onFormSubmit, } = useSchemaContext();
|
|
6078
6219
|
const methods = reactHookForm.useFormContext();
|
|
6079
6220
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6080
6221
|
const onValid = (data) => {
|
|
6081
6222
|
const { isValid, errors } = validateData(data, schema);
|
|
6082
6223
|
if (!isValid) {
|
|
6083
6224
|
setError({
|
|
6084
|
-
type:
|
|
6225
|
+
type: 'validation',
|
|
6085
6226
|
errors,
|
|
6086
6227
|
});
|
|
6087
6228
|
setIsError(true);
|
|
6088
6229
|
return;
|
|
6089
6230
|
}
|
|
6090
|
-
// If validation passes,
|
|
6091
|
-
|
|
6092
|
-
|
|
6093
|
-
|
|
6231
|
+
// If validation passes, check if confirmation is required
|
|
6232
|
+
if (requireConfirmation) {
|
|
6233
|
+
// Show confirmation (existing behavior)
|
|
6234
|
+
setValidatedData(data);
|
|
6235
|
+
setIsError(false);
|
|
6236
|
+
setIsConfirming(true);
|
|
6237
|
+
}
|
|
6238
|
+
else {
|
|
6239
|
+
// Skip confirmation and submit directly
|
|
6240
|
+
setValidatedData(data);
|
|
6241
|
+
setIsError(false);
|
|
6242
|
+
onFormSubmit(data);
|
|
6243
|
+
}
|
|
6094
6244
|
};
|
|
6095
6245
|
return (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6096
6246
|
methods.handleSubmit(onValid)();
|
|
6097
|
-
}, formNoValidate: true, children: translate.t(
|
|
6247
|
+
}, formNoValidate: true, children: translate.t('submit') }));
|
|
6098
6248
|
};
|
|
6099
6249
|
|
|
6100
6250
|
const FormBody = () => {
|
|
6101
|
-
const { schema,
|
|
6251
|
+
const { schema, order, ignore, include, translate, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, onFormSubmit, } = useSchemaContext();
|
|
6102
6252
|
const { showSubmitButton, showResetButton } = displayConfig;
|
|
6103
6253
|
const methods = reactHookForm.useFormContext();
|
|
6104
6254
|
const { properties } = schema;
|
|
6105
|
-
const onBeforeSubmit = () => {
|
|
6106
|
-
setIsSubmiting(true);
|
|
6107
|
-
};
|
|
6108
|
-
const onAfterSubmit = () => {
|
|
6109
|
-
setIsSubmiting(false);
|
|
6110
|
-
};
|
|
6111
|
-
const onSubmitError = (error) => {
|
|
6112
|
-
setIsError(true);
|
|
6113
|
-
setError(error);
|
|
6114
|
-
};
|
|
6115
|
-
const onSubmitSuccess = () => {
|
|
6116
|
-
setIsSuccess(true);
|
|
6117
|
-
};
|
|
6118
|
-
const validateFormData = (data) => {
|
|
6119
|
-
try {
|
|
6120
|
-
const { isValid, errors } = validateData(data, schema);
|
|
6121
|
-
return {
|
|
6122
|
-
isValid,
|
|
6123
|
-
errors,
|
|
6124
|
-
};
|
|
6125
|
-
}
|
|
6126
|
-
catch (error) {
|
|
6127
|
-
return {
|
|
6128
|
-
isValid: false,
|
|
6129
|
-
errors: [
|
|
6130
|
-
{
|
|
6131
|
-
field: "validation",
|
|
6132
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
6133
|
-
},
|
|
6134
|
-
],
|
|
6135
|
-
};
|
|
6136
|
-
}
|
|
6137
|
-
};
|
|
6138
|
-
const defaultOnSubmit = async (promise) => {
|
|
6139
|
-
try {
|
|
6140
|
-
onBeforeSubmit();
|
|
6141
|
-
await promise;
|
|
6142
|
-
onSubmitSuccess();
|
|
6143
|
-
}
|
|
6144
|
-
catch (error) {
|
|
6145
|
-
onSubmitError(error);
|
|
6146
|
-
}
|
|
6147
|
-
finally {
|
|
6148
|
-
onAfterSubmit();
|
|
6149
|
-
}
|
|
6150
|
-
};
|
|
6151
|
-
const defaultSubmitPromise = (data) => {
|
|
6152
|
-
const options = {
|
|
6153
|
-
method: "POST",
|
|
6154
|
-
url: `${requestUrl}`,
|
|
6155
|
-
data: clearEmptyString(data),
|
|
6156
|
-
...requestOptions,
|
|
6157
|
-
};
|
|
6158
|
-
return axios.request(options);
|
|
6159
|
-
};
|
|
6160
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6161
|
-
const onFormSubmit = async (data) => {
|
|
6162
|
-
// Validate data using AJV before submission
|
|
6163
|
-
const validationResult = validateFormData(data);
|
|
6164
|
-
if (!validationResult.isValid) {
|
|
6165
|
-
// Set validation errors
|
|
6166
|
-
const validationErrorMessage = {
|
|
6167
|
-
type: "validation",
|
|
6168
|
-
errors: validationResult.errors,
|
|
6169
|
-
message: translate.t("validation_error"),
|
|
6170
|
-
};
|
|
6171
|
-
onSubmitError(validationErrorMessage);
|
|
6172
|
-
return;
|
|
6173
|
-
}
|
|
6174
|
-
if (onSubmit === undefined) {
|
|
6175
|
-
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
6176
|
-
return;
|
|
6177
|
-
}
|
|
6178
|
-
await defaultOnSubmit(onSubmit(data));
|
|
6179
|
-
};
|
|
6180
6255
|
// Custom error renderer for validation errors with i18n support
|
|
6181
6256
|
const renderValidationErrors = (validationErrors) => {
|
|
6182
|
-
return (jsxRuntime.jsx(react.Flex, { flexFlow:
|
|
6257
|
+
return (jsxRuntime.jsx(react.Flex, { flexFlow: 'column', gap: "2", children: validationErrors.map((err, index) => (jsxRuntime.jsxs(react.Alert.Root, { status: "error", display: "flex", alignItems: "center", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Description, { children: err.message }) })] }, index))) }));
|
|
6183
6258
|
};
|
|
6184
6259
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
6185
6260
|
const included = include.length > 0 ? include : keys;
|
|
@@ -6207,32 +6282,32 @@ const FormBody = () => {
|
|
|
6207
6282
|
if (customSuccessRenderer) {
|
|
6208
6283
|
return customSuccessRenderer(resetHandler);
|
|
6209
6284
|
}
|
|
6210
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow:
|
|
6285
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: 'column', gap: "2", children: [jsxRuntime.jsxs(react.Alert.Root, { status: "success", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsx(react.Alert.Content, { children: jsxRuntime.jsx(react.Alert.Title, { children: translate.t('submit_success') }) })] }), jsxRuntime.jsx(react.Flex, { justifyContent: 'end', children: jsxRuntime.jsx(react.Button, { onClick: resetHandler, formNoValidate: true, children: translate.t('submit_again') }) })] }));
|
|
6211
6286
|
}
|
|
6212
6287
|
if (isConfirming) {
|
|
6213
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow:
|
|
6288
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: 'column', gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: 4, gridTemplateColumns: 'repeat(12, 1fr)', gridTemplateRows: 'repeat(12, max-content)', autoFlow: 'row', children: ordered.map((column) => {
|
|
6214
6289
|
return (jsxRuntime.jsx(ColumnViewer
|
|
6215
6290
|
// @ts-expect-error find suitable types
|
|
6216
6291
|
, {
|
|
6217
6292
|
// @ts-expect-error find suitable types
|
|
6218
6293
|
properties: properties, prefix: ``, column }, `form-viewer-${column}`));
|
|
6219
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent:
|
|
6294
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: '2', children: [jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6220
6295
|
setIsConfirming(false);
|
|
6221
|
-
}, variant:
|
|
6296
|
+
}, variant: 'subtle', children: translate.t('cancel') }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6222
6297
|
onFormSubmit(validatedData);
|
|
6223
|
-
}, children: translate.t(
|
|
6224
|
-
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value:
|
|
6298
|
+
}, children: translate.t('confirm') })] }), isSubmiting && (jsxRuntime.jsx(react.Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsxRuntime.jsx(react.Center, { h: "full", children: jsxRuntime.jsx(react.Spinner, { color: "teal.500" }) }) })), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === 'validation' &&
|
|
6299
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: 'b', children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
6225
6300
|
}
|
|
6226
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow:
|
|
6301
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: 'column', gap: "2", children: [jsxRuntime.jsx(react.Grid, { gap: "4", gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: ordered.map((column) => {
|
|
6227
6302
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
6228
6303
|
// @ts-expect-error find suitable types
|
|
6229
6304
|
, {
|
|
6230
6305
|
// @ts-expect-error find suitable types
|
|
6231
6306
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
6232
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent:
|
|
6307
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6233
6308
|
methods.reset();
|
|
6234
|
-
}, variant:
|
|
6235
|
-
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value:
|
|
6309
|
+
}, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: error?.type === 'validation' &&
|
|
6310
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxRuntime.jsxs(react.Alert.Root, { status: "error", children: [jsxRuntime.jsx(react.Alert.Indicator, {}), jsxRuntime.jsxs(react.Alert.Content, { children: [jsxRuntime.jsx(react.Alert.Title, { children: "Error" }), jsxRuntime.jsx(react.Alert.Description, { children: jsxRuntime.jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxRuntime.jsxs(AccordionItem, { value: 'b', children: [jsxRuntime.jsx(AccordionItemTrigger, { children: `${error}` }), jsxRuntime.jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
6236
6311
|
};
|
|
6237
6312
|
|
|
6238
6313
|
const FormTitle = () => {
|