@bsol-oss/react-datatable5 12.0.0-beta.74 → 12.0.0-beta.75
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 +133 -126
- package/dist/index.js +567 -253
- package/dist/index.mjs +569 -256
- package/dist/types/components/Form/SchemaFormContext.d.ts +3 -2
- package/dist/types/components/Form/components/fields/BooleanPicker.d.ts +1 -1
- package/dist/types/components/Form/components/fields/ColumnRenderer.d.ts +3 -2
- package/dist/types/components/Form/components/fields/DateTimePicker.d.ts +1 -1
- package/dist/types/components/Form/components/fields/FilePicker.d.ts +1 -1
- package/dist/types/components/Form/components/fields/ObjectInput.d.ts +1 -1
- package/dist/types/components/Form/components/fields/RecordInput.d.ts +1 -1
- package/dist/types/components/Form/components/fields/StringInputField.d.ts +1 -1
- package/dist/types/components/Form/components/fields/TextAreaInput.d.ts +1 -1
- package/dist/types/components/Form/components/fields/TimePicker.d.ts +1 -1
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +3 -0
- package/dist/types/components/Form/useForm.d.ts +4 -2
- package/dist/types/components/Form/utils/ajvResolver.d.ts +13 -0
- package/dist/types/components/Form/utils/buildErrorMessages.d.ts +5 -1
- package/dist/types/components/Form/utils/getFieldError.d.ts +6 -0
- package/dist/types/components/Form/utils/useFormI18n.d.ts +1 -1
- package/dist/types/components/Form/utils/validateData.d.ts +2 -2
- package/dist/types/components/ui/field.d.ts +3 -3
- package/package.json +1 -1
- package/dist/types/components/Controls/DensityFeature.d.ts +0 -23
- package/dist/types/components/Controls/DensityToggleButton.d.ts +0 -6
- package/dist/types/components/Controls/EditFilterButton.d.ts +0 -9
- package/dist/types/components/Controls/EditOrderButton.d.ts +0 -7
- package/dist/types/components/Controls/EditSortingButton.d.ts +0 -7
- package/dist/types/components/Controls/EditViewButton.d.ts +0 -7
- package/dist/types/components/Controls/FilterDialog.d.ts +0 -5
- package/dist/types/components/Controls/PageSizeControl.d.ts +0 -4
- package/dist/types/components/Controls/Pagination.d.ts +0 -1
- package/dist/types/components/Controls/ResetFilteringButton.d.ts +0 -4
- package/dist/types/components/Controls/ResetSelectionButton.d.ts +0 -4
- package/dist/types/components/Controls/ResetSortingButton.d.ts +0 -4
- package/dist/types/components/Controls/RowCountText.d.ts +0 -1
- package/dist/types/components/Controls/SelectAllRowsToggle.d.ts +0 -8
- package/dist/types/components/Controls/TablePagination.d.ts +0 -1
- package/dist/types/components/Controls/ViewDialog.d.ts +0 -5
- package/dist/types/components/DataTable/CardHeader.d.ts +0 -13
- package/dist/types/components/DataTable/DataDisplay.d.ts +0 -6
- package/dist/types/components/DataTable/ReloadButton.d.ts +0 -5
- package/dist/types/components/DataTable/Table.d.ts +0 -10
- package/dist/types/components/DataTable/TableBody.d.ts +0 -21
- package/dist/types/components/DataTable/TableCardContainer.d.ts +0 -7
- package/dist/types/components/DataTable/TableCards.d.ts +0 -11
- package/dist/types/components/DataTable/TableComponent.d.ts +0 -6
- package/dist/types/components/DataTable/TableControls.d.ts +0 -21
- package/dist/types/components/DataTable/TableFilter.d.ts +0 -1
- package/dist/types/components/DataTable/TableFilterTags.d.ts +0 -1
- package/dist/types/components/DataTable/TableFilters.d.ts +0 -1
- package/dist/types/components/DataTable/TableFooter.d.ts +0 -9
- package/dist/types/components/DataTable/TableHeader.d.ts +0 -13
- package/dist/types/components/DataTable/TableLoadingComponent.d.ts +0 -5
- package/dist/types/components/DataTable/TableOrderer.d.ts +0 -1
- package/dist/types/components/DataTable/TableSelector.d.ts +0 -1
- package/dist/types/components/DataTable/TableSorter.d.ts +0 -1
- package/dist/types/components/DataTable/TableViewer.d.ts +0 -1
- package/dist/types/components/DataTable/TextCell.d.ts +0 -10
- package/dist/types/components/DataTable/components/EmptyState.d.ts +0 -5
- package/dist/types/components/DataTable/components/ErrorAlert.d.ts +0 -4
- package/dist/types/components/DataTable/components/RecordDisplay.d.ts +0 -9
- package/dist/types/components/DataTable/components/TextCell.d.ts +0 -10
- package/dist/types/components/Filter/DateRangeFilter.d.ts +0 -9
- package/dist/types/components/Filter/FilterOptions.d.ts +0 -4
- package/dist/types/components/Form/Form.d.ts +0 -36
- package/dist/types/components/Form/components/ArrayRenderer.d.ts +0 -7
- package/dist/types/components/Form/components/BooleanPicker.d.ts +0 -7
- package/dist/types/components/Form/components/ColumnRenderer.d.ts +0 -7
- package/dist/types/components/Form/components/DatePicker.d.ts +0 -7
- package/dist/types/components/Form/components/EnumPicker.d.ts +0 -8
- package/dist/types/components/Form/components/FilePicker.d.ts +0 -5
- package/dist/types/components/Form/components/IdPicker.d.ts +0 -8
- package/dist/types/components/Form/components/IdViewer.d.ts +0 -5
- package/dist/types/components/Form/components/NumberInputField.d.ts +0 -7
- package/dist/types/components/Form/components/ObjectInput.d.ts +0 -7
- package/dist/types/components/Form/components/RecordInput.d.ts +0 -7
- package/dist/types/components/Form/components/SchemaRenderer.d.ts +0 -7
- package/dist/types/components/Form/components/StringInputField.d.ts +0 -20
- package/dist/types/components/Form/components/TagPicker.d.ts +0 -30
- package/dist/types/components/Form/utils/translateWrapper.d.ts +0 -6
- package/dist/types/components/Form/utils/validation.d.ts +0 -104
package/dist/index.js
CHANGED
|
@@ -31,7 +31,6 @@ var axios = require('axios');
|
|
|
31
31
|
var reactHookForm = require('react-hook-form');
|
|
32
32
|
var Ajv = require('ajv');
|
|
33
33
|
var addFormats = require('ajv-formats');
|
|
34
|
-
var addErrors = require('ajv-errors');
|
|
35
34
|
var dayjs = require('dayjs');
|
|
36
35
|
var utc = require('dayjs/plugin/utc');
|
|
37
36
|
var timezone = require('dayjs/plugin/timezone');
|
|
@@ -3664,16 +3663,6 @@ const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
|
3664
3663
|
})] }));
|
|
3665
3664
|
};
|
|
3666
3665
|
|
|
3667
|
-
const AccordionItemTrigger = React__namespace.forwardRef(function AccordionItemTrigger(props, ref) {
|
|
3668
|
-
const { children, indicatorPlacement = "end", ...rest } = props;
|
|
3669
|
-
return (jsxRuntime.jsxs(react.Accordion.ItemTrigger, { ...rest, ref: ref, children: [indicatorPlacement === "start" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { rotate: { base: "-90deg", _open: "0deg" }, children: jsxRuntime.jsx(lu.LuChevronDown, {}) })), jsxRuntime.jsx(react.HStack, { gap: "4", flex: "1", textAlign: "start", width: "full", children: children }), indicatorPlacement === "end" && (jsxRuntime.jsx(react.Accordion.ItemIndicator, { children: jsxRuntime.jsx(lu.LuChevronDown, {}) }))] }));
|
|
3670
|
-
});
|
|
3671
|
-
const AccordionItemContent = React__namespace.forwardRef(function AccordionItemContent(props, ref) {
|
|
3672
|
-
return (jsxRuntime.jsx(react.Accordion.ItemContent, { children: jsxRuntime.jsx(react.Accordion.ItemBody, { ...props, ref: ref }) }));
|
|
3673
|
-
});
|
|
3674
|
-
const AccordionRoot = react.Accordion.Root;
|
|
3675
|
-
const AccordionItem = react.Accordion.Item;
|
|
3676
|
-
|
|
3677
3666
|
//@ts-expect-error TODO: find appropriate type
|
|
3678
3667
|
const SchemaFormContext = React.createContext({
|
|
3679
3668
|
schema: {},
|
|
@@ -3693,19 +3682,23 @@ const SchemaFormContext = React.createContext({
|
|
|
3693
3682
|
},
|
|
3694
3683
|
requireConfirmation: false,
|
|
3695
3684
|
onFormSubmit: async () => { },
|
|
3685
|
+
ajvResolver: async () => ({ values: {}, errors: {} }),
|
|
3696
3686
|
});
|
|
3697
3687
|
|
|
3698
3688
|
const useSchemaContext = () => {
|
|
3699
3689
|
return React.useContext(SchemaFormContext);
|
|
3700
3690
|
};
|
|
3701
3691
|
|
|
3692
|
+
const clearEmptyString = (object) => {
|
|
3693
|
+
return Object.fromEntries(Object.entries(object).filter(([, value]) => value !== ""));
|
|
3694
|
+
};
|
|
3695
|
+
|
|
3702
3696
|
const validateData = (data, schema) => {
|
|
3703
3697
|
const ajv = new Ajv({
|
|
3704
3698
|
strict: false,
|
|
3705
3699
|
allErrors: true,
|
|
3706
3700
|
});
|
|
3707
3701
|
addFormats(ajv);
|
|
3708
|
-
addErrors(ajv);
|
|
3709
3702
|
const validate = ajv.compile(schema);
|
|
3710
3703
|
const validationResult = validate(data);
|
|
3711
3704
|
const errors = validate.errors;
|
|
@@ -3717,8 +3710,183 @@ const validateData = (data, schema) => {
|
|
|
3717
3710
|
};
|
|
3718
3711
|
};
|
|
3719
3712
|
|
|
3720
|
-
|
|
3721
|
-
|
|
3713
|
+
/**
|
|
3714
|
+
* Gets the schema node for a field by following the path from root schema
|
|
3715
|
+
*/
|
|
3716
|
+
const getSchemaNodeForField = (schema, fieldPath) => {
|
|
3717
|
+
if (!fieldPath || fieldPath === '') {
|
|
3718
|
+
return schema;
|
|
3719
|
+
}
|
|
3720
|
+
const pathParts = fieldPath.split('.');
|
|
3721
|
+
let currentSchema = schema;
|
|
3722
|
+
for (const part of pathParts) {
|
|
3723
|
+
if (currentSchema &&
|
|
3724
|
+
currentSchema.properties &&
|
|
3725
|
+
currentSchema.properties[part] &&
|
|
3726
|
+
typeof currentSchema.properties[part] === 'object' &&
|
|
3727
|
+
currentSchema.properties[part] !== null) {
|
|
3728
|
+
currentSchema = currentSchema.properties[part];
|
|
3729
|
+
}
|
|
3730
|
+
else {
|
|
3731
|
+
return undefined;
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
return currentSchema;
|
|
3735
|
+
};
|
|
3736
|
+
/**
|
|
3737
|
+
* Converts AJV error objects to react-hook-form field errors format
|
|
3738
|
+
*/
|
|
3739
|
+
const convertAjvErrorsToFieldErrors = (errors, schema) => {
|
|
3740
|
+
if (!errors || errors.length === 0) {
|
|
3741
|
+
return {};
|
|
3742
|
+
}
|
|
3743
|
+
const fieldErrors = {};
|
|
3744
|
+
errors.forEach((error) => {
|
|
3745
|
+
let fieldName = '';
|
|
3746
|
+
// Special handling for required keyword: map to the specific missing property
|
|
3747
|
+
if (error.keyword === 'required') {
|
|
3748
|
+
const basePath = (error.instancePath || '')
|
|
3749
|
+
.replace(/^\//, '')
|
|
3750
|
+
.replace(/\//g, '.');
|
|
3751
|
+
const missingProperty = (error.params &&
|
|
3752
|
+
error.params.missingProperty);
|
|
3753
|
+
if (missingProperty) {
|
|
3754
|
+
fieldName = basePath
|
|
3755
|
+
? `${basePath}.${missingProperty}`
|
|
3756
|
+
: missingProperty;
|
|
3757
|
+
}
|
|
3758
|
+
else {
|
|
3759
|
+
// Fallback to schemaPath conversion if missingProperty is unavailable
|
|
3760
|
+
fieldName = (error.schemaPath || '')
|
|
3761
|
+
.replace(/^#\//, '#.')
|
|
3762
|
+
.replace(/\//g, '.');
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
else {
|
|
3766
|
+
const fieldPath = error.instancePath || error.schemaPath;
|
|
3767
|
+
if (fieldPath) {
|
|
3768
|
+
fieldName = fieldPath.replace(/^\//, '').replace(/\//g, '.');
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
if (fieldName) {
|
|
3772
|
+
// Get the schema node for this field to check for custom error messages
|
|
3773
|
+
const fieldSchema = getSchemaNodeForField(schema, fieldName);
|
|
3774
|
+
const customMessage = fieldSchema?.errorMessages?.[error.keyword];
|
|
3775
|
+
// Provide helpful fallback message if no custom message is provided
|
|
3776
|
+
const fallbackMessage = customMessage ||
|
|
3777
|
+
`Missing error message for ${error.keyword}. Add errorMessages.${error.keyword} to schema for field '${fieldName}'`;
|
|
3778
|
+
if (error.keyword === 'required') {
|
|
3779
|
+
// Required errors override any existing non-required errors for this field
|
|
3780
|
+
fieldErrors[fieldName] = {
|
|
3781
|
+
type: 'required',
|
|
3782
|
+
keyword: error.keyword,
|
|
3783
|
+
params: error.params,
|
|
3784
|
+
message: fallbackMessage,
|
|
3785
|
+
};
|
|
3786
|
+
}
|
|
3787
|
+
else {
|
|
3788
|
+
const existing = fieldErrors[fieldName];
|
|
3789
|
+
if (existing) {
|
|
3790
|
+
// Do not override required errors
|
|
3791
|
+
if (existing.type === 'required') {
|
|
3792
|
+
return;
|
|
3793
|
+
}
|
|
3794
|
+
// Combine messages if multiple errors for same field
|
|
3795
|
+
existing.message = existing.message
|
|
3796
|
+
? `${existing.message}; ${fallbackMessage}`
|
|
3797
|
+
: fallbackMessage;
|
|
3798
|
+
}
|
|
3799
|
+
else {
|
|
3800
|
+
fieldErrors[fieldName] = {
|
|
3801
|
+
type: error.keyword,
|
|
3802
|
+
keyword: error.keyword,
|
|
3803
|
+
params: error.params,
|
|
3804
|
+
message: fallbackMessage,
|
|
3805
|
+
};
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3809
|
+
});
|
|
3810
|
+
return fieldErrors;
|
|
3811
|
+
};
|
|
3812
|
+
/**
|
|
3813
|
+
* AJV resolver for react-hook-form
|
|
3814
|
+
* Integrates AJV validation with react-hook-form's validation system
|
|
3815
|
+
*/
|
|
3816
|
+
/**
|
|
3817
|
+
* Strips null, undefined, and empty string values from an object
|
|
3818
|
+
*/
|
|
3819
|
+
const stripEmptyValues = (obj) => {
|
|
3820
|
+
if (obj === null || obj === undefined) {
|
|
3821
|
+
return undefined;
|
|
3822
|
+
}
|
|
3823
|
+
if (typeof obj === 'string' && obj.trim() === '') {
|
|
3824
|
+
return undefined;
|
|
3825
|
+
}
|
|
3826
|
+
if (Array.isArray(obj)) {
|
|
3827
|
+
const filtered = obj
|
|
3828
|
+
.map(stripEmptyValues)
|
|
3829
|
+
.filter((item) => item !== undefined);
|
|
3830
|
+
return filtered.length > 0 ? filtered : undefined;
|
|
3831
|
+
}
|
|
3832
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
3833
|
+
const result = {};
|
|
3834
|
+
let hasValues = false;
|
|
3835
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
3836
|
+
const cleanedValue = stripEmptyValues(value);
|
|
3837
|
+
if (cleanedValue !== undefined) {
|
|
3838
|
+
result[key] = cleanedValue;
|
|
3839
|
+
hasValues = true;
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
return hasValues ? result : undefined;
|
|
3843
|
+
}
|
|
3844
|
+
return obj;
|
|
3845
|
+
};
|
|
3846
|
+
const ajvResolver = (schema) => {
|
|
3847
|
+
return async (values) => {
|
|
3848
|
+
try {
|
|
3849
|
+
// Strip empty values before validation
|
|
3850
|
+
const cleanedValues = stripEmptyValues(values);
|
|
3851
|
+
// Use empty object for validation if all values were stripped
|
|
3852
|
+
const valuesToValidate = cleanedValues === undefined ? {} : cleanedValues;
|
|
3853
|
+
const { isValid, errors } = validateData(valuesToValidate, schema);
|
|
3854
|
+
console.debug('AJV Validation Result:', {
|
|
3855
|
+
isValid,
|
|
3856
|
+
errors,
|
|
3857
|
+
cleanedValues,
|
|
3858
|
+
valuesToValidate,
|
|
3859
|
+
});
|
|
3860
|
+
if (isValid) {
|
|
3861
|
+
return {
|
|
3862
|
+
values: (cleanedValues || {}),
|
|
3863
|
+
errors: {},
|
|
3864
|
+
};
|
|
3865
|
+
}
|
|
3866
|
+
const fieldErrors = convertAjvErrorsToFieldErrors(errors, schema);
|
|
3867
|
+
console.debug('AJV Validation Failed:', {
|
|
3868
|
+
errors,
|
|
3869
|
+
fieldErrors,
|
|
3870
|
+
cleanedValues,
|
|
3871
|
+
valuesToValidate,
|
|
3872
|
+
});
|
|
3873
|
+
return {
|
|
3874
|
+
values: {},
|
|
3875
|
+
errors: fieldErrors,
|
|
3876
|
+
};
|
|
3877
|
+
}
|
|
3878
|
+
catch (error) {
|
|
3879
|
+
return {
|
|
3880
|
+
values: {},
|
|
3881
|
+
errors: {
|
|
3882
|
+
root: {
|
|
3883
|
+
type: 'validation',
|
|
3884
|
+
message: error instanceof Error ? error.message : 'Validation failed',
|
|
3885
|
+
},
|
|
3886
|
+
},
|
|
3887
|
+
};
|
|
3888
|
+
}
|
|
3889
|
+
};
|
|
3722
3890
|
};
|
|
3723
3891
|
|
|
3724
3892
|
const idPickerSanityCheck = (column, foreign_key) => {
|
|
@@ -3760,33 +3928,16 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3760
3928
|
const onSubmitSuccess = () => {
|
|
3761
3929
|
setIsSuccess(true);
|
|
3762
3930
|
};
|
|
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
3931
|
const defaultOnSubmit = async (promise) => {
|
|
3784
3932
|
try {
|
|
3933
|
+
console.log('onBeforeSubmit');
|
|
3785
3934
|
onBeforeSubmit();
|
|
3786
3935
|
await promise;
|
|
3936
|
+
console.log('onSubmitSuccess');
|
|
3787
3937
|
onSubmitSuccess();
|
|
3788
3938
|
}
|
|
3789
3939
|
catch (error) {
|
|
3940
|
+
console.log('onSubmitError', error);
|
|
3790
3941
|
onSubmitError(error);
|
|
3791
3942
|
}
|
|
3792
3943
|
finally {
|
|
@@ -3796,7 +3947,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3796
3947
|
const defaultSubmitPromise = (data) => {
|
|
3797
3948
|
const options = {
|
|
3798
3949
|
method: 'POST',
|
|
3799
|
-
url: `${
|
|
3950
|
+
url: `${serverUrl}`,
|
|
3800
3951
|
data: clearEmptyString(data),
|
|
3801
3952
|
...requestOptions,
|
|
3802
3953
|
};
|
|
@@ -3804,23 +3955,13 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3804
3955
|
};
|
|
3805
3956
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3806
3957
|
const onFormSubmit = async (data) => {
|
|
3807
|
-
//
|
|
3808
|
-
|
|
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
|
-
}
|
|
3958
|
+
// AJV validation is now handled by react-hook-form resolver
|
|
3959
|
+
// This function will only be called if validation passes
|
|
3819
3960
|
if (onSubmit === undefined) {
|
|
3820
|
-
await defaultOnSubmit(defaultSubmitPromise(data));
|
|
3961
|
+
await defaultOnSubmit(Promise.resolve(defaultSubmitPromise(data)));
|
|
3821
3962
|
return;
|
|
3822
3963
|
}
|
|
3823
|
-
await defaultOnSubmit(onSubmit(data));
|
|
3964
|
+
await defaultOnSubmit(Promise.resolve(onSubmit(data)));
|
|
3824
3965
|
};
|
|
3825
3966
|
return (jsxRuntime.jsx(SchemaFormContext.Provider, { value: {
|
|
3826
3967
|
schema,
|
|
@@ -3856,6 +3997,7 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3856
3997
|
dateTimePickerLabels,
|
|
3857
3998
|
idPickerLabels,
|
|
3858
3999
|
enumPickerLabels,
|
|
4000
|
+
ajvResolver: ajvResolver(schema),
|
|
3859
4001
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
|
|
3860
4002
|
};
|
|
3861
4003
|
|
|
@@ -3901,20 +4043,22 @@ const ArrayRenderer = ({ schema, column, prefix, }) => {
|
|
|
3901
4043
|
|
|
3902
4044
|
const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
3903
4045
|
const { label, children, helperText, errorText, optionalText, ...rest } = props;
|
|
3904
|
-
return (jsxRuntime.jsxs(react.Field.Root, { ref: ref, ...rest, children: [label && (jsxRuntime.jsxs(react.Field.Label, { children: [label, jsxRuntime.jsx(react.Field.RequiredIndicator, { fallback: optionalText })] })), children, helperText && (jsxRuntime.jsx(react.Field.HelperText, { children: helperText })), errorText && (jsxRuntime.
|
|
4046
|
+
return (jsxRuntime.jsxs(react.Field.Root, { ref: ref, ...rest, children: [label && (jsxRuntime.jsxs(react.Field.Label, { children: [label, jsxRuntime.jsx(react.Field.RequiredIndicator, { color: rest.invalid && rest.required ? 'red.500' : undefined, fallback: optionalText })] })), children, helperText && (jsxRuntime.jsx(react.Field.HelperText, { children: helperText })), !!errorText && (jsxRuntime.jsxs(react.Field.ErrorText, { children: [rest.required && rest.invalid && (jsxRuntime.jsx("span", { style: { color: 'var(--chakra-colors-red-500)' }, children: "* " })), errorText] }))] }));
|
|
3905
4047
|
});
|
|
3906
4048
|
|
|
3907
4049
|
const BooleanPicker = ({ schema, column, prefix }) => {
|
|
3908
4050
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3909
4051
|
const { translate } = useSchemaContext();
|
|
3910
|
-
const { required, gridColumn =
|
|
4052
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
3911
4053
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3912
4054
|
const colLabel = `${prefix}${column}`;
|
|
3913
4055
|
const value = watch(colLabel);
|
|
3914
|
-
return (jsxRuntime.
|
|
3915
|
-
gridRow,
|
|
3916
|
-
|
|
3917
|
-
|
|
4056
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4057
|
+
gridRow, errorText: errors[`${colLabel}`]
|
|
4058
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4059
|
+
: undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(CheckboxCard, { checked: value, variant: 'surface', onChange: () => {
|
|
4060
|
+
setValue(colLabel, !value);
|
|
4061
|
+
} }) }));
|
|
3918
4062
|
};
|
|
3919
4063
|
|
|
3920
4064
|
const CustomInput = ({ column, schema, prefix }) => {
|
|
@@ -4147,83 +4291,83 @@ const DatePicker = ({ column, schema, prefix }) => {
|
|
|
4147
4291
|
console.error(e);
|
|
4148
4292
|
}
|
|
4149
4293
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4150
|
-
return (jsxRuntime.
|
|
4151
|
-
gridRow, children:
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4294
|
+
return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4295
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], 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: () => {
|
|
4296
|
+
setOpen(true);
|
|
4297
|
+
}, 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 }) => {
|
|
4298
|
+
setValue(colLabel, dayjs(date).format(dateFormat));
|
|
4299
|
+
setOpen(false);
|
|
4300
|
+
}, labels: {
|
|
4301
|
+
monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
|
|
4302
|
+
formI18n.translate.t(`common.month_1`, {
|
|
4303
|
+
defaultValue: 'January',
|
|
4304
|
+
}),
|
|
4305
|
+
formI18n.translate.t(`common.month_2`, {
|
|
4306
|
+
defaultValue: 'February',
|
|
4307
|
+
}),
|
|
4308
|
+
formI18n.translate.t(`common.month_3`, {
|
|
4309
|
+
defaultValue: 'March',
|
|
4310
|
+
}),
|
|
4311
|
+
formI18n.translate.t(`common.month_4`, {
|
|
4312
|
+
defaultValue: 'April',
|
|
4313
|
+
}),
|
|
4314
|
+
formI18n.translate.t(`common.month_5`, {
|
|
4315
|
+
defaultValue: 'May',
|
|
4316
|
+
}),
|
|
4317
|
+
formI18n.translate.t(`common.month_6`, {
|
|
4318
|
+
defaultValue: 'June',
|
|
4319
|
+
}),
|
|
4320
|
+
formI18n.translate.t(`common.month_7`, {
|
|
4321
|
+
defaultValue: 'July',
|
|
4322
|
+
}),
|
|
4323
|
+
formI18n.translate.t(`common.month_8`, {
|
|
4324
|
+
defaultValue: 'August',
|
|
4325
|
+
}),
|
|
4326
|
+
formI18n.translate.t(`common.month_9`, {
|
|
4327
|
+
defaultValue: 'September',
|
|
4328
|
+
}),
|
|
4329
|
+
formI18n.translate.t(`common.month_10`, {
|
|
4330
|
+
defaultValue: 'October',
|
|
4331
|
+
}),
|
|
4332
|
+
formI18n.translate.t(`common.month_11`, {
|
|
4333
|
+
defaultValue: 'November',
|
|
4334
|
+
}),
|
|
4335
|
+
formI18n.translate.t(`common.month_12`, {
|
|
4336
|
+
defaultValue: 'December',
|
|
4337
|
+
}),
|
|
4338
|
+
],
|
|
4339
|
+
weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
|
|
4340
|
+
formI18n.translate.t(`common.weekday_1`, {
|
|
4341
|
+
defaultValue: 'Sun',
|
|
4342
|
+
}),
|
|
4343
|
+
formI18n.translate.t(`common.weekday_2`, {
|
|
4344
|
+
defaultValue: 'Mon',
|
|
4345
|
+
}),
|
|
4346
|
+
formI18n.translate.t(`common.weekday_3`, {
|
|
4347
|
+
defaultValue: 'Tue',
|
|
4348
|
+
}),
|
|
4349
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
4350
|
+
defaultValue: 'Wed',
|
|
4351
|
+
}),
|
|
4352
|
+
formI18n.translate.t(`common.weekday_5`, {
|
|
4353
|
+
defaultValue: 'Thu',
|
|
4354
|
+
}),
|
|
4355
|
+
formI18n.translate.t(`common.weekday_6`, {
|
|
4356
|
+
defaultValue: 'Fri',
|
|
4357
|
+
}),
|
|
4358
|
+
formI18n.translate.t(`common.weekday_7`, {
|
|
4359
|
+
defaultValue: 'Sat',
|
|
4360
|
+
}),
|
|
4361
|
+
],
|
|
4362
|
+
backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
|
|
4363
|
+
formI18n.translate.t(`common.back_button`, {
|
|
4364
|
+
defaultValue: 'Back',
|
|
4365
|
+
}),
|
|
4366
|
+
forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
|
|
4367
|
+
formI18n.translate.t(`common.forward_button`, {
|
|
4368
|
+
defaultValue: 'Forward',
|
|
4369
|
+
}),
|
|
4370
|
+
} })] }) })] }) }));
|
|
4227
4371
|
};
|
|
4228
4372
|
|
|
4229
4373
|
function filterArray(array, searchTerm) {
|
|
@@ -4258,7 +4402,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4258
4402
|
};
|
|
4259
4403
|
if (variant === 'radio') {
|
|
4260
4404
|
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4261
|
-
gridRow,
|
|
4405
|
+
gridRow, errorText: errors[`${colLabel}`]
|
|
4406
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4407
|
+
: undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, { defaultValue: "1", children: jsxRuntime.jsx(react.HStack, { gap: "6", children: filterArray(dataList, searchText ?? '').map((item) => {
|
|
4262
4408
|
return (jsxRuntime.jsxs(react.RadioGroup.Item, { onClick: () => {
|
|
4263
4409
|
if (!isMultiple) {
|
|
4264
4410
|
setOpenSearchResult(false);
|
|
@@ -4273,7 +4419,9 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4273
4419
|
}) }) }) }));
|
|
4274
4420
|
}
|
|
4275
4421
|
return (jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4276
|
-
gridRow,
|
|
4422
|
+
gridRow, errorText: errors[`${colLabel}`]
|
|
4423
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4424
|
+
: undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchEnums.map((enumValue) => {
|
|
4277
4425
|
const item = enumValue;
|
|
4278
4426
|
if (!!item === false) {
|
|
4279
4427
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
@@ -4328,7 +4476,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4328
4476
|
? renderDisplay(item)
|
|
4329
4477
|
: translate.t(removeIndex(`${colLabel}.${item}`)) }, `${colLabel}-${item}`));
|
|
4330
4478
|
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4331
|
-
translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] })
|
|
4479
|
+
translate.t(removeIndex(`${colLabel}.empty_search_result`)) })) }))] })] }) })] })] }));
|
|
4332
4480
|
};
|
|
4333
4481
|
|
|
4334
4482
|
function isEnteringWindow(_ref) {
|
|
@@ -4686,20 +4834,22 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4686
4834
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4687
4835
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4688
4836
|
const { translate } = useSchemaContext();
|
|
4689
|
-
const { required, gridColumn =
|
|
4837
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', } = schema;
|
|
4690
4838
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4691
4839
|
const currentFiles = (watch(column) ?? []);
|
|
4692
4840
|
const colLabel = `${prefix}${column}`;
|
|
4693
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ??
|
|
4841
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${colLabel}.field_label`)}`, required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: 'grid', gridTemplateRows: 'auto 1fr auto', alignItems: 'stretch', errorText: errors[`${colLabel}`]
|
|
4842
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4843
|
+
: undefined, invalid: !!errors[colLabel], children: [jsxRuntime.jsx(FileDropzone, { onDrop: ({ files }) => {
|
|
4694
4844
|
const newFiles = files.filter(({ name }) => !currentFiles.some((cur) => cur.name === name));
|
|
4695
4845
|
setValue(colLabel, [...currentFiles, ...newFiles]);
|
|
4696
|
-
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow:
|
|
4697
|
-
return (jsxRuntime.jsx(react.Card.Root, { variant:
|
|
4846
|
+
}, placeholder: translate.t(removeIndex(`${colLabel}.fileDropzone`)) }), jsxRuntime.jsx(react.Flex, { flexFlow: 'column', gap: 1, children: currentFiles.map((file) => {
|
|
4847
|
+
return (jsxRuntime.jsx(react.Card.Root, { variant: 'subtle', children: jsxRuntime.jsxs(react.Card.Body, { gap: "2", cursor: 'pointer', onClick: () => {
|
|
4698
4848
|
setValue(column, currentFiles.filter(({ name }) => {
|
|
4699
4849
|
return name !== file.name;
|
|
4700
4850
|
}));
|
|
4701
|
-
}, display:
|
|
4702
|
-
}) })
|
|
4851
|
+
}, display: 'flex', flexFlow: 'row', alignItems: 'center', padding: '2', children: [file.type.startsWith('image/') && (jsxRuntime.jsx(react.Image, { src: URL.createObjectURL(file), alt: file.name, boxSize: "50px", objectFit: "cover", borderRadius: "md", marginRight: "2" })), jsxRuntime.jsx(react.Box, { children: file.name }), jsxRuntime.jsx(ti.TiDeleteOutline, {})] }) }, file.name));
|
|
4852
|
+
}) })] }));
|
|
4703
4853
|
};
|
|
4704
4854
|
|
|
4705
4855
|
const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
|
|
@@ -4888,7 +5038,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4888
5038
|
return record[display_column];
|
|
4889
5039
|
};
|
|
4890
5040
|
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4891
|
-
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
|
|
5041
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
|
|
4892
5042
|
const item = idMap[id];
|
|
4893
5043
|
if (item === undefined) {
|
|
4894
5044
|
return (jsxRuntime.jsx(react.Text, { children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
|
|
@@ -4939,7 +5089,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4939
5089
|
? idPickerLabels?.emptySearchResult ??
|
|
4940
5090
|
formI18n.t('empty_search_result')
|
|
4941
5091
|
: idPickerLabels?.initialResults ??
|
|
4942
|
-
formI18n.t('initial_results') })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] })
|
|
5092
|
+
formI18n.t('initial_results') })) }), jsxRuntime.jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxRuntime.jsxs(react.HStack, { gap: "4", children: [jsxRuntime.jsx(PaginationPrevTrigger, {}), count > 0 && jsxRuntime.jsx(PaginationPageText, {}), jsxRuntime.jsx(PaginationNextTrigger, {})] }) })] }))] }) })] })] }));
|
|
4943
5093
|
};
|
|
4944
5094
|
|
|
4945
5095
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
@@ -4950,20 +5100,84 @@ const NumberInputField$1 = react.NumberInput.Input;
|
|
|
4950
5100
|
react.NumberInput.Scrubber;
|
|
4951
5101
|
react.NumberInput.Label;
|
|
4952
5102
|
|
|
5103
|
+
/**
|
|
5104
|
+
* Gets the error message for a specific field from react-hook-form errors
|
|
5105
|
+
* Prioritizes required errors (#.required) over field-specific validation errors
|
|
5106
|
+
*/
|
|
5107
|
+
const getFieldError = (errors, fieldName) => {
|
|
5108
|
+
// Check for form-level required errors first (highest priority)
|
|
5109
|
+
const requiredError = errors['#.required'];
|
|
5110
|
+
if (requiredError) {
|
|
5111
|
+
const requiredErrorMessage = extractErrorMessage(requiredError);
|
|
5112
|
+
if (requiredErrorMessage) {
|
|
5113
|
+
return requiredErrorMessage;
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
// If no required errors, return field-specific error
|
|
5117
|
+
const fieldError = errors[fieldName];
|
|
5118
|
+
if (fieldError) {
|
|
5119
|
+
const fieldErrorMessage = extractErrorMessage(fieldError);
|
|
5120
|
+
if (fieldErrorMessage) {
|
|
5121
|
+
return fieldErrorMessage;
|
|
5122
|
+
}
|
|
5123
|
+
}
|
|
5124
|
+
return undefined;
|
|
5125
|
+
};
|
|
5126
|
+
/**
|
|
5127
|
+
* Helper function to extract error message from various error formats
|
|
5128
|
+
* Only returns message if explicitly provided, no fallback text
|
|
5129
|
+
*/
|
|
5130
|
+
const extractErrorMessage = (error) => {
|
|
5131
|
+
if (!error) {
|
|
5132
|
+
return undefined;
|
|
5133
|
+
}
|
|
5134
|
+
// If it's a simple string error
|
|
5135
|
+
if (typeof error === 'string') {
|
|
5136
|
+
return error;
|
|
5137
|
+
}
|
|
5138
|
+
// If it's an error object with a message property
|
|
5139
|
+
if (error && typeof error === 'object' && 'message' in error) {
|
|
5140
|
+
return error.message;
|
|
5141
|
+
}
|
|
5142
|
+
// If it's an array of errors, get the first one
|
|
5143
|
+
if (Array.isArray(error) && error.length > 0) {
|
|
5144
|
+
const firstError = error[0];
|
|
5145
|
+
if (typeof firstError === 'string') {
|
|
5146
|
+
return firstError;
|
|
5147
|
+
}
|
|
5148
|
+
if (firstError &&
|
|
5149
|
+
typeof firstError === 'object' &&
|
|
5150
|
+
'message' in firstError) {
|
|
5151
|
+
return firstError.message;
|
|
5152
|
+
}
|
|
5153
|
+
}
|
|
5154
|
+
// No fallback - return undefined if no message provided
|
|
5155
|
+
return undefined;
|
|
5156
|
+
};
|
|
5157
|
+
|
|
4953
5158
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4954
5159
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4955
5160
|
const { translate } = useSchemaContext();
|
|
4956
|
-
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5161
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', numberStorageType = 'number', } = schema;
|
|
4957
5162
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4958
5163
|
const colLabel = `${prefix}${column}`;
|
|
4959
5164
|
const value = watch(`${colLabel}`);
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
5165
|
+
const fieldError = getFieldError(errors, colLabel);
|
|
5166
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn, gridRow, errorText: fieldError
|
|
5167
|
+
? fieldError.includes('required')
|
|
5168
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
5169
|
+
: fieldError
|
|
5170
|
+
: undefined, invalid: !!fieldError, children: jsxRuntime.jsx(NumberInputRoot, { value: value, onValueChange: (details) => {
|
|
5171
|
+
// Store as string or number based on configuration, default to number
|
|
5172
|
+
const value = numberStorageType === 'string'
|
|
5173
|
+
? details.value
|
|
5174
|
+
: details.valueAsNumber;
|
|
5175
|
+
setValue(`${colLabel}`, value);
|
|
5176
|
+
}, 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 }) }) }));
|
|
4963
5177
|
};
|
|
4964
5178
|
|
|
4965
5179
|
const ObjectInput = ({ schema, column, prefix }) => {
|
|
4966
|
-
const { properties, gridColumn =
|
|
5180
|
+
const { properties, gridColumn = 'span 12', gridRow = 'span 1', required, showLabel = true, } = schema;
|
|
4967
5181
|
const { translate } = useSchemaContext();
|
|
4968
5182
|
const colLabel = `${prefix}${column}`;
|
|
4969
5183
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -4971,29 +5185,32 @@ const ObjectInput = ({ schema, column, prefix }) => {
|
|
|
4971
5185
|
if (properties === undefined) {
|
|
4972
5186
|
throw new Error(`properties is undefined when using ObjectInput`);
|
|
4973
5187
|
}
|
|
4974
|
-
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base:
|
|
4975
|
-
base:
|
|
4976
|
-
_dark:
|
|
4977
|
-
}, gap: "4", padding:
|
|
5188
|
+
return (jsxRuntime.jsxs(react.Box, { gridRow, gridColumn, children: [showLabel && (jsxRuntime.jsxs(react.Box, { as: "label", children: [`${translate.t(removeIndex(`${colLabel}.field_label`))}`, isRequired && jsxRuntime.jsx("span", { children: "*" })] })), jsxRuntime.jsx(react.Grid, { bgColor: { base: 'colorPalette.100', _dark: 'colorPalette.900' }, p: 2, borderRadius: 4, borderWidth: 1, borderColor: {
|
|
5189
|
+
base: 'colorPalette.200',
|
|
5190
|
+
_dark: 'colorPalette.800',
|
|
5191
|
+
}, gap: "4", padding: '4', gridTemplateColumns: 'repeat(12, 1fr)', autoFlow: 'row', children: Object.keys(properties ?? {}).map((key) => {
|
|
4978
5192
|
return (
|
|
4979
5193
|
// @ts-expect-error find suitable types
|
|
4980
5194
|
jsxRuntime.jsx(ColumnRenderer, { column: `${key}`,
|
|
4981
5195
|
prefix: `${prefix}${column}.`,
|
|
4982
|
-
properties
|
|
4983
|
-
|
|
5196
|
+
properties,
|
|
5197
|
+
parentRequired: required }, `form-${colLabel}-${key}`));
|
|
5198
|
+
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4984
5199
|
};
|
|
4985
5200
|
|
|
4986
5201
|
const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
4987
5202
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4988
5203
|
const { translate } = useSchemaContext();
|
|
4989
|
-
const { required, gridColumn =
|
|
5204
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
4990
5205
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4991
5206
|
const entries = Object.entries(getValues(column) ?? {});
|
|
4992
5207
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4993
5208
|
const [newKey, setNewKey] = React.useState();
|
|
4994
5209
|
const [newValue, setNewValue] = React.useState();
|
|
4995
|
-
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems:
|
|
4996
|
-
|
|
5210
|
+
return (jsxRuntime.jsxs(Field, { label: `${translate.t(`${column}.field_label`)}`, required: isRequired, alignItems: 'stretch', gridColumn, gridRow, errorText: errors[`${column}`]
|
|
5211
|
+
? translate.t(`${column}.field_required`)
|
|
5212
|
+
: undefined, invalid: !!errors[column], children: [entries.map(([key, value]) => {
|
|
5213
|
+
return (jsxRuntime.jsxs(react.Grid, { templateColumns: '1fr 1fr auto', gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4997
5214
|
const filtered = entries.filter(([target]) => {
|
|
4998
5215
|
return target !== key;
|
|
4999
5216
|
});
|
|
@@ -5003,17 +5220,17 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
5003
5220
|
...getValues(column),
|
|
5004
5221
|
[key]: e.target.value,
|
|
5005
5222
|
});
|
|
5006
|
-
}, autoComplete: "off" }), jsxRuntime.jsx(react.IconButton, { variant:
|
|
5223
|
+
}, autoComplete: "off" }), jsxRuntime.jsx(react.IconButton, { variant: 'ghost', onClick: () => {
|
|
5007
5224
|
const filtered = entries.filter(([target]) => {
|
|
5008
5225
|
return target !== key;
|
|
5009
5226
|
});
|
|
5010
5227
|
setValue(column, Object.fromEntries([...filtered]));
|
|
5011
5228
|
}, children: jsxRuntime.jsx(cg.CgClose, {}) })] }));
|
|
5012
|
-
}), jsxRuntime.jsx(react.Show, { when: showNewEntries, children: jsxRuntime.jsxs(react.Card.Root, { children: [jsxRuntime.jsx(react.Card.Body, { gap: "2", children: jsxRuntime.jsxs(react.Grid, { templateColumns:
|
|
5229
|
+
}), jsxRuntime.jsx(react.Show, { when: showNewEntries, children: jsxRuntime.jsxs(react.Card.Root, { children: [jsxRuntime.jsx(react.Card.Body, { gap: "2", children: jsxRuntime.jsxs(react.Grid, { templateColumns: '1fr 1fr auto', gap: 1, children: [jsxRuntime.jsx(react.Input, { value: newKey, onChange: (e) => {
|
|
5013
5230
|
setNewKey(e.target.value);
|
|
5014
5231
|
}, autoComplete: "off" }), jsxRuntime.jsx(react.Input, { value: newValue, onChange: (e) => {
|
|
5015
5232
|
setNewValue(e.target.value);
|
|
5016
|
-
}, autoComplete: "off" })] }) }), jsxRuntime.jsxs(react.Card.Footer, { justifyContent: "flex-end", children: [jsxRuntime.jsx(react.IconButton, { variant:
|
|
5233
|
+
}, autoComplete: "off" })] }) }), jsxRuntime.jsxs(react.Card.Footer, { justifyContent: "flex-end", children: [jsxRuntime.jsx(react.IconButton, { variant: 'subtle', onClick: () => {
|
|
5017
5234
|
setShowNewEntries(false);
|
|
5018
5235
|
setNewKey(undefined);
|
|
5019
5236
|
setNewValue(undefined);
|
|
@@ -5032,16 +5249,17 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
5032
5249
|
setShowNewEntries(true);
|
|
5033
5250
|
setNewKey(undefined);
|
|
5034
5251
|
setNewValue(undefined);
|
|
5035
|
-
}, children: translate.t(`${column}.addNew`) })
|
|
5252
|
+
}, children: translate.t(`${column}.addNew`) })] }));
|
|
5036
5253
|
};
|
|
5037
5254
|
|
|
5038
5255
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
5039
5256
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5040
5257
|
const { translate } = useSchemaContext();
|
|
5041
|
-
const { required, gridColumn =
|
|
5258
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5042
5259
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5043
5260
|
const colLabel = `${prefix}${column}`;
|
|
5044
|
-
|
|
5261
|
+
const fieldError = getFieldError(errors, colLabel);
|
|
5262
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, errorText: fieldError, invalid: !!fieldError, children: jsxRuntime.jsx(react.Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }) }) }));
|
|
5045
5263
|
};
|
|
5046
5264
|
|
|
5047
5265
|
const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
|
|
@@ -5227,13 +5445,18 @@ Textarea.displayName = "Textarea";
|
|
|
5227
5445
|
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
5228
5446
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5229
5447
|
const { translate } = useSchemaContext();
|
|
5230
|
-
const { required, gridColumn =
|
|
5448
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1' } = schema;
|
|
5231
5449
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5232
5450
|
const colLabel = `${prefix}${column}`;
|
|
5233
5451
|
const form = reactHookForm.useFormContext();
|
|
5234
5452
|
const { setValue, watch } = form;
|
|
5453
|
+
const fieldError = getFieldError(errors, colLabel);
|
|
5235
5454
|
const watchValue = watch(colLabel);
|
|
5236
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.
|
|
5455
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn ?? 'span 4', gridRow: gridRow ?? 'span 1', display: "grid", errorText: fieldError
|
|
5456
|
+
? fieldError.includes('required')
|
|
5457
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
5458
|
+
: fieldError
|
|
5459
|
+
: undefined, invalid: !!fieldError, children: jsxRuntime.jsx(Textarea, { value: watchValue, onChange: (value) => setValue(colLabel, value) }) }) }));
|
|
5237
5460
|
};
|
|
5238
5461
|
|
|
5239
5462
|
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
@@ -5364,25 +5587,25 @@ dayjs.extend(timezone);
|
|
|
5364
5587
|
const TimePicker = ({ column, schema, prefix }) => {
|
|
5365
5588
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5366
5589
|
const { translate, timezone } = useSchemaContext();
|
|
5367
|
-
const { required, gridColumn =
|
|
5590
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', timeFormat = 'HH:mm:ssZ', displayTimeFormat = 'hh:mm A', } = schema;
|
|
5368
5591
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5369
5592
|
const colLabel = `${prefix}${column}`;
|
|
5370
5593
|
const [open, setOpen] = React.useState(false);
|
|
5371
5594
|
const value = watch(colLabel);
|
|
5372
5595
|
const displayedTime = dayjs(`1970-01-01T${value}`).tz(timezone).isValid()
|
|
5373
5596
|
? dayjs(`1970-01-01T${value}`).tz(timezone).format(displayTimeFormat)
|
|
5374
|
-
:
|
|
5597
|
+
: '';
|
|
5375
5598
|
// Parse the initial time parts from the time string (HH:mm:ssZ)
|
|
5376
5599
|
const parseTime = (time) => {
|
|
5377
5600
|
if (!time)
|
|
5378
|
-
return { hour: 12, minute: 0, meridiem:
|
|
5601
|
+
return { hour: 12, minute: 0, meridiem: 'am' };
|
|
5379
5602
|
const parsed = dayjs(`1970-01-01T${time}`).tz(timezone);
|
|
5380
5603
|
if (!parsed.isValid()) {
|
|
5381
|
-
return { hour: 12, minute: 0, meridiem:
|
|
5604
|
+
return { hour: 12, minute: 0, meridiem: 'am' };
|
|
5382
5605
|
}
|
|
5383
5606
|
let hour = parsed.hour();
|
|
5384
5607
|
const minute = parsed.minute();
|
|
5385
|
-
const meridiem = hour >= 12 ?
|
|
5608
|
+
const meridiem = hour >= 12 ? 'pm' : 'am';
|
|
5386
5609
|
if (hour === 0)
|
|
5387
5610
|
hour = 12;
|
|
5388
5611
|
else if (hour > 12)
|
|
@@ -5403,10 +5626,15 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
5403
5626
|
if (hour === null || minute === null || meridiem === null)
|
|
5404
5627
|
return null;
|
|
5405
5628
|
let newHour = hour;
|
|
5406
|
-
if (meridiem ===
|
|
5629
|
+
if (meridiem === 'pm' && hour !== 12) {
|
|
5407
5630
|
newHour = hour + 12;
|
|
5408
5631
|
}
|
|
5409
|
-
return dayjs()
|
|
5632
|
+
return dayjs()
|
|
5633
|
+
.tz(timezone)
|
|
5634
|
+
.hour(newHour)
|
|
5635
|
+
.minute(minute)
|
|
5636
|
+
.second(0)
|
|
5637
|
+
.format(timeFormat);
|
|
5410
5638
|
};
|
|
5411
5639
|
// Handle changes to time parts
|
|
5412
5640
|
const handleTimeChange = ({ hour: newHour, minute: newMinute, meridiem: newMeridiem, }) => {
|
|
@@ -5416,13 +5644,15 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
5416
5644
|
const timeString = getTimeString(newHour, newMinute, newMeridiem);
|
|
5417
5645
|
setValue(colLabel, timeString, { shouldValidate: true, shouldDirty: true });
|
|
5418
5646
|
};
|
|
5419
|
-
return (jsxRuntime.
|
|
5420
|
-
gridRow,
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5647
|
+
return (jsxRuntime.jsx(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, alignItems: 'stretch', gridColumn,
|
|
5648
|
+
gridRow, errorText: errors[`${colLabel}`]
|
|
5649
|
+
? translate.t(removeIndex(`${colLabel}.field_required`))
|
|
5650
|
+
: undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5651
|
+
setOpen(true);
|
|
5652
|
+
}, justifyContent: 'start', children: [jsxRuntime.jsx(io.IoMdClock, {}), !!value ? `${displayedTime}` : ''] }) }), jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
5653
|
+
am: translate.t(`common.am`, { defaultValue: 'AM' }),
|
|
5654
|
+
pm: translate.t(`common.pm`, { defaultValue: 'PM' }),
|
|
5655
|
+
} }) }) }) })] }) }));
|
|
5426
5656
|
};
|
|
5427
5657
|
|
|
5428
5658
|
function IsoTimePicker({ hour, setHour, minute, setMinute, second, setSecond, onChange = (_newValue) => { }, }) {
|
|
@@ -5628,9 +5858,9 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
|
5628
5858
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5629
5859
|
const { timezone, dateTimePickerLabels } = useSchemaContext();
|
|
5630
5860
|
const formI18n = useFormI18n(column, prefix);
|
|
5631
|
-
const { required, gridColumn =
|
|
5861
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', displayDateFormat = 'YYYY-MM-DD HH:mm:ss',
|
|
5632
5862
|
// with timezone
|
|
5633
|
-
dateFormat =
|
|
5863
|
+
dateFormat = 'YYYY-MM-DD[T]HH:mm:ssZ', } = schema;
|
|
5634
5864
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5635
5865
|
const colLabel = formI18n.colLabel;
|
|
5636
5866
|
const [open, setOpen] = React.useState(false);
|
|
@@ -5661,44 +5891,82 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
|
5661
5891
|
console.error(e);
|
|
5662
5892
|
}
|
|
5663
5893
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5664
|
-
return (jsxRuntime.
|
|
5665
|
-
gridRow, children:
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
defaultValue:
|
|
5894
|
+
return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
5895
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], 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: () => {
|
|
5896
|
+
setOpen(true);
|
|
5897
|
+
}, justifyContent: 'start', children: [jsxRuntime.jsx(md.MdDateRange, {}), selectedDate !== undefined ? `${displayDate}` : ''] }) }), jsxRuntime.jsx(PopoverContent, { minW: '450px', children: jsxRuntime.jsxs(PopoverBody, { children: [jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(DateTimePicker$1, { value: selectedDate, onChange: (date) => {
|
|
5898
|
+
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5899
|
+
}, timezone: timezone, labels: {
|
|
5900
|
+
monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
|
|
5901
|
+
formI18n.translate.t(`common.month_1`, {
|
|
5902
|
+
defaultValue: 'January',
|
|
5903
|
+
}),
|
|
5904
|
+
formI18n.translate.t(`common.month_2`, {
|
|
5905
|
+
defaultValue: 'February',
|
|
5906
|
+
}),
|
|
5907
|
+
formI18n.translate.t(`common.month_3`, {
|
|
5908
|
+
defaultValue: 'March',
|
|
5909
|
+
}),
|
|
5910
|
+
formI18n.translate.t(`common.month_4`, {
|
|
5911
|
+
defaultValue: 'April',
|
|
5912
|
+
}),
|
|
5913
|
+
formI18n.translate.t(`common.month_5`, {
|
|
5914
|
+
defaultValue: 'May',
|
|
5915
|
+
}),
|
|
5916
|
+
formI18n.translate.t(`common.month_6`, {
|
|
5917
|
+
defaultValue: 'June',
|
|
5918
|
+
}),
|
|
5919
|
+
formI18n.translate.t(`common.month_7`, {
|
|
5920
|
+
defaultValue: 'July',
|
|
5921
|
+
}),
|
|
5922
|
+
formI18n.translate.t(`common.month_8`, {
|
|
5923
|
+
defaultValue: 'August',
|
|
5924
|
+
}),
|
|
5925
|
+
formI18n.translate.t(`common.month_9`, {
|
|
5926
|
+
defaultValue: 'September',
|
|
5927
|
+
}),
|
|
5928
|
+
formI18n.translate.t(`common.month_10`, {
|
|
5929
|
+
defaultValue: 'October',
|
|
5930
|
+
}),
|
|
5931
|
+
formI18n.translate.t(`common.month_11`, {
|
|
5932
|
+
defaultValue: 'November',
|
|
5933
|
+
}),
|
|
5934
|
+
formI18n.translate.t(`common.month_12`, {
|
|
5935
|
+
defaultValue: 'December',
|
|
5936
|
+
}),
|
|
5937
|
+
],
|
|
5938
|
+
weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
|
|
5939
|
+
formI18n.translate.t(`common.weekday_1`, {
|
|
5940
|
+
defaultValue: 'Sun',
|
|
5941
|
+
}),
|
|
5942
|
+
formI18n.translate.t(`common.weekday_2`, {
|
|
5943
|
+
defaultValue: 'Mon',
|
|
5944
|
+
}),
|
|
5945
|
+
formI18n.translate.t(`common.weekday_3`, {
|
|
5946
|
+
defaultValue: 'Tue',
|
|
5947
|
+
}),
|
|
5948
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
5949
|
+
defaultValue: 'Wed',
|
|
5950
|
+
}),
|
|
5951
|
+
formI18n.translate.t(`common.weekday_5`, {
|
|
5952
|
+
defaultValue: 'Thu',
|
|
5953
|
+
}),
|
|
5954
|
+
formI18n.translate.t(`common.weekday_6`, {
|
|
5955
|
+
defaultValue: 'Fri',
|
|
5956
|
+
}),
|
|
5957
|
+
formI18n.translate.t(`common.weekday_7`, {
|
|
5958
|
+
defaultValue: 'Sat',
|
|
5959
|
+
}),
|
|
5960
|
+
],
|
|
5961
|
+
backButtonLabel: dateTimePickerLabels?.backButtonLabel ??
|
|
5962
|
+
formI18n.translate.t(`common.back_button`, {
|
|
5963
|
+
defaultValue: 'Back',
|
|
5697
5964
|
}),
|
|
5698
|
-
|
|
5699
|
-
|
|
5965
|
+
forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ??
|
|
5966
|
+
formI18n.translate.t(`common.forward_button`, {
|
|
5967
|
+
defaultValue: 'Forward',
|
|
5700
5968
|
}),
|
|
5701
|
-
|
|
5969
|
+
} })] }) })] }) }));
|
|
5702
5970
|
};
|
|
5703
5971
|
|
|
5704
5972
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
@@ -5772,13 +6040,18 @@ const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
|
5772
6040
|
return jsxRuntime.jsx(react.Text, { children: "missing type" });
|
|
5773
6041
|
};
|
|
5774
6042
|
|
|
5775
|
-
const ColumnRenderer = ({ column, properties, prefix, }) => {
|
|
6043
|
+
const ColumnRenderer = ({ column, properties, prefix, parentRequired, }) => {
|
|
5776
6044
|
const colSchema = properties[column];
|
|
5777
6045
|
const colLabel = `${prefix}${column}`;
|
|
5778
6046
|
if (colSchema === undefined) {
|
|
5779
6047
|
throw new Error(`${colLabel} does not exist when using ColumnRenderer`);
|
|
5780
6048
|
}
|
|
5781
|
-
|
|
6049
|
+
// Merge parent's required array with the schema's required array
|
|
6050
|
+
const schemaWithRequired = {
|
|
6051
|
+
...colSchema,
|
|
6052
|
+
required: parentRequired || colSchema.required,
|
|
6053
|
+
};
|
|
6054
|
+
return jsxRuntime.jsx(SchemaRenderer, { schema: schemaWithRequired, prefix, column });
|
|
5782
6055
|
};
|
|
5783
6056
|
|
|
5784
6057
|
const ArrayViewer = ({ schema, column, prefix }) => {
|
|
@@ -6219,15 +6492,15 @@ const SubmitButton = () => {
|
|
|
6219
6492
|
const methods = reactHookForm.useFormContext();
|
|
6220
6493
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6221
6494
|
const onValid = (data) => {
|
|
6222
|
-
const { isValid, errors } = validateData(data, schema);
|
|
6223
|
-
if (!isValid) {
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
}
|
|
6495
|
+
// const { isValid, errors } = validateData(data, schema);
|
|
6496
|
+
// if (!isValid) {
|
|
6497
|
+
// setError({
|
|
6498
|
+
// type: 'validation',
|
|
6499
|
+
// errors,
|
|
6500
|
+
// });
|
|
6501
|
+
// setIsError(true);
|
|
6502
|
+
// return;
|
|
6503
|
+
// }
|
|
6231
6504
|
// If validation passes, check if confirmation is required
|
|
6232
6505
|
if (requireConfirmation) {
|
|
6233
6506
|
// Show confirmation (existing behavior)
|
|
@@ -6252,10 +6525,6 @@ const FormBody = () => {
|
|
|
6252
6525
|
const { showSubmitButton, showResetButton } = displayConfig;
|
|
6253
6526
|
const methods = reactHookForm.useFormContext();
|
|
6254
6527
|
const { properties } = schema;
|
|
6255
|
-
// Custom error renderer for validation errors with i18n support
|
|
6256
|
-
const renderValidationErrors = (validationErrors) => {
|
|
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))) }));
|
|
6258
|
-
};
|
|
6259
6528
|
const renderColumns = ({ order, keys, ignore, include, }) => {
|
|
6260
6529
|
const included = include.length > 0 ? include : keys;
|
|
6261
6530
|
const not_exist = included.filter((columnA) => !order.some((columnB) => columnA === columnB));
|
|
@@ -6295,19 +6564,17 @@ const FormBody = () => {
|
|
|
6295
6564
|
setIsConfirming(false);
|
|
6296
6565
|
}, variant: 'subtle', children: translate.t('cancel') }), jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6297
6566
|
onFormSubmit(validatedData);
|
|
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 &&
|
|
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)}` })] }) }) })] })] })) })) }))] }));
|
|
6567
|
+
}, 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 && customErrorRenderer && customErrorRenderer(error)] }));
|
|
6300
6568
|
}
|
|
6301
6569
|
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) => {
|
|
6302
6570
|
return (jsxRuntime.jsx(ColumnRenderer
|
|
6303
6571
|
// @ts-expect-error find suitable types
|
|
6304
6572
|
, {
|
|
6305
6573
|
// @ts-expect-error find suitable types
|
|
6306
|
-
properties: properties, prefix: ``, column }, `form-input-${column}`));
|
|
6574
|
+
properties: properties, prefix: ``, parentRequired: schema.required, column }, `form-input-${column}`));
|
|
6307
6575
|
}) }), jsxRuntime.jsxs(react.Flex, { justifyContent: 'end', gap: "2", children: [showResetButton && (jsxRuntime.jsx(react.Button, { onClick: () => {
|
|
6308
6576
|
methods.reset();
|
|
6309
|
-
}, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError &&
|
|
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)}` })] }) }) })] })] })) })) }))] }));
|
|
6577
|
+
}, variant: 'subtle', children: translate.t('reset') })), showSubmitButton && jsxRuntime.jsx(SubmitButton, {})] }), isError && customErrorRenderer && customErrorRenderer(error)] }));
|
|
6311
6578
|
};
|
|
6312
6579
|
|
|
6313
6580
|
const FormTitle = () => {
|
|
@@ -6320,12 +6587,15 @@ const DefaultForm = ({ formConfig, }) => {
|
|
|
6320
6587
|
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
6321
6588
|
};
|
|
6322
6589
|
|
|
6323
|
-
const useForm = ({ preLoadedValues, keyPrefix, namespace }) => {
|
|
6590
|
+
const useForm = ({ preLoadedValues, keyPrefix, namespace, schema, }) => {
|
|
6324
6591
|
const form = reactHookForm.useForm({
|
|
6325
6592
|
values: preLoadedValues,
|
|
6593
|
+
resolver: schema ? ajvResolver(schema) : undefined,
|
|
6594
|
+
mode: 'onBlur',
|
|
6595
|
+
reValidateMode: 'onBlur',
|
|
6326
6596
|
});
|
|
6327
6597
|
const [idMap, setIdMap] = React.useState({});
|
|
6328
|
-
const translate = reactI18next.useTranslation(namespace ||
|
|
6598
|
+
const translate = reactI18next.useTranslation(namespace || '', { keyPrefix });
|
|
6329
6599
|
return {
|
|
6330
6600
|
form,
|
|
6331
6601
|
idMap,
|
|
@@ -6395,15 +6665,15 @@ const buildErrorMessages = (config) => {
|
|
|
6395
6665
|
}
|
|
6396
6666
|
// Add global fallback error messages
|
|
6397
6667
|
const globalKeys = [
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6668
|
+
'minLength',
|
|
6669
|
+
'maxLength',
|
|
6670
|
+
'pattern',
|
|
6671
|
+
'minimum',
|
|
6672
|
+
'maximum',
|
|
6673
|
+
'multipleOf',
|
|
6674
|
+
'format',
|
|
6675
|
+
'type',
|
|
6676
|
+
'enum',
|
|
6407
6677
|
];
|
|
6408
6678
|
globalKeys.forEach((key) => {
|
|
6409
6679
|
if (config[key]) {
|
|
@@ -6412,6 +6682,46 @@ const buildErrorMessages = (config) => {
|
|
|
6412
6682
|
});
|
|
6413
6683
|
return result;
|
|
6414
6684
|
};
|
|
6685
|
+
/**
|
|
6686
|
+
* Converts buildErrorMessages result to ajv-errors compatible format
|
|
6687
|
+
*/
|
|
6688
|
+
const convertToAjvErrorsFormat = (errorMessages) => {
|
|
6689
|
+
const result = {};
|
|
6690
|
+
// Convert required field errors
|
|
6691
|
+
if (errorMessages.required) {
|
|
6692
|
+
result.required = errorMessages.required;
|
|
6693
|
+
}
|
|
6694
|
+
// Convert properties errors to ajv-errors format
|
|
6695
|
+
if (errorMessages.properties) {
|
|
6696
|
+
result.properties = {};
|
|
6697
|
+
Object.keys(errorMessages.properties).forEach((fieldName) => {
|
|
6698
|
+
const fieldErrors = errorMessages.properties[fieldName];
|
|
6699
|
+
result.properties[fieldName] = {};
|
|
6700
|
+
Object.keys(fieldErrors).forEach((keyword) => {
|
|
6701
|
+
result.properties[fieldName][keyword] =
|
|
6702
|
+
fieldErrors[keyword];
|
|
6703
|
+
});
|
|
6704
|
+
});
|
|
6705
|
+
}
|
|
6706
|
+
// Add global fallback errors
|
|
6707
|
+
const globalKeys = [
|
|
6708
|
+
'minLength',
|
|
6709
|
+
'maxLength',
|
|
6710
|
+
'pattern',
|
|
6711
|
+
'minimum',
|
|
6712
|
+
'maximum',
|
|
6713
|
+
'multipleOf',
|
|
6714
|
+
'format',
|
|
6715
|
+
'type',
|
|
6716
|
+
'enum',
|
|
6717
|
+
];
|
|
6718
|
+
globalKeys.forEach((key) => {
|
|
6719
|
+
if (errorMessages[key]) {
|
|
6720
|
+
result[key] = errorMessages[key];
|
|
6721
|
+
}
|
|
6722
|
+
});
|
|
6723
|
+
return result;
|
|
6724
|
+
};
|
|
6415
6725
|
/**
|
|
6416
6726
|
* Helper function to build required field errors
|
|
6417
6727
|
*
|
|
@@ -6454,10 +6764,10 @@ const buildErrorMessages = (config) => {
|
|
|
6454
6764
|
* // Result: { username: "user.username.field_required", email: "user.email.field_required" }
|
|
6455
6765
|
* ```
|
|
6456
6766
|
*/
|
|
6457
|
-
const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix =
|
|
6767
|
+
const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = '') => {
|
|
6458
6768
|
const result = {};
|
|
6459
6769
|
fields.forEach((field) => {
|
|
6460
|
-
if (typeof messageOrGenerator ===
|
|
6770
|
+
if (typeof messageOrGenerator === 'function') {
|
|
6461
6771
|
const message = messageOrGenerator(field);
|
|
6462
6772
|
result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
|
|
6463
6773
|
}
|
|
@@ -6528,11 +6838,14 @@ const buildFieldErrors = (config) => {
|
|
|
6528
6838
|
* ```
|
|
6529
6839
|
*/
|
|
6530
6840
|
const createErrorMessage = (required, properties, globalFallbacks) => {
|
|
6531
|
-
|
|
6841
|
+
const config = {
|
|
6532
6842
|
required,
|
|
6533
6843
|
properties,
|
|
6534
|
-
|
|
6535
|
-
|
|
6844
|
+
};
|
|
6845
|
+
if (globalFallbacks) {
|
|
6846
|
+
Object.assign(config, globalFallbacks);
|
|
6847
|
+
}
|
|
6848
|
+
return buildErrorMessages(config);
|
|
6536
6849
|
};
|
|
6537
6850
|
|
|
6538
6851
|
const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) => {
|
|
@@ -6595,6 +6908,7 @@ exports.ViewDialog = ViewDialog;
|
|
|
6595
6908
|
exports.buildErrorMessages = buildErrorMessages;
|
|
6596
6909
|
exports.buildFieldErrors = buildFieldErrors;
|
|
6597
6910
|
exports.buildRequiredErrors = buildRequiredErrors;
|
|
6911
|
+
exports.convertToAjvErrorsFormat = convertToAjvErrorsFormat;
|
|
6598
6912
|
exports.createErrorMessage = createErrorMessage;
|
|
6599
6913
|
exports.getColumns = getColumns;
|
|
6600
6914
|
exports.getMultiDates = getMultiDates;
|