@bsol-oss/react-datatable5 12.0.0-beta.73 → 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/dist/index.d.ts +3 -1
- package/dist/index.js +136 -105
- package/dist/index.mjs +136 -105
- package/dist/types/components/Form/SchemaFormContext.d.ts +2 -0
- package/dist/types/components/Form/components/core/FormRoot.d.ts +2 -1
- package/dist/types/components/Form/components/fields/NumberInputField.d.ts +1 -1
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +1 -0
- package/dist/types/components/Form/components/viewers/NumberViewer.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -622,6 +622,7 @@ interface CustomJSONSchema7 extends JSONSchema7 {
|
|
|
622
622
|
timeFormat?: string;
|
|
623
623
|
displayTimeFormat?: string;
|
|
624
624
|
showLabel?: boolean;
|
|
625
|
+
formatOptions?: Intl.NumberFormatOptions;
|
|
625
626
|
}
|
|
626
627
|
interface TagPickerProps {
|
|
627
628
|
column: string;
|
|
@@ -652,6 +653,7 @@ interface FormRootProps<TData extends FieldValues> {
|
|
|
652
653
|
showResetButton?: boolean;
|
|
653
654
|
showTitle?: boolean;
|
|
654
655
|
};
|
|
656
|
+
requireConfirmation?: boolean;
|
|
655
657
|
dateTimePickerLabels?: DateTimePickerLabels;
|
|
656
658
|
idPickerLabels?: IdPickerLabels;
|
|
657
659
|
enumPickerLabels?: EnumPickerLabels;
|
|
@@ -671,7 +673,7 @@ declare const idPickerSanityCheck: (column: string, foreign_key?: {
|
|
|
671
673
|
column?: string | undefined;
|
|
672
674
|
display_column?: string | undefined;
|
|
673
675
|
} | undefined) => void;
|
|
674
|
-
declare const FormRoot: <TData extends FieldValues>({ schema, idMap, setIdMap, form, serverUrl, translate, children, order, ignore, include, onSubmit, rowNumber, requestOptions, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }: FormRootProps<TData>) => react_jsx_runtime.JSX.Element;
|
|
676
|
+
declare const FormRoot: <TData extends FieldValues>({ schema, idMap, setIdMap, form, serverUrl, translate, children, order, ignore, include, onSubmit, rowNumber, requestOptions, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, requireConfirmation, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }: FormRootProps<TData>) => react_jsx_runtime.JSX.Element;
|
|
675
677
|
|
|
676
678
|
interface DefaultFormProps<TData extends FieldValues> {
|
|
677
679
|
formConfig: Omit<FormRootProps<TData>, "children">;
|
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, enumPickerLabels, }) => {
|
|
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,6 +3851,8 @@ 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,
|
|
3779
3858
|
enumPickerLabels,
|
|
@@ -4874,13 +4953,13 @@ react.NumberInput.Label;
|
|
|
4874
4953
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4875
4954
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4876
4955
|
const { translate } = useSchemaContext();
|
|
4877
|
-
const { required, gridColumn =
|
|
4956
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
4878
4957
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4879
4958
|
const colLabel = `${prefix}${column}`;
|
|
4880
4959
|
const value = watch(`${colLabel}`);
|
|
4881
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsxRuntime.jsx(NumberInputRoot, {
|
|
4882
|
-
|
|
4883
|
-
|
|
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`)) }))] }));
|
|
4884
4963
|
};
|
|
4885
4964
|
|
|
4886
4965
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
@@ -5822,11 +5901,29 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5822
5901
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
5823
5902
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5824
5903
|
const { translate } = useSchemaContext();
|
|
5825
|
-
const { required, gridColumn =
|
|
5904
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5826
5905
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5827
5906
|
const colLabel = `${prefix}${column}`;
|
|
5828
5907
|
const value = watch(colLabel);
|
|
5829
|
-
|
|
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`)) }))] }));
|
|
5830
5927
|
};
|
|
5831
5928
|
|
|
5832
5929
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
@@ -6118,112 +6215,46 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
6118
6215
|
};
|
|
6119
6216
|
|
|
6120
6217
|
const SubmitButton = () => {
|
|
6121
|
-
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
6218
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, requireConfirmation, onFormSubmit, } = useSchemaContext();
|
|
6122
6219
|
const methods = reactHookForm.useFormContext();
|
|
6123
6220
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6124
6221
|
const onValid = (data) => {
|
|
6125
6222
|
const { isValid, errors } = validateData(data, schema);
|
|
6126
6223
|
if (!isValid) {
|
|
6127
6224
|
setError({
|
|
6128
|
-
type:
|
|
6225
|
+
type: 'validation',
|
|
6129
6226
|
errors,
|
|
6130
6227
|
});
|
|
6131
6228
|
setIsError(true);
|
|
6132
6229
|
return;
|
|
6133
6230
|
}
|
|
6134
|
-
// If validation passes,
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
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
|
+
}
|
|
6138
6244
|
};
|
|
6139
6245
|
return (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6140
6246
|
methods.handleSubmit(onValid)();
|
|
6141
|
-
}, formNoValidate: true, children: translate.t(
|
|
6247
|
+
}, formNoValidate: true, children: translate.t('submit') }));
|
|
6142
6248
|
};
|
|
6143
6249
|
|
|
6144
6250
|
const FormBody = () => {
|
|
6145
|
-
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();
|
|
6146
6252
|
const { showSubmitButton, showResetButton } = displayConfig;
|
|
6147
6253
|
const methods = reactHookForm.useFormContext();
|
|
6148
6254
|
const { properties } = schema;
|
|
6149
|
-
const onBeforeSubmit = () => {
|
|
6150
|
-
setIsSubmiting(true);
|
|
6151
|
-
};
|
|
6152
|
-
const onAfterSubmit = () => {
|
|
6153
|
-
setIsSubmiting(false);
|
|
6154
|
-
};
|
|
6155
|
-
const onSubmitError = (error) => {
|
|
6156
|
-
setIsError(true);
|
|
6157
|
-
setError(error);
|
|
6158
|
-
};
|
|
6159
|
-
const onSubmitSuccess = () => {
|
|
6160
|
-
setIsSuccess(true);
|
|
6161
|
-
};
|
|
6162
|
-
const validateFormData = (data) => {
|
|
6163
|
-
try {
|
|
6164
|
-
const { isValid, errors } = validateData(data, schema);
|
|
6165
|
-
return {
|
|
6166
|
-
isValid,
|
|
6167
|
-
errors,
|
|
6168
|
-
};
|
|
6169
|
-
}
|
|
6170
|
-
catch (error) {
|
|
6171
|
-
return {
|
|
6172
|
-
isValid: false,
|
|
6173
|
-
errors: [
|
|
6174
|
-
{
|
|
6175
|
-
field: "validation",
|
|
6176
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
6177
|
-
},
|
|
6178
|
-
],
|
|
6179
|
-
};
|
|
6180
|
-
}
|
|
6181
|
-
};
|
|
6182
|
-
const defaultOnSubmit = async (promise) => {
|
|
6183
|
-
try {
|
|
6184
|
-
onBeforeSubmit();
|
|
6185
|
-
await promise;
|
|
6186
|
-
onSubmitSuccess();
|
|
6187
|
-
}
|
|
6188
|
-
catch (error) {
|
|
6189
|
-
onSubmitError(error);
|
|
6190
|
-
}
|
|
6191
|
-
finally {
|
|
6192
|
-
onAfterSubmit();
|
|
6193
|
-
}
|
|
6194
|
-
};
|
|
6195
|
-
const defaultSubmitPromise = (data) => {
|
|
6196
|
-
const options = {
|
|
6197
|
-
method: "POST",
|
|
6198
|
-
url: `${requestUrl}`,
|
|
6199
|
-
data: clearEmptyString(data),
|
|
6200
|
-
...requestOptions,
|
|
6201
|
-
};
|
|
6202
|
-
return axios.request(options);
|
|
6203
|
-
};
|
|
6204
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6205
|
-
const onFormSubmit = async (data) => {
|
|
6206
|
-
// Validate data using AJV before submission
|
|
6207
|
-
const validationResult = validateFormData(data);
|
|
6208
|
-
if (!validationResult.isValid) {
|
|
6209
|
-
// Set validation errors
|
|
6210
|
-
const validationErrorMessage = {
|
|
6211
|
-
type: "validation",
|
|
6212
|
-
errors: validationResult.errors,
|
|
6213
|
-
message: translate.t("validation_error"),
|
|
6214
|
-
};
|
|
6215
|
-
onSubmitError(validationErrorMessage);
|
|
6216
|
-
return;
|
|
6217
|
-
}
|
|
6218
|
-
if (onSubmit === undefined) {
|
|
6219
|
-
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
6220
|
-
return;
|
|
6221
|
-
}
|
|
6222
|
-
await defaultOnSubmit(onSubmit(data));
|
|
6223
|
-
};
|
|
6224
6255
|
// Custom error renderer for validation errors with i18n support
|
|
6225
6256
|
const renderValidationErrors = (validationErrors) => {
|
|
6226
|
-
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))) }));
|
|
6227
6258
|
};
|
|
6228
6259
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
6229
6260
|
const included = include.length > 0 ? include : keys;
|
|
@@ -6251,32 +6282,32 @@ const FormBody = () => {
|
|
|
6251
6282
|
if (customSuccessRenderer) {
|
|
6252
6283
|
return customSuccessRenderer(resetHandler);
|
|
6253
6284
|
}
|
|
6254
|
-
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') }) })] }));
|
|
6255
6286
|
}
|
|
6256
6287
|
if (isConfirming) {
|
|
6257
|
-
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) => {
|
|
6258
6289
|
return (jsxRuntime.jsx(ColumnViewer
|
|
6259
6290
|
// @ts-expect-error find suitable types
|
|
6260
6291
|
, {
|
|
6261
6292
|
// @ts-expect-error find suitable types
|
|
6262
6293
|
properties: properties, prefix: ``, column }, `form-viewer-${column}`));
|
|
6263
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent:
|
|
6294
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: '2', children: [jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6264
6295
|
setIsConfirming(false);
|
|
6265
|
-
}, variant:
|
|
6296
|
+
}, variant: 'subtle', children: translate.t('cancel') }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6266
6297
|
onFormSubmit(validatedData);
|
|
6267
|
-
}, children: translate.t(
|
|
6268
|
-
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)}` })] }) }) })] })] })) })) }))] }));
|
|
6269
6300
|
}
|
|
6270
|
-
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) => {
|
|
6271
6302
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
6272
6303
|
// @ts-expect-error find suitable types
|
|
6273
6304
|
, {
|
|
6274
6305
|
// @ts-expect-error find suitable types
|
|
6275
6306
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
6276
|
-
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent:
|
|
6307
|
+
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6277
6308
|
methods.reset();
|
|
6278
|
-
}, variant:
|
|
6279
|
-
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)}` })] }) }) })] })] })) })) }))] }));
|
|
6280
6311
|
};
|
|
6281
6312
|
|
|
6282
6313
|
const FormTitle = () => {
|
package/dist/index.mjs
CHANGED
|
@@ -3671,16 +3671,14 @@ const SchemaFormContext = createContext({
|
|
|
3671
3671
|
showResetButton: true,
|
|
3672
3672
|
showTitle: true,
|
|
3673
3673
|
},
|
|
3674
|
+
requireConfirmation: false,
|
|
3675
|
+
onFormSubmit: async () => { },
|
|
3674
3676
|
});
|
|
3675
3677
|
|
|
3676
3678
|
const useSchemaContext = () => {
|
|
3677
3679
|
return useContext(SchemaFormContext);
|
|
3678
3680
|
};
|
|
3679
3681
|
|
|
3680
|
-
const clearEmptyString = (object) => {
|
|
3681
|
-
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3682
|
-
};
|
|
3683
|
-
|
|
3684
3682
|
const validateData = (data, schema) => {
|
|
3685
3683
|
const ajv = new Ajv({
|
|
3686
3684
|
strict: false,
|
|
@@ -3699,6 +3697,10 @@ const validateData = (data, schema) => {
|
|
|
3699
3697
|
};
|
|
3700
3698
|
};
|
|
3701
3699
|
|
|
3700
|
+
const clearEmptyString = (object) => {
|
|
3701
|
+
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3702
|
+
};
|
|
3703
|
+
|
|
3702
3704
|
const idPickerSanityCheck = (column, foreign_key) => {
|
|
3703
3705
|
if (!!foreign_key == false) {
|
|
3704
3706
|
throw new Error(`The key foreign_key does not exist in properties of column ${column} when using id-picker.`);
|
|
@@ -3718,13 +3720,88 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3718
3720
|
showSubmitButton: true,
|
|
3719
3721
|
showResetButton: true,
|
|
3720
3722
|
showTitle: true,
|
|
3721
|
-
}, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }) => {
|
|
3723
|
+
}, requireConfirmation = false, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }) => {
|
|
3722
3724
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
3723
3725
|
const [isError, setIsError] = useState(false);
|
|
3724
3726
|
const [isSubmiting, setIsSubmiting] = useState(false);
|
|
3725
3727
|
const [isConfirming, setIsConfirming] = useState(false);
|
|
3726
3728
|
const [validatedData, setValidatedData] = useState();
|
|
3727
3729
|
const [error, setError] = useState();
|
|
3730
|
+
const onBeforeSubmit = () => {
|
|
3731
|
+
setIsSubmiting(true);
|
|
3732
|
+
};
|
|
3733
|
+
const onAfterSubmit = () => {
|
|
3734
|
+
setIsSubmiting(false);
|
|
3735
|
+
};
|
|
3736
|
+
const onSubmitError = (error) => {
|
|
3737
|
+
setIsError(true);
|
|
3738
|
+
setError(error);
|
|
3739
|
+
};
|
|
3740
|
+
const onSubmitSuccess = () => {
|
|
3741
|
+
setIsSuccess(true);
|
|
3742
|
+
};
|
|
3743
|
+
const validateFormData = (data) => {
|
|
3744
|
+
try {
|
|
3745
|
+
const { isValid, errors } = validateData(data, schema);
|
|
3746
|
+
return {
|
|
3747
|
+
isValid,
|
|
3748
|
+
errors,
|
|
3749
|
+
};
|
|
3750
|
+
}
|
|
3751
|
+
catch (error) {
|
|
3752
|
+
return {
|
|
3753
|
+
isValid: false,
|
|
3754
|
+
errors: [
|
|
3755
|
+
{
|
|
3756
|
+
field: 'validation',
|
|
3757
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
3758
|
+
},
|
|
3759
|
+
],
|
|
3760
|
+
};
|
|
3761
|
+
}
|
|
3762
|
+
};
|
|
3763
|
+
const defaultOnSubmit = async (promise) => {
|
|
3764
|
+
try {
|
|
3765
|
+
onBeforeSubmit();
|
|
3766
|
+
await promise;
|
|
3767
|
+
onSubmitSuccess();
|
|
3768
|
+
}
|
|
3769
|
+
catch (error) {
|
|
3770
|
+
onSubmitError(error);
|
|
3771
|
+
}
|
|
3772
|
+
finally {
|
|
3773
|
+
onAfterSubmit();
|
|
3774
|
+
}
|
|
3775
|
+
};
|
|
3776
|
+
const defaultSubmitPromise = (data) => {
|
|
3777
|
+
const options = {
|
|
3778
|
+
method: 'POST',
|
|
3779
|
+
url: `${requestUrl}`,
|
|
3780
|
+
data: clearEmptyString(data),
|
|
3781
|
+
...requestOptions,
|
|
3782
|
+
};
|
|
3783
|
+
return axios.request(options);
|
|
3784
|
+
};
|
|
3785
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3786
|
+
const onFormSubmit = async (data) => {
|
|
3787
|
+
// Validate data using AJV before submission
|
|
3788
|
+
const validationResult = validateFormData(data);
|
|
3789
|
+
if (!validationResult.isValid) {
|
|
3790
|
+
// Set validation errors
|
|
3791
|
+
const validationErrorMessage = {
|
|
3792
|
+
type: 'validation',
|
|
3793
|
+
errors: validationResult.errors,
|
|
3794
|
+
message: translate.t('validation_error'),
|
|
3795
|
+
};
|
|
3796
|
+
onSubmitError(validationErrorMessage);
|
|
3797
|
+
return;
|
|
3798
|
+
}
|
|
3799
|
+
if (onSubmit === undefined) {
|
|
3800
|
+
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
3801
|
+
return;
|
|
3802
|
+
}
|
|
3803
|
+
await defaultOnSubmit(onSubmit(data));
|
|
3804
|
+
};
|
|
3728
3805
|
return (jsx(SchemaFormContext.Provider, { value: {
|
|
3729
3806
|
schema,
|
|
3730
3807
|
serverUrl,
|
|
@@ -3754,6 +3831,8 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3754
3831
|
customErrorRenderer,
|
|
3755
3832
|
customSuccessRenderer,
|
|
3756
3833
|
displayConfig,
|
|
3834
|
+
requireConfirmation,
|
|
3835
|
+
onFormSubmit,
|
|
3757
3836
|
dateTimePickerLabels,
|
|
3758
3837
|
idPickerLabels,
|
|
3759
3838
|
enumPickerLabels,
|
|
@@ -4854,13 +4933,13 @@ NumberInput.Label;
|
|
|
4854
4933
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4855
4934
|
const { setValue, formState: { errors }, watch, } = useFormContext();
|
|
4856
4935
|
const { translate } = useSchemaContext();
|
|
4857
|
-
const { required, gridColumn =
|
|
4936
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
4858
4937
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4859
4938
|
const colLabel = `${prefix}${column}`;
|
|
4860
4939
|
const value = watch(`${colLabel}`);
|
|
4861
|
-
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(NumberInputRoot, {
|
|
4862
|
-
|
|
4863
|
-
|
|
4940
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
|
|
4941
|
+
setValue(`${colLabel}`, details.value); // Store as string to avoid floating-point precision issues
|
|
4942
|
+
}, min: schema.minimum, max: schema.maximum, step: schema.multipleOf || 0.01, allowOverflow: false, clampValueOnBlur: false, inputMode: "decimal", formatOptions: schema.formatOptions, children: jsx(NumberInputField$1, { required: isRequired }) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4864
4943
|
};
|
|
4865
4944
|
|
|
4866
4945
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
@@ -5802,11 +5881,29 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5802
5881
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
5803
5882
|
const { watch, formState: { errors }, } = useFormContext();
|
|
5804
5883
|
const { translate } = useSchemaContext();
|
|
5805
|
-
const { required, gridColumn =
|
|
5884
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5806
5885
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5807
5886
|
const colLabel = `${prefix}${column}`;
|
|
5808
5887
|
const value = watch(colLabel);
|
|
5809
|
-
|
|
5888
|
+
// Format the value for display if formatOptions are provided
|
|
5889
|
+
const formatValue = (val) => {
|
|
5890
|
+
if (val === undefined || val === null || val === '')
|
|
5891
|
+
return '';
|
|
5892
|
+
const numValue = typeof val === 'string' ? parseFloat(val) : val;
|
|
5893
|
+
if (isNaN(numValue))
|
|
5894
|
+
return String(val);
|
|
5895
|
+
// Use formatOptions if available, otherwise display as-is
|
|
5896
|
+
if (schema.formatOptions) {
|
|
5897
|
+
try {
|
|
5898
|
+
return new Intl.NumberFormat(undefined, schema.formatOptions).format(numValue);
|
|
5899
|
+
}
|
|
5900
|
+
catch {
|
|
5901
|
+
return String(val);
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
return String(val);
|
|
5905
|
+
};
|
|
5906
|
+
return (jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, children: [jsx(Text, { children: formatValue(value) }), errors[`${column}`] && (jsx(Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
5810
5907
|
};
|
|
5811
5908
|
|
|
5812
5909
|
const ObjectViewer = ({ schema, column, prefix }) => {
|
|
@@ -6098,112 +6195,46 @@ const ColumnViewer = ({ column, properties, prefix, }) => {
|
|
|
6098
6195
|
};
|
|
6099
6196
|
|
|
6100
6197
|
const SubmitButton = () => {
|
|
6101
|
-
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, } = useSchemaContext();
|
|
6198
|
+
const { translate, setValidatedData, setIsError, setIsConfirming, setError, schema, requireConfirmation, onFormSubmit, } = useSchemaContext();
|
|
6102
6199
|
const methods = useFormContext();
|
|
6103
6200
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6104
6201
|
const onValid = (data) => {
|
|
6105
6202
|
const { isValid, errors } = validateData(data, schema);
|
|
6106
6203
|
if (!isValid) {
|
|
6107
6204
|
setError({
|
|
6108
|
-
type:
|
|
6205
|
+
type: 'validation',
|
|
6109
6206
|
errors,
|
|
6110
6207
|
});
|
|
6111
6208
|
setIsError(true);
|
|
6112
6209
|
return;
|
|
6113
6210
|
}
|
|
6114
|
-
// If validation passes,
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6211
|
+
// If validation passes, check if confirmation is required
|
|
6212
|
+
if (requireConfirmation) {
|
|
6213
|
+
// Show confirmation (existing behavior)
|
|
6214
|
+
setValidatedData(data);
|
|
6215
|
+
setIsError(false);
|
|
6216
|
+
setIsConfirming(true);
|
|
6217
|
+
}
|
|
6218
|
+
else {
|
|
6219
|
+
// Skip confirmation and submit directly
|
|
6220
|
+
setValidatedData(data);
|
|
6221
|
+
setIsError(false);
|
|
6222
|
+
onFormSubmit(data);
|
|
6223
|
+
}
|
|
6118
6224
|
};
|
|
6119
6225
|
return (jsx(Button$1, { onClick: () => {
|
|
6120
6226
|
methods.handleSubmit(onValid)();
|
|
6121
|
-
}, formNoValidate: true, children: translate.t(
|
|
6227
|
+
}, formNoValidate: true, children: translate.t('submit') }));
|
|
6122
6228
|
};
|
|
6123
6229
|
|
|
6124
6230
|
const FormBody = () => {
|
|
6125
|
-
const { schema,
|
|
6231
|
+
const { schema, order, ignore, include, translate, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, onFormSubmit, } = useSchemaContext();
|
|
6126
6232
|
const { showSubmitButton, showResetButton } = displayConfig;
|
|
6127
6233
|
const methods = useFormContext();
|
|
6128
6234
|
const { properties } = schema;
|
|
6129
|
-
const onBeforeSubmit = () => {
|
|
6130
|
-
setIsSubmiting(true);
|
|
6131
|
-
};
|
|
6132
|
-
const onAfterSubmit = () => {
|
|
6133
|
-
setIsSubmiting(false);
|
|
6134
|
-
};
|
|
6135
|
-
const onSubmitError = (error) => {
|
|
6136
|
-
setIsError(true);
|
|
6137
|
-
setError(error);
|
|
6138
|
-
};
|
|
6139
|
-
const onSubmitSuccess = () => {
|
|
6140
|
-
setIsSuccess(true);
|
|
6141
|
-
};
|
|
6142
|
-
const validateFormData = (data) => {
|
|
6143
|
-
try {
|
|
6144
|
-
const { isValid, errors } = validateData(data, schema);
|
|
6145
|
-
return {
|
|
6146
|
-
isValid,
|
|
6147
|
-
errors,
|
|
6148
|
-
};
|
|
6149
|
-
}
|
|
6150
|
-
catch (error) {
|
|
6151
|
-
return {
|
|
6152
|
-
isValid: false,
|
|
6153
|
-
errors: [
|
|
6154
|
-
{
|
|
6155
|
-
field: "validation",
|
|
6156
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
6157
|
-
},
|
|
6158
|
-
],
|
|
6159
|
-
};
|
|
6160
|
-
}
|
|
6161
|
-
};
|
|
6162
|
-
const defaultOnSubmit = async (promise) => {
|
|
6163
|
-
try {
|
|
6164
|
-
onBeforeSubmit();
|
|
6165
|
-
await promise;
|
|
6166
|
-
onSubmitSuccess();
|
|
6167
|
-
}
|
|
6168
|
-
catch (error) {
|
|
6169
|
-
onSubmitError(error);
|
|
6170
|
-
}
|
|
6171
|
-
finally {
|
|
6172
|
-
onAfterSubmit();
|
|
6173
|
-
}
|
|
6174
|
-
};
|
|
6175
|
-
const defaultSubmitPromise = (data) => {
|
|
6176
|
-
const options = {
|
|
6177
|
-
method: "POST",
|
|
6178
|
-
url: `${requestUrl}`,
|
|
6179
|
-
data: clearEmptyString(data),
|
|
6180
|
-
...requestOptions,
|
|
6181
|
-
};
|
|
6182
|
-
return axios.request(options);
|
|
6183
|
-
};
|
|
6184
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6185
|
-
const onFormSubmit = async (data) => {
|
|
6186
|
-
// Validate data using AJV before submission
|
|
6187
|
-
const validationResult = validateFormData(data);
|
|
6188
|
-
if (!validationResult.isValid) {
|
|
6189
|
-
// Set validation errors
|
|
6190
|
-
const validationErrorMessage = {
|
|
6191
|
-
type: "validation",
|
|
6192
|
-
errors: validationResult.errors,
|
|
6193
|
-
message: translate.t("validation_error"),
|
|
6194
|
-
};
|
|
6195
|
-
onSubmitError(validationErrorMessage);
|
|
6196
|
-
return;
|
|
6197
|
-
}
|
|
6198
|
-
if (onSubmit === undefined) {
|
|
6199
|
-
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
6200
|
-
return;
|
|
6201
|
-
}
|
|
6202
|
-
await defaultOnSubmit(onSubmit(data));
|
|
6203
|
-
};
|
|
6204
6235
|
// Custom error renderer for validation errors with i18n support
|
|
6205
6236
|
const renderValidationErrors = (validationErrors) => {
|
|
6206
|
-
return (jsx(Flex, { flexFlow:
|
|
6237
|
+
return (jsx(Flex, { flexFlow: 'column', gap: "2", children: validationErrors.map((err, index) => (jsxs(Alert.Root, { status: "error", display: "flex", alignItems: "center", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Description, { children: err.message }) })] }, index))) }));
|
|
6207
6238
|
};
|
|
6208
6239
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
6209
6240
|
const included = include.length > 0 ? include : keys;
|
|
@@ -6231,32 +6262,32 @@ const FormBody = () => {
|
|
|
6231
6262
|
if (customSuccessRenderer) {
|
|
6232
6263
|
return customSuccessRenderer(resetHandler);
|
|
6233
6264
|
}
|
|
6234
|
-
return (jsxs(Flex, { flexFlow:
|
|
6265
|
+
return (jsxs(Flex, { flexFlow: 'column', gap: "2", children: [jsxs(Alert.Root, { status: "success", children: [jsx(Alert.Indicator, {}), jsx(Alert.Content, { children: jsx(Alert.Title, { children: translate.t('submit_success') }) })] }), jsx(Flex, { justifyContent: 'end', children: jsx(Button$1, { onClick: resetHandler, formNoValidate: true, children: translate.t('submit_again') }) })] }));
|
|
6235
6266
|
}
|
|
6236
6267
|
if (isConfirming) {
|
|
6237
|
-
return (jsxs(Flex, { flexFlow:
|
|
6268
|
+
return (jsxs(Flex, { flexFlow: 'column', gap: "2", children: [jsx(Grid, { gap: 4, gridTemplateColumns: 'repeat(12, 1fr)', gridTemplateRows: 'repeat(12, max-content)', autoFlow: 'row', children: ordered.map((column) => {
|
|
6238
6269
|
return (jsx(ColumnViewer
|
|
6239
6270
|
// @ts-expect-error find suitable types
|
|
6240
6271
|
, {
|
|
6241
6272
|
// @ts-expect-error find suitable types
|
|
6242
6273
|
properties: properties, prefix: ``, column }, `form-viewer-${column}`));
|
|
6243
|
-
}) }), jsxs(Flex, { justifyContent:
|
|
6274
|
+
}) }), jsxs(Flex, { justifyContent: 'end', gap: '2', children: [jsx(Button$1, { onClick: () => {
|
|
6244
6275
|
setIsConfirming(false);
|
|
6245
|
-
}, variant:
|
|
6276
|
+
}, variant: 'subtle', children: translate.t('cancel') }), jsx(Button$1, { onClick: () => {
|
|
6246
6277
|
onFormSubmit(validatedData);
|
|
6247
|
-
}, children: translate.t(
|
|
6248
|
-
error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value:
|
|
6278
|
+
}, children: translate.t('confirm') })] }), isSubmiting && (jsx(Box, { pos: "absolute", inset: "0", bg: "bg/80", children: jsx(Center, { h: "full", children: jsx(Spinner, { color: "teal.500" }) }) })), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === 'validation' &&
|
|
6279
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: 'b', children: [jsx(AccordionItemTrigger, { children: `${error}` }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
6249
6280
|
}
|
|
6250
|
-
return (jsxs(Flex, { flexFlow:
|
|
6281
|
+
return (jsxs(Flex, { flexFlow: 'column', gap: "2", children: [jsx(Grid, { gap: "4", gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: ordered.map((column) => {
|
|
6251
6282
|
return (jsx(ColumnRenderer
|
|
6252
6283
|
// @ts-expect-error find suitable types
|
|
6253
6284
|
, {
|
|
6254
6285
|
// @ts-expect-error find suitable types
|
|
6255
6286
|
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
6256
|
-
}) }), jsxs(Flex, { justifyContent:
|
|
6287
|
+
}) }), jsxs(Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsx(Button$1, { onClick: () => {
|
|
6257
6288
|
methods.reset();
|
|
6258
|
-
}, variant:
|
|
6259
|
-
error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value:
|
|
6289
|
+
}, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsx(SubmitButton, {})] }), isError && (jsx(Fragment, { children: customErrorRenderer ? (customErrorRenderer(error)) : (jsx(Fragment, { children: error?.type === 'validation' &&
|
|
6290
|
+
error?.errors ? (renderValidationErrors(error.errors)) : (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: "Error" }), jsx(Alert.Description, { children: jsx(AccordionRoot, { collapsible: true, defaultValue: [], children: jsxs(AccordionItem, { value: 'b', children: [jsx(AccordionItemTrigger, { children: `${error}` }), jsx(AccordionItemContent, { children: `${JSON.stringify(error)}` })] }) }) })] })] })) })) }))] }));
|
|
6260
6291
|
};
|
|
6261
6292
|
|
|
6262
6293
|
const FormTitle = () => {
|
|
@@ -38,6 +38,8 @@ export interface SchemaFormContext<TData extends FieldValues> {
|
|
|
38
38
|
showResetButton?: boolean;
|
|
39
39
|
showTitle?: boolean;
|
|
40
40
|
};
|
|
41
|
+
requireConfirmation: boolean;
|
|
42
|
+
onFormSubmit: (data: TData) => Promise<void>;
|
|
41
43
|
dateTimePickerLabels?: DateTimePickerLabels;
|
|
42
44
|
idPickerLabels?: IdPickerLabels;
|
|
43
45
|
enumPickerLabels?: EnumPickerLabels;
|
|
@@ -28,6 +28,7 @@ export interface FormRootProps<TData extends FieldValues> {
|
|
|
28
28
|
showResetButton?: boolean;
|
|
29
29
|
showTitle?: boolean;
|
|
30
30
|
};
|
|
31
|
+
requireConfirmation?: boolean;
|
|
31
32
|
dateTimePickerLabels?: DateTimePickerLabels;
|
|
32
33
|
idPickerLabels?: IdPickerLabels;
|
|
33
34
|
enumPickerLabels?: EnumPickerLabels;
|
|
@@ -47,4 +48,4 @@ export declare const idPickerSanityCheck: (column: string, foreign_key?: {
|
|
|
47
48
|
column?: string | undefined;
|
|
48
49
|
display_column?: string | undefined;
|
|
49
50
|
} | undefined) => void;
|
|
50
|
-
export declare const FormRoot: <TData extends FieldValues>({ schema, idMap, setIdMap, form, serverUrl, translate, children, order, ignore, include, onSubmit, rowNumber, requestOptions, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }: FormRootProps<TData>) => import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare const FormRoot: <TData extends FieldValues>({ schema, idMap, setIdMap, form, serverUrl, translate, children, order, ignore, include, onSubmit, rowNumber, requestOptions, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, requireConfirmation, dateTimePickerLabels, idPickerLabels, enumPickerLabels, }: FormRootProps<TData>) => import("react/jsx-runtime").JSX.Element;
|