@bsol-oss/react-datatable5 12.0.0-beta.70 → 12.0.0-beta.72
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 +259 -14
- package/dist/index.js +399 -131
- package/dist/index.mjs +396 -132
- package/dist/types/components/Form/SchemaFormContext.d.ts +9 -5
- package/dist/types/components/Form/components/core/FormBody.d.ts +2 -1
- package/dist/types/components/Form/components/core/FormRoot.d.ts +11 -8
- package/dist/types/components/Form/components/fields/IdPicker.d.ts +1 -1
- package/dist/types/components/Form/components/types/CustomJSONSchema7.d.ts +20 -4
- package/dist/types/components/Form/useForm.d.ts +3 -2
- package/dist/types/components/Form/utils/buildErrorMessages.d.ts +219 -0
- package/dist/types/components/Form/utils/useFormI18n.d.ts +53 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -3677,8 +3677,8 @@ const AccordionItem = react.Accordion.Item;
|
|
|
3677
3677
|
//@ts-expect-error TODO: find appropriate type
|
|
3678
3678
|
const SchemaFormContext = React.createContext({
|
|
3679
3679
|
schema: {},
|
|
3680
|
-
serverUrl:
|
|
3681
|
-
requestUrl:
|
|
3680
|
+
serverUrl: '',
|
|
3681
|
+
requestUrl: '',
|
|
3682
3682
|
order: [],
|
|
3683
3683
|
ignore: [],
|
|
3684
3684
|
include: [],
|
|
@@ -3734,11 +3734,11 @@ const idPickerSanityCheck = (column, foreign_key) => {
|
|
|
3734
3734
|
throw new Error(`The key column does not exist in properties of column ${column} when using id-picker.`);
|
|
3735
3735
|
}
|
|
3736
3736
|
};
|
|
3737
|
-
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, displayConfig = {
|
|
3737
|
+
const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, children, order = [], ignore = [], include = [], onSubmit = undefined, rowNumber = undefined, requestOptions = {}, getUpdatedData = () => { }, customErrorRenderer, customSuccessRenderer, displayConfig = {
|
|
3738
3738
|
showSubmitButton: true,
|
|
3739
3739
|
showResetButton: true,
|
|
3740
3740
|
showTitle: true,
|
|
3741
|
-
}, }) => {
|
|
3741
|
+
}, dateTimePickerLabels, idPickerLabels, }) => {
|
|
3742
3742
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
3743
3743
|
const [isError, setIsError] = React.useState(false);
|
|
3744
3744
|
const [isSubmiting, setIsSubmiting] = React.useState(false);
|
|
@@ -3772,7 +3772,10 @@ const FormRoot = ({ schema, idMap, setIdMap, form, serverUrl, translate, childre
|
|
|
3772
3772
|
setError,
|
|
3773
3773
|
getUpdatedData,
|
|
3774
3774
|
customErrorRenderer,
|
|
3775
|
+
customSuccessRenderer,
|
|
3775
3776
|
displayConfig,
|
|
3777
|
+
dateTimePickerLabels,
|
|
3778
|
+
idPickerLabels,
|
|
3776
3779
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...form, children: children }) }));
|
|
3777
3780
|
};
|
|
3778
3781
|
|
|
@@ -3824,7 +3827,7 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
|
3824
3827
|
const BooleanPicker = ({ schema, column, prefix }) => {
|
|
3825
3828
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3826
3829
|
const { translate } = useSchemaContext();
|
|
3827
|
-
const { required, gridColumn = "span
|
|
3830
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
3828
3831
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3829
3832
|
const colLabel = `${prefix}${column}`;
|
|
3830
3833
|
const value = watch(colLabel);
|
|
@@ -3963,18 +3966,79 @@ const PopoverRoot = react.Popover.Root;
|
|
|
3963
3966
|
const PopoverBody = react.Popover.Body;
|
|
3964
3967
|
const PopoverTrigger = react.Popover.Trigger;
|
|
3965
3968
|
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
+
/**
|
|
3970
|
+
* Custom hook to simplify i18n translation for form fields.
|
|
3971
|
+
* Automatically handles colLabel construction and removeIndex logic.
|
|
3972
|
+
*
|
|
3973
|
+
* @param column - The column name
|
|
3974
|
+
* @param prefix - The prefix for the field (usually empty string or parent path)
|
|
3975
|
+
* @returns Object with translation helper functions
|
|
3976
|
+
*
|
|
3977
|
+
* @example
|
|
3978
|
+
* ```tsx
|
|
3979
|
+
* const formI18n = useFormI18n(column, prefix);
|
|
3980
|
+
*
|
|
3981
|
+
* // Get field label
|
|
3982
|
+
* <Field label={formI18n.label()} />
|
|
3983
|
+
*
|
|
3984
|
+
* // Get error message
|
|
3985
|
+
* <Text>{formI18n.required()}</Text>
|
|
3986
|
+
*
|
|
3987
|
+
* // Get custom translation key
|
|
3988
|
+
* <Text>{formI18n.t('add_more')}</Text>
|
|
3989
|
+
*
|
|
3990
|
+
* // Access the raw colLabel
|
|
3991
|
+
* const colLabel = formI18n.colLabel;
|
|
3992
|
+
* ```
|
|
3993
|
+
*/
|
|
3994
|
+
const useFormI18n = (column, prefix = "") => {
|
|
3995
|
+
const { translate } = useSchemaContext();
|
|
3996
|
+
const colLabel = `${prefix}${column}`;
|
|
3997
|
+
return {
|
|
3998
|
+
/**
|
|
3999
|
+
* The constructed column label (prefix + column)
|
|
4000
|
+
*/
|
|
4001
|
+
colLabel,
|
|
4002
|
+
/**
|
|
4003
|
+
* Get the field label translation
|
|
4004
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.field_label`))
|
|
4005
|
+
*/
|
|
4006
|
+
label: (options) => {
|
|
4007
|
+
return translate.t(removeIndex(`${colLabel}.field_label`), options);
|
|
4008
|
+
},
|
|
4009
|
+
/**
|
|
4010
|
+
* Get the required error message translation
|
|
4011
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.field_required`))
|
|
4012
|
+
*/
|
|
4013
|
+
required: (options) => {
|
|
4014
|
+
return translate.t(removeIndex(`${colLabel}.field_required`), options);
|
|
4015
|
+
},
|
|
4016
|
+
/**
|
|
4017
|
+
* Get a translation for any custom key relative to the field
|
|
4018
|
+
* Equivalent to: translate.t(removeIndex(`${colLabel}.${key}`))
|
|
4019
|
+
*
|
|
4020
|
+
* @param key - The translation key suffix (e.g., 'add_more', 'total', etc.)
|
|
4021
|
+
* @param options - Optional translation options (e.g., defaultValue, interpolation variables)
|
|
4022
|
+
*/
|
|
4023
|
+
t: (key, options) => {
|
|
4024
|
+
return translate.t(removeIndex(`${colLabel}.${key}`), options);
|
|
4025
|
+
},
|
|
4026
|
+
/**
|
|
4027
|
+
* Access to the original translate object for edge cases
|
|
4028
|
+
*/
|
|
4029
|
+
translate,
|
|
4030
|
+
};
|
|
4031
|
+
};
|
|
3969
4032
|
|
|
3970
4033
|
dayjs.extend(utc);
|
|
3971
4034
|
dayjs.extend(timezone);
|
|
3972
4035
|
const DatePicker = ({ column, schema, prefix }) => {
|
|
3973
4036
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3974
|
-
const {
|
|
3975
|
-
const
|
|
4037
|
+
const { timezone } = useSchemaContext();
|
|
4038
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4039
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD", dateFormat = "YYYY-MM-DD", } = schema;
|
|
3976
4040
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3977
|
-
const colLabel =
|
|
4041
|
+
const colLabel = formI18n.colLabel;
|
|
3978
4042
|
const [open, setOpen] = React.useState(false);
|
|
3979
4043
|
const selectedDate = watch(colLabel);
|
|
3980
4044
|
const displayDate = dayjs(selectedDate).tz(timezone).format(displayDateFormat);
|
|
@@ -4001,10 +4065,7 @@ const DatePicker = ({ column, schema, prefix }) => {
|
|
|
4001
4065
|
console.error(e);
|
|
4002
4066
|
}
|
|
4003
4067
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
4004
|
-
|
|
4005
|
-
return translateWrapper({ prefix, column, label, translate });
|
|
4006
|
-
};
|
|
4007
|
-
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
4068
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
4008
4069
|
gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
4009
4070
|
setOpen(true);
|
|
4010
4071
|
}, 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 }) => {
|
|
@@ -4012,37 +4073,37 @@ const DatePicker = ({ column, schema, prefix }) => {
|
|
|
4012
4073
|
setOpen(false);
|
|
4013
4074
|
}, labels: {
|
|
4014
4075
|
monthNamesShort: [
|
|
4015
|
-
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
4016
|
-
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
4017
|
-
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
4018
|
-
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
4019
|
-
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
4020
|
-
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4021
|
-
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4022
|
-
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4023
|
-
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4024
|
-
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4025
|
-
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4026
|
-
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4076
|
+
formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
4077
|
+
formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
4078
|
+
formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
4079
|
+
formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
4080
|
+
formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
4081
|
+
formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
4082
|
+
formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
4083
|
+
formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
4084
|
+
formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
4085
|
+
formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
4086
|
+
formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
4087
|
+
formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
4027
4088
|
],
|
|
4028
4089
|
weekdayNamesShort: [
|
|
4029
|
-
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4030
|
-
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4031
|
-
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4032
|
-
translate.t(`common.weekday_4`, {
|
|
4090
|
+
formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
4091
|
+
formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
4092
|
+
formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
4093
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
4033
4094
|
defaultValue: "Wed",
|
|
4034
4095
|
}),
|
|
4035
|
-
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4036
|
-
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4037
|
-
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4096
|
+
formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
4097
|
+
formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
4098
|
+
formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
4038
4099
|
],
|
|
4039
|
-
backButtonLabel: translate.t(`common.back_button`, {
|
|
4100
|
+
backButtonLabel: formI18n.translate.t(`common.back_button`, {
|
|
4040
4101
|
defaultValue: "Back",
|
|
4041
4102
|
}),
|
|
4042
|
-
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
4103
|
+
forwardButtonLabel: formI18n.translate.t(`common.forward_button`, {
|
|
4043
4104
|
defaultValue: "Forward",
|
|
4044
4105
|
}),
|
|
4045
|
-
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children:
|
|
4106
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
4046
4107
|
};
|
|
4047
4108
|
|
|
4048
4109
|
function filterArray(array, searchTerm) {
|
|
@@ -4060,7 +4121,7 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4060
4121
|
const { translate } = useSchemaContext();
|
|
4061
4122
|
const { required, variant } = schema;
|
|
4062
4123
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4063
|
-
const { gridColumn = "span
|
|
4124
|
+
const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
|
|
4064
4125
|
const [searchText, setSearchText] = React.useState();
|
|
4065
4126
|
const [limit, setLimit] = React.useState(10);
|
|
4066
4127
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
@@ -4502,7 +4563,7 @@ const FileDropzone = ({ children = undefined, gridProps = {}, onDrop = () => { }
|
|
|
4502
4563
|
const FilePicker = ({ column, schema, prefix }) => {
|
|
4503
4564
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4504
4565
|
const { translate } = useSchemaContext();
|
|
4505
|
-
const { required, gridColumn = "span
|
|
4566
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
|
|
4506
4567
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4507
4568
|
const currentFiles = (watch(column) ?? []);
|
|
4508
4569
|
const colLabel = `${prefix}${column}`;
|
|
@@ -4557,16 +4618,17 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
4557
4618
|
|
|
4558
4619
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
4559
4620
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4560
|
-
const { serverUrl, idMap, setIdMap,
|
|
4561
|
-
const
|
|
4621
|
+
const { serverUrl, idMap, setIdMap, schema: parentSchema, idPickerLabels, } = useSchemaContext();
|
|
4622
|
+
const formI18n = useFormI18n(column, prefix);
|
|
4623
|
+
const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
|
|
4562
4624
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4563
4625
|
const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
|
|
4564
|
-
const [searchText, setSearchText] = React.useState(
|
|
4626
|
+
const [searchText, setSearchText] = React.useState('');
|
|
4565
4627
|
const [limit, setLimit] = React.useState(10);
|
|
4566
4628
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4567
4629
|
const [page, setPage] = React.useState(0);
|
|
4568
4630
|
const ref = React.useRef(null);
|
|
4569
|
-
const colLabel =
|
|
4631
|
+
const colLabel = formI18n.colLabel;
|
|
4570
4632
|
const watchId = watch(colLabel);
|
|
4571
4633
|
const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
|
|
4572
4634
|
// Query for search results
|
|
@@ -4575,7 +4637,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4575
4637
|
queryFn: async () => {
|
|
4576
4638
|
if (customQueryFn) {
|
|
4577
4639
|
const { data, idMap } = await customQueryFn({
|
|
4578
|
-
searching: searchText ??
|
|
4640
|
+
searching: searchText ?? '',
|
|
4579
4641
|
limit: limit,
|
|
4580
4642
|
offset: page * limit,
|
|
4581
4643
|
});
|
|
@@ -4586,7 +4648,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4586
4648
|
}
|
|
4587
4649
|
const data = await getTableData({
|
|
4588
4650
|
serverUrl,
|
|
4589
|
-
searching: searchText ??
|
|
4651
|
+
searching: searchText ?? '',
|
|
4590
4652
|
in_table: table,
|
|
4591
4653
|
limit: limit,
|
|
4592
4654
|
offset: page * limit,
|
|
@@ -4616,7 +4678,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4616
4678
|
queryFn: async () => {
|
|
4617
4679
|
if (customQueryFn) {
|
|
4618
4680
|
const { data, idMap } = await customQueryFn({
|
|
4619
|
-
searching: watchIds.join(
|
|
4681
|
+
searching: watchIds.join(','),
|
|
4620
4682
|
limit: isMultiple ? watchIds.length : 1,
|
|
4621
4683
|
offset: 0,
|
|
4622
4684
|
});
|
|
@@ -4628,7 +4690,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4628
4690
|
if (!watchId && (!watchIds || watchIds.length === 0)) {
|
|
4629
4691
|
return { data: [] };
|
|
4630
4692
|
}
|
|
4631
|
-
const searchValue = isMultiple ? watchIds.join(
|
|
4693
|
+
const searchValue = isMultiple ? watchIds.join(',') : watchId;
|
|
4632
4694
|
const data = await getTableData({
|
|
4633
4695
|
serverUrl,
|
|
4634
4696
|
searching: searchValue,
|
|
@@ -4665,7 +4727,7 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4665
4727
|
React.useEffect(() => {
|
|
4666
4728
|
if (openSearchResult) {
|
|
4667
4729
|
// Reset search text when opening the popover
|
|
4668
|
-
setSearchText(
|
|
4730
|
+
setSearchText('');
|
|
4669
4731
|
// Reset page to first page
|
|
4670
4732
|
setPage(0);
|
|
4671
4733
|
// Fetch initial data
|
|
@@ -4691,44 +4753,44 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4691
4753
|
const count = data?.count ?? 0;
|
|
4692
4754
|
const getPickedValue = () => {
|
|
4693
4755
|
if (Object.keys(idMap).length <= 0) {
|
|
4694
|
-
return
|
|
4756
|
+
return '';
|
|
4695
4757
|
}
|
|
4696
4758
|
const record = idMap[watchId];
|
|
4697
4759
|
if (record === undefined) {
|
|
4698
|
-
return
|
|
4760
|
+
return '';
|
|
4699
4761
|
}
|
|
4700
4762
|
if (!!renderDisplay === true) {
|
|
4701
4763
|
return renderDisplay(record);
|
|
4702
4764
|
}
|
|
4703
4765
|
return record[display_column];
|
|
4704
4766
|
};
|
|
4705
|
-
return (jsxRuntime.jsxs(Field, { label:
|
|
4706
|
-
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow:
|
|
4767
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4768
|
+
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: 'wrap', gap: 1, children: [watchIds.map((id) => {
|
|
4707
4769
|
const item = idMap[id];
|
|
4708
4770
|
if (item === undefined) {
|
|
4709
|
-
return (jsxRuntime.jsx(react.Text, { children:
|
|
4771
|
+
return (jsxRuntime.jsx(react.Text, { children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
|
|
4710
4772
|
}
|
|
4711
4773
|
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
4712
4774
|
setValue(colLabel, watchIds.filter((itemId) => itemId !== item[column_ref]));
|
|
4713
4775
|
}, children: !!renderDisplay === true
|
|
4714
4776
|
? renderDisplay(item)
|
|
4715
4777
|
: item[display_column] }, id));
|
|
4716
|
-
}), jsxRuntime.jsx(Tag, { cursor:
|
|
4778
|
+
}), jsxRuntime.jsx(Tag, { cursor: 'pointer', onClick: () => {
|
|
4717
4779
|
setOpenSearchResult(true);
|
|
4718
|
-
}, children:
|
|
4780
|
+
}, children: idPickerLabels?.addMore ?? formI18n.t('add_more') })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: 'outline', onClick: () => {
|
|
4719
4781
|
setOpenSearchResult(true);
|
|
4720
|
-
}, justifyContent:
|
|
4782
|
+
}, justifyContent: 'start', children: queryDefault.isLoading ? jsxRuntime.jsx(react.Spinner, { size: "sm" }) : getPickedValue() })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start', strategy: 'fixed' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: onSearchChange, autoComplete: "off", ref: ref, value: searchText }), jsxRuntime.jsx(PopoverTitle, {}), openSearchResult && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, {}), isError && (jsxRuntime.jsx(react.Icon, { color: 'red.400', children: jsxRuntime.jsx(bi.BiError, {}) })), jsxRuntime.jsxs(react.Flex, { justifyContent: "space-between", alignItems: "center", children: [jsxRuntime.jsxs(react.Flex, { alignItems: "center", gap: "2", children: [jsxRuntime.jsx(InfoTip, { children: `${idPickerLabels?.total ?? formI18n.t('total')} ${count}, ${idPickerLabels?.showing ?? formI18n.t('showing')} ${limit} ${idPickerLabels?.perPage ?? formI18n.t('per_page', { defaultValue: 'per page' })}` }), jsxRuntime.jsxs(react.Text, { fontSize: "sm", fontWeight: "bold", children: [count, jsxRuntime.jsxs(react.Text, { as: "span", fontSize: "xs", ml: "1", color: "gray.500", children: ["/", ' ', count > 0
|
|
4721
4783
|
? `${page * limit + 1}-${Math.min((page + 1) * limit, count)}`
|
|
4722
|
-
:
|
|
4723
|
-
padding:
|
|
4724
|
-
borderRadius:
|
|
4725
|
-
border:
|
|
4726
|
-
fontSize:
|
|
4727
|
-
}, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY:
|
|
4784
|
+
: '0'] })] })] }), jsxRuntime.jsx(react.Box, { children: jsxRuntime.jsxs("select", { value: limit, onChange: handleLimitChange, style: {
|
|
4785
|
+
padding: '4px 8px',
|
|
4786
|
+
borderRadius: '4px',
|
|
4787
|
+
border: '1px solid #ccc',
|
|
4788
|
+
fontSize: '14px',
|
|
4789
|
+
}, children: [jsxRuntime.jsx("option", { value: "5", children: "5" }), jsxRuntime.jsx("option", { value: "10", children: "10" }), jsxRuntime.jsx("option", { value: "20", children: "20" }), jsxRuntime.jsx("option", { value: "30", children: "30" })] }) })] }), jsxRuntime.jsx(react.Grid, { overflowY: 'auto', children: dataList.length > 0 ? (jsxRuntime.jsx(react.Flex, { flexFlow: 'column wrap', gap: 1, children: dataList.map((item) => {
|
|
4728
4790
|
const selected = isMultiple
|
|
4729
4791
|
? watchIds.some((id) => item[column_ref] === id)
|
|
4730
4792
|
: watchId === item[column_ref];
|
|
4731
|
-
return (jsxRuntime.jsx(react.Box, { cursor:
|
|
4793
|
+
return (jsxRuntime.jsx(react.Box, { cursor: 'pointer', onClick: () => {
|
|
4732
4794
|
if (!isMultiple) {
|
|
4733
4795
|
setOpenSearchResult(false);
|
|
4734
4796
|
setValue(colLabel, item[column_ref]);
|
|
@@ -4744,15 +4806,17 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
4744
4806
|
setValue(colLabel, [...newSet]);
|
|
4745
4807
|
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
4746
4808
|
? {
|
|
4747
|
-
color:
|
|
4748
|
-
fontWeight:
|
|
4809
|
+
color: 'colorPalette.400/50',
|
|
4810
|
+
fontWeight: 'bold',
|
|
4749
4811
|
}
|
|
4750
4812
|
: {}), children: !!renderDisplay === true
|
|
4751
4813
|
? renderDisplay(item)
|
|
4752
4814
|
: item[display_column] }, item[column_ref]));
|
|
4753
4815
|
}) })) : (jsxRuntime.jsx(react.Text, { children: searchText
|
|
4754
|
-
?
|
|
4755
|
-
|
|
4816
|
+
? idPickerLabels?.emptySearchResult ??
|
|
4817
|
+
formI18n.t('empty_search_result')
|
|
4818
|
+
: idPickerLabels?.initialResults ??
|
|
4819
|
+
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, {})] }) })] }))] }) })] }), errors[`${colLabel}`] && (jsxRuntime.jsx(react.Text, { color: 'red.400', children: formI18n.required() }))] }));
|
|
4756
4820
|
};
|
|
4757
4821
|
|
|
4758
4822
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
@@ -4766,7 +4830,7 @@ react.NumberInput.Label;
|
|
|
4766
4830
|
const NumberInputField = ({ schema, column, prefix, }) => {
|
|
4767
4831
|
const { setValue, formState: { errors }, watch, } = reactHookForm.useFormContext();
|
|
4768
4832
|
const { translate } = useSchemaContext();
|
|
4769
|
-
const { required, gridColumn = "span
|
|
4833
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4770
4834
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4771
4835
|
const colLabel = `${prefix}${column}`;
|
|
4772
4836
|
const value = watch(`${colLabel}`);
|
|
@@ -4851,7 +4915,7 @@ const RecordInput$1 = ({ column, schema, prefix }) => {
|
|
|
4851
4915
|
const StringInputField = ({ column, schema, prefix, }) => {
|
|
4852
4916
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
4853
4917
|
const { translate } = useSchemaContext();
|
|
4854
|
-
const { required, gridColumn = "span
|
|
4918
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
4855
4919
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4856
4920
|
const colLabel = `${prefix}${column}`;
|
|
4857
4921
|
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(Field, { label: `${translate.t(removeIndex(`${colLabel}.field_label`))}`, required: isRequired, gridColumn: gridColumn, gridRow: gridRow, children: [jsxRuntime.jsx(react.Input, { ...register(`${colLabel}`, { required: isRequired }), autoComplete: "off" }), errors[colLabel] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }) }));
|
|
@@ -5040,7 +5104,7 @@ Textarea.displayName = "Textarea";
|
|
|
5040
5104
|
const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
5041
5105
|
const { register, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5042
5106
|
const { translate } = useSchemaContext();
|
|
5043
|
-
const { required, gridColumn = "span
|
|
5107
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5044
5108
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5045
5109
|
const colLabel = `${prefix}${column}`;
|
|
5046
5110
|
const form = reactHookForm.useFormContext();
|
|
@@ -5177,7 +5241,7 @@ dayjs.extend(timezone);
|
|
|
5177
5241
|
const TimePicker = ({ column, schema, prefix }) => {
|
|
5178
5242
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5179
5243
|
const { translate, timezone } = useSchemaContext();
|
|
5180
|
-
const { required, gridColumn = "span
|
|
5244
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", timeFormat = "HH:mm:ssZ", displayTimeFormat = "hh:mm A", } = schema;
|
|
5181
5245
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5182
5246
|
const colLabel = `${prefix}${column}`;
|
|
5183
5247
|
const [open, setOpen] = React.useState(false);
|
|
@@ -5439,12 +5503,13 @@ dayjs.extend(utc);
|
|
|
5439
5503
|
dayjs.extend(timezone);
|
|
5440
5504
|
const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
5441
5505
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
5442
|
-
const {
|
|
5443
|
-
const
|
|
5506
|
+
const { timezone, dateTimePickerLabels } = useSchemaContext();
|
|
5507
|
+
const formI18n = useFormI18n(column, prefix);
|
|
5508
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayDateFormat = "YYYY-MM-DD HH:mm:ss",
|
|
5444
5509
|
// with timezone
|
|
5445
5510
|
dateFormat = "YYYY-MM-DD[T]HH:mm:ssZ", } = schema;
|
|
5446
5511
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5447
|
-
const colLabel =
|
|
5512
|
+
const colLabel = formI18n.colLabel;
|
|
5448
5513
|
const [open, setOpen] = React.useState(false);
|
|
5449
5514
|
const selectedDate = watch(colLabel);
|
|
5450
5515
|
const displayDate = dayjs(selectedDate)
|
|
@@ -5473,47 +5538,44 @@ const DateTimePicker = ({ column, schema, prefix, }) => {
|
|
|
5473
5538
|
console.error(e);
|
|
5474
5539
|
}
|
|
5475
5540
|
}, [selectedDate, dateFormat, colLabel, setValue]);
|
|
5476
|
-
|
|
5477
|
-
return translateWrapper({ prefix, column, label, translate });
|
|
5478
|
-
};
|
|
5479
|
-
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5541
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
5480
5542
|
gridRow, children: [jsxRuntime.jsxs(PopoverRoot, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
5481
5543
|
setOpen(true);
|
|
5482
5544
|
}, 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) => {
|
|
5483
5545
|
setValue(colLabel, dayjs(date).tz(timezone).format(dateFormat));
|
|
5484
5546
|
}, timezone: timezone, labels: {
|
|
5485
|
-
monthNamesShort: [
|
|
5486
|
-
translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5487
|
-
translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5488
|
-
translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5489
|
-
translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5490
|
-
translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5491
|
-
translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5492
|
-
translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5493
|
-
translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5494
|
-
translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5495
|
-
translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5496
|
-
translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5497
|
-
translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5547
|
+
monthNamesShort: dateTimePickerLabels?.monthNamesShort ?? [
|
|
5548
|
+
formI18n.translate.t(`common.month_1`, { defaultValue: "January" }),
|
|
5549
|
+
formI18n.translate.t(`common.month_2`, { defaultValue: "February" }),
|
|
5550
|
+
formI18n.translate.t(`common.month_3`, { defaultValue: "March" }),
|
|
5551
|
+
formI18n.translate.t(`common.month_4`, { defaultValue: "April" }),
|
|
5552
|
+
formI18n.translate.t(`common.month_5`, { defaultValue: "May" }),
|
|
5553
|
+
formI18n.translate.t(`common.month_6`, { defaultValue: "June" }),
|
|
5554
|
+
formI18n.translate.t(`common.month_7`, { defaultValue: "July" }),
|
|
5555
|
+
formI18n.translate.t(`common.month_8`, { defaultValue: "August" }),
|
|
5556
|
+
formI18n.translate.t(`common.month_9`, { defaultValue: "September" }),
|
|
5557
|
+
formI18n.translate.t(`common.month_10`, { defaultValue: "October" }),
|
|
5558
|
+
formI18n.translate.t(`common.month_11`, { defaultValue: "November" }),
|
|
5559
|
+
formI18n.translate.t(`common.month_12`, { defaultValue: "December" }),
|
|
5498
5560
|
],
|
|
5499
|
-
weekdayNamesShort: [
|
|
5500
|
-
translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5501
|
-
translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5502
|
-
translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5503
|
-
translate.t(`common.weekday_4`, {
|
|
5561
|
+
weekdayNamesShort: dateTimePickerLabels?.weekdayNamesShort ?? [
|
|
5562
|
+
formI18n.translate.t(`common.weekday_1`, { defaultValue: "Sun" }),
|
|
5563
|
+
formI18n.translate.t(`common.weekday_2`, { defaultValue: "Mon" }),
|
|
5564
|
+
formI18n.translate.t(`common.weekday_3`, { defaultValue: "Tue" }),
|
|
5565
|
+
formI18n.translate.t(`common.weekday_4`, {
|
|
5504
5566
|
defaultValue: "Wed",
|
|
5505
5567
|
}),
|
|
5506
|
-
translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5507
|
-
translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5508
|
-
translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5568
|
+
formI18n.translate.t(`common.weekday_5`, { defaultValue: "Thu" }),
|
|
5569
|
+
formI18n.translate.t(`common.weekday_6`, { defaultValue: "Fri" }),
|
|
5570
|
+
formI18n.translate.t(`common.weekday_7`, { defaultValue: "Sat" }),
|
|
5509
5571
|
],
|
|
5510
|
-
backButtonLabel: translate.t(`common.back_button`, {
|
|
5572
|
+
backButtonLabel: dateTimePickerLabels?.backButtonLabel ?? formI18n.translate.t(`common.back_button`, {
|
|
5511
5573
|
defaultValue: "Back",
|
|
5512
5574
|
}),
|
|
5513
|
-
forwardButtonLabel: translate.t(`common.forward_button`, {
|
|
5575
|
+
forwardButtonLabel: dateTimePickerLabels?.forwardButtonLabel ?? formI18n.translate.t(`common.forward_button`, {
|
|
5514
5576
|
defaultValue: "Forward",
|
|
5515
5577
|
}),
|
|
5516
|
-
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children:
|
|
5578
|
+
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
5517
5579
|
};
|
|
5518
5580
|
|
|
5519
5581
|
const SchemaRenderer = ({ schema, prefix, column, }) => {
|
|
@@ -5615,7 +5677,7 @@ const ArrayViewer = ({ schema, column, prefix }) => {
|
|
|
5615
5677
|
const BooleanViewer = ({ schema, column, prefix, }) => {
|
|
5616
5678
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5617
5679
|
const { translate } = useSchemaContext();
|
|
5618
|
-
const { required, gridColumn = "span
|
|
5680
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5619
5681
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5620
5682
|
const colLabel = `${prefix}${column}`;
|
|
5621
5683
|
const value = watch(colLabel);
|
|
@@ -5651,17 +5713,14 @@ const DateViewer = ({ column, schema, prefix }) => {
|
|
|
5651
5713
|
|
|
5652
5714
|
const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
5653
5715
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5654
|
-
const
|
|
5716
|
+
const formI18n = useFormI18n(column, prefix);
|
|
5655
5717
|
const { required } = schema;
|
|
5656
5718
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5657
|
-
const { gridColumn = "span
|
|
5658
|
-
const colLabel =
|
|
5719
|
+
const { gridColumn = "span 12", gridRow = "span 1", renderDisplay } = schema;
|
|
5720
|
+
const colLabel = formI18n.colLabel;
|
|
5659
5721
|
const watchEnum = watch(colLabel);
|
|
5660
5722
|
const watchEnums = (watch(colLabel) ?? []);
|
|
5661
|
-
|
|
5662
|
-
return translateWrapper({ prefix, column, label, translate });
|
|
5663
|
-
};
|
|
5664
|
-
return (jsxRuntime.jsxs(Field, { label: `${customTranslate(`field_label`)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
5723
|
+
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: "stretch", gridColumn,
|
|
5665
5724
|
gridRow, children: [isMultiple && (jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 1, children: watchEnums.map((enumValue) => {
|
|
5666
5725
|
const item = enumValue;
|
|
5667
5726
|
if (item === undefined) {
|
|
@@ -5669,14 +5728,14 @@ const EnumViewer = ({ column, isMultiple = false, schema, prefix, }) => {
|
|
|
5669
5728
|
}
|
|
5670
5729
|
return (jsxRuntime.jsx(Tag, { size: "lg", children: !!renderDisplay === true
|
|
5671
5730
|
? renderDisplay(item)
|
|
5672
|
-
:
|
|
5673
|
-
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children:
|
|
5731
|
+
: formI18n.t(item) }, item));
|
|
5732
|
+
}) })), !isMultiple && jsxRuntime.jsx(react.Text, { children: formI18n.t(watchEnum) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: formI18n.required() }))] }));
|
|
5674
5733
|
};
|
|
5675
5734
|
|
|
5676
5735
|
const FileViewer = ({ column, schema, prefix }) => {
|
|
5677
5736
|
const { watch } = reactHookForm.useFormContext();
|
|
5678
5737
|
const { translate } = useSchemaContext();
|
|
5679
|
-
const { required, gridColumn = "span
|
|
5738
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", } = schema;
|
|
5680
5739
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5681
5740
|
const currentFiles = (watch(column) ?? []);
|
|
5682
5741
|
const colLabel = `${prefix}${column}`;
|
|
@@ -5688,7 +5747,7 @@ const FileViewer = ({ column, schema, prefix }) => {
|
|
|
5688
5747
|
const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
5689
5748
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5690
5749
|
const { idMap, translate } = useSchemaContext();
|
|
5691
|
-
const { required, gridColumn = "span
|
|
5750
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", renderDisplay, foreign_key, } = schema;
|
|
5692
5751
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5693
5752
|
const { display_column } = foreign_key;
|
|
5694
5753
|
const colLabel = `${prefix}${column}`;
|
|
@@ -5719,7 +5778,7 @@ const IdViewer = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5719
5778
|
const NumberViewer = ({ schema, column, prefix, }) => {
|
|
5720
5779
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5721
5780
|
const { translate } = useSchemaContext();
|
|
5722
|
-
const { required, gridColumn = "span
|
|
5781
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5723
5782
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5724
5783
|
const colLabel = `${prefix}${column}`;
|
|
5725
5784
|
const value = watch(colLabel);
|
|
@@ -5750,7 +5809,7 @@ const ObjectViewer = ({ schema, column, prefix }) => {
|
|
|
5750
5809
|
const RecordInput = ({ column, schema, prefix }) => {
|
|
5751
5810
|
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
5752
5811
|
const { translate } = useSchemaContext();
|
|
5753
|
-
const { required, gridColumn = "span
|
|
5812
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5754
5813
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5755
5814
|
const entries = Object.entries(getValues(column) ?? {});
|
|
5756
5815
|
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
@@ -5802,7 +5861,7 @@ const RecordInput = ({ column, schema, prefix }) => {
|
|
|
5802
5861
|
const StringViewer = ({ column, schema, prefix, }) => {
|
|
5803
5862
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5804
5863
|
const { translate } = useSchemaContext();
|
|
5805
|
-
const { required, gridColumn = "span
|
|
5864
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5806
5865
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5807
5866
|
const colLabel = `${prefix}${column}`;
|
|
5808
5867
|
const value = watch(colLabel);
|
|
@@ -5897,7 +5956,7 @@ const TagViewer = ({ column, schema, prefix }) => {
|
|
|
5897
5956
|
const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
5898
5957
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5899
5958
|
const { translate } = useSchemaContext();
|
|
5900
|
-
const { required, gridColumn = "span
|
|
5959
|
+
const { required, gridColumn = "span 12", gridRow = "span 1" } = schema;
|
|
5901
5960
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5902
5961
|
const colLabel = `${prefix}${column}`;
|
|
5903
5962
|
const value = watch(colLabel);
|
|
@@ -5907,7 +5966,7 @@ const TextAreaViewer = ({ column, schema, prefix, }) => {
|
|
|
5907
5966
|
const TimeViewer = ({ column, schema, prefix }) => {
|
|
5908
5967
|
const { watch, formState: { errors }, } = reactHookForm.useFormContext();
|
|
5909
5968
|
const { translate, timezone } = useSchemaContext();
|
|
5910
|
-
const { required, gridColumn = "span
|
|
5969
|
+
const { required, gridColumn = "span 12", gridRow = "span 1", displayTimeFormat = "hh:mm A", } = schema;
|
|
5911
5970
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5912
5971
|
const colLabel = `${prefix}${column}`;
|
|
5913
5972
|
const selectedDate = watch(colLabel);
|
|
@@ -6039,7 +6098,7 @@ const SubmitButton = () => {
|
|
|
6039
6098
|
};
|
|
6040
6099
|
|
|
6041
6100
|
const FormBody = () => {
|
|
6042
|
-
const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, displayConfig, } = useSchemaContext();
|
|
6101
|
+
const { schema, requestUrl, order, ignore, include, onSubmit, translate, requestOptions, isSuccess, setIsSuccess, isError, setIsError, isSubmiting, setIsSubmiting, isConfirming, setIsConfirming, validatedData, setValidatedData, error, setError, getUpdatedData, customErrorRenderer, customSuccessRenderer, displayConfig, } = useSchemaContext();
|
|
6043
6102
|
const { showSubmitButton, showResetButton } = displayConfig;
|
|
6044
6103
|
const methods = reactHookForm.useFormContext();
|
|
6045
6104
|
const { properties } = schema;
|
|
@@ -6136,15 +6195,19 @@ const FormBody = () => {
|
|
|
6136
6195
|
include,
|
|
6137
6196
|
});
|
|
6138
6197
|
if (isSuccess) {
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6198
|
+
const resetHandler = async () => {
|
|
6199
|
+
setIsError(false);
|
|
6200
|
+
setIsSubmiting(false);
|
|
6201
|
+
setIsSuccess(false);
|
|
6202
|
+
setIsConfirming(false);
|
|
6203
|
+
setValidatedData(undefined);
|
|
6204
|
+
const data = await getUpdatedData();
|
|
6205
|
+
methods.reset(data);
|
|
6206
|
+
};
|
|
6207
|
+
if (customSuccessRenderer) {
|
|
6208
|
+
return customSuccessRenderer(resetHandler);
|
|
6209
|
+
}
|
|
6210
|
+
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") }) })] }));
|
|
6148
6211
|
}
|
|
6149
6212
|
if (isConfirming) {
|
|
6150
6213
|
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) => {
|
|
@@ -6182,12 +6245,12 @@ const DefaultForm = ({ formConfig, }) => {
|
|
|
6182
6245
|
return (jsxRuntime.jsx(FormRoot, { ...formConfig, children: jsxRuntime.jsxs(react.Grid, { gap: "2", children: [showTitle && jsxRuntime.jsx(FormTitle, {}), jsxRuntime.jsx(FormBody, {})] }) }));
|
|
6183
6246
|
};
|
|
6184
6247
|
|
|
6185
|
-
const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
6248
|
+
const useForm = ({ preLoadedValues, keyPrefix, namespace }) => {
|
|
6186
6249
|
const form = reactHookForm.useForm({
|
|
6187
6250
|
values: preLoadedValues,
|
|
6188
6251
|
});
|
|
6189
6252
|
const [idMap, setIdMap] = React.useState({});
|
|
6190
|
-
const translate = reactI18next.useTranslation("", { keyPrefix });
|
|
6253
|
+
const translate = reactI18next.useTranslation(namespace || "", { keyPrefix });
|
|
6191
6254
|
return {
|
|
6192
6255
|
form,
|
|
6193
6256
|
idMap,
|
|
@@ -6196,6 +6259,207 @@ const useForm = ({ preLoadedValues, keyPrefix }) => {
|
|
|
6196
6259
|
};
|
|
6197
6260
|
};
|
|
6198
6261
|
|
|
6262
|
+
/**
|
|
6263
|
+
* Type definitions for error message configuration
|
|
6264
|
+
*/
|
|
6265
|
+
/**
|
|
6266
|
+
* Schema-level error message builder
|
|
6267
|
+
*
|
|
6268
|
+
* Builds a complete errorMessage object compatible with ajv-errors plugin.
|
|
6269
|
+
* Supports both i18n translation keys and plain string messages.
|
|
6270
|
+
*
|
|
6271
|
+
* @param config - Error message configuration
|
|
6272
|
+
* @returns Complete errorMessage object for JSON Schema
|
|
6273
|
+
*
|
|
6274
|
+
* @example
|
|
6275
|
+
* ```typescript
|
|
6276
|
+
* // Simple required field errors
|
|
6277
|
+
* const errorMessage = buildErrorMessages({
|
|
6278
|
+
* required: {
|
|
6279
|
+
* username: "Username is required",
|
|
6280
|
+
* email: "user.email.field_required" // i18n key
|
|
6281
|
+
* }
|
|
6282
|
+
* });
|
|
6283
|
+
*
|
|
6284
|
+
* // With validation rules
|
|
6285
|
+
* const errorMessage = buildErrorMessages({
|
|
6286
|
+
* required: {
|
|
6287
|
+
* password: "Password is required"
|
|
6288
|
+
* },
|
|
6289
|
+
* properties: {
|
|
6290
|
+
* password: {
|
|
6291
|
+
* minLength: "Password must be at least 8 characters",
|
|
6292
|
+
* pattern: "Password must contain letters and numbers"
|
|
6293
|
+
* },
|
|
6294
|
+
* age: {
|
|
6295
|
+
* minimum: "Must be 18 or older",
|
|
6296
|
+
* maximum: "Must be under 120"
|
|
6297
|
+
* }
|
|
6298
|
+
* }
|
|
6299
|
+
* });
|
|
6300
|
+
*
|
|
6301
|
+
* // With global fallbacks
|
|
6302
|
+
* const errorMessage = buildErrorMessages({
|
|
6303
|
+
* required: {
|
|
6304
|
+
* email: "Email is required"
|
|
6305
|
+
* },
|
|
6306
|
+
* minLength: "This field is too short", // applies to all fields
|
|
6307
|
+
* minimum: "Value is too small"
|
|
6308
|
+
* });
|
|
6309
|
+
* ```
|
|
6310
|
+
*/
|
|
6311
|
+
const buildErrorMessages = (config) => {
|
|
6312
|
+
const result = {};
|
|
6313
|
+
// Add required field errors
|
|
6314
|
+
if (config.required && Object.keys(config.required).length > 0) {
|
|
6315
|
+
result.required = config.required;
|
|
6316
|
+
}
|
|
6317
|
+
// Add field-specific validation errors
|
|
6318
|
+
if (config.properties && Object.keys(config.properties).length > 0) {
|
|
6319
|
+
result.properties = config.properties;
|
|
6320
|
+
}
|
|
6321
|
+
// Add global fallback error messages
|
|
6322
|
+
const globalKeys = [
|
|
6323
|
+
"minLength",
|
|
6324
|
+
"maxLength",
|
|
6325
|
+
"pattern",
|
|
6326
|
+
"minimum",
|
|
6327
|
+
"maximum",
|
|
6328
|
+
"multipleOf",
|
|
6329
|
+
"format",
|
|
6330
|
+
"type",
|
|
6331
|
+
"enum",
|
|
6332
|
+
];
|
|
6333
|
+
globalKeys.forEach((key) => {
|
|
6334
|
+
if (config[key]) {
|
|
6335
|
+
result[key] = config[key];
|
|
6336
|
+
}
|
|
6337
|
+
});
|
|
6338
|
+
return result;
|
|
6339
|
+
};
|
|
6340
|
+
/**
|
|
6341
|
+
* Helper function to build required field errors
|
|
6342
|
+
*
|
|
6343
|
+
* Simplifies creating required field error messages, especially useful
|
|
6344
|
+
* for generating i18n translation keys following a pattern.
|
|
6345
|
+
*
|
|
6346
|
+
* @param fields - Array of required field names
|
|
6347
|
+
* @param messageOrGenerator - Either a string template or function to generate messages
|
|
6348
|
+
* @returns Required field error configuration
|
|
6349
|
+
*
|
|
6350
|
+
* @example
|
|
6351
|
+
* ```typescript
|
|
6352
|
+
* // Plain string messages
|
|
6353
|
+
* const required = buildRequiredErrors(
|
|
6354
|
+
* ["username", "email", "password"],
|
|
6355
|
+
* (field) => `${field} is required`
|
|
6356
|
+
* );
|
|
6357
|
+
* // Result: { username: "username is required", email: "email is required", ... }
|
|
6358
|
+
*
|
|
6359
|
+
* // i18n translation keys
|
|
6360
|
+
* const required = buildRequiredErrors(
|
|
6361
|
+
* ["username", "email"],
|
|
6362
|
+
* (field) => `user.${field}.field_required`
|
|
6363
|
+
* );
|
|
6364
|
+
* // Result: { username: "user.username.field_required", email: "user.email.field_required" }
|
|
6365
|
+
*
|
|
6366
|
+
* // Same message for all fields
|
|
6367
|
+
* const required = buildRequiredErrors(
|
|
6368
|
+
* ["username", "email"],
|
|
6369
|
+
* "This field is required"
|
|
6370
|
+
* );
|
|
6371
|
+
* // Result: { username: "This field is required", email: "This field is required" }
|
|
6372
|
+
*
|
|
6373
|
+
* // With keyPrefix for i18n
|
|
6374
|
+
* const required = buildRequiredErrors(
|
|
6375
|
+
* ["username", "email"],
|
|
6376
|
+
* (field) => `${field}.field_required`,
|
|
6377
|
+
* "user"
|
|
6378
|
+
* );
|
|
6379
|
+
* // Result: { username: "user.username.field_required", email: "user.email.field_required" }
|
|
6380
|
+
* ```
|
|
6381
|
+
*/
|
|
6382
|
+
const buildRequiredErrors = (fields, messageOrGenerator, keyPrefix = "") => {
|
|
6383
|
+
const result = {};
|
|
6384
|
+
fields.forEach((field) => {
|
|
6385
|
+
if (typeof messageOrGenerator === "function") {
|
|
6386
|
+
const message = messageOrGenerator(field);
|
|
6387
|
+
result[field] = keyPrefix ? `${keyPrefix}.${message}` : message;
|
|
6388
|
+
}
|
|
6389
|
+
else {
|
|
6390
|
+
result[field] = messageOrGenerator;
|
|
6391
|
+
}
|
|
6392
|
+
});
|
|
6393
|
+
return result;
|
|
6394
|
+
};
|
|
6395
|
+
/**
|
|
6396
|
+
* Helper function to build field-specific validation errors
|
|
6397
|
+
*
|
|
6398
|
+
* Creates property-specific error messages for multiple fields at once.
|
|
6399
|
+
*
|
|
6400
|
+
* @param config - Maps field names to their validation error configurations
|
|
6401
|
+
* @returns Properties error configuration
|
|
6402
|
+
*
|
|
6403
|
+
* @example
|
|
6404
|
+
* ```typescript
|
|
6405
|
+
* const properties = buildFieldErrors({
|
|
6406
|
+
* username: {
|
|
6407
|
+
* minLength: "Username must be at least 3 characters",
|
|
6408
|
+
* pattern: "Username can only contain letters and numbers"
|
|
6409
|
+
* },
|
|
6410
|
+
* age: {
|
|
6411
|
+
* minimum: "Must be 18 or older",
|
|
6412
|
+
* maximum: "Must be under 120"
|
|
6413
|
+
* },
|
|
6414
|
+
* email: {
|
|
6415
|
+
* format: "Please enter a valid email address"
|
|
6416
|
+
* }
|
|
6417
|
+
* });
|
|
6418
|
+
* ```
|
|
6419
|
+
*/
|
|
6420
|
+
const buildFieldErrors = (config) => {
|
|
6421
|
+
return config;
|
|
6422
|
+
};
|
|
6423
|
+
/**
|
|
6424
|
+
* Helper function to create a complete error message configuration in one call
|
|
6425
|
+
*
|
|
6426
|
+
* Convenient wrapper that combines required and validation errors.
|
|
6427
|
+
*
|
|
6428
|
+
* @param required - Required field error messages
|
|
6429
|
+
* @param properties - Field-specific validation error messages
|
|
6430
|
+
* @param globalFallbacks - Global fallback error messages
|
|
6431
|
+
* @returns Complete error message configuration
|
|
6432
|
+
*
|
|
6433
|
+
* @example
|
|
6434
|
+
* ```typescript
|
|
6435
|
+
* const errorMessage = createErrorMessage(
|
|
6436
|
+
* {
|
|
6437
|
+
* username: "Username is required",
|
|
6438
|
+
* email: "Email is required"
|
|
6439
|
+
* },
|
|
6440
|
+
* {
|
|
6441
|
+
* username: {
|
|
6442
|
+
* minLength: "Username must be at least 3 characters"
|
|
6443
|
+
* },
|
|
6444
|
+
* email: {
|
|
6445
|
+
* format: "Please enter a valid email"
|
|
6446
|
+
* }
|
|
6447
|
+
* },
|
|
6448
|
+
* {
|
|
6449
|
+
* minLength: "This field is too short",
|
|
6450
|
+
* format: "Invalid format"
|
|
6451
|
+
* }
|
|
6452
|
+
* );
|
|
6453
|
+
* ```
|
|
6454
|
+
*/
|
|
6455
|
+
const createErrorMessage = (required, properties, globalFallbacks) => {
|
|
6456
|
+
return buildErrorMessages({
|
|
6457
|
+
required,
|
|
6458
|
+
properties,
|
|
6459
|
+
...globalFallbacks,
|
|
6460
|
+
});
|
|
6461
|
+
};
|
|
6462
|
+
|
|
6199
6463
|
const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) => {
|
|
6200
6464
|
if (!selectable) {
|
|
6201
6465
|
return [...selectedDates];
|
|
@@ -6253,6 +6517,10 @@ exports.TableSorter = TableSorter;
|
|
|
6253
6517
|
exports.TableViewer = TableViewer;
|
|
6254
6518
|
exports.TextCell = TextCell;
|
|
6255
6519
|
exports.ViewDialog = ViewDialog;
|
|
6520
|
+
exports.buildErrorMessages = buildErrorMessages;
|
|
6521
|
+
exports.buildFieldErrors = buildFieldErrors;
|
|
6522
|
+
exports.buildRequiredErrors = buildRequiredErrors;
|
|
6523
|
+
exports.createErrorMessage = createErrorMessage;
|
|
6256
6524
|
exports.getColumns = getColumns;
|
|
6257
6525
|
exports.getMultiDates = getMultiDates;
|
|
6258
6526
|
exports.getRangeDates = getRangeDates;
|