@bsol-oss/react-datatable5 8.0.1 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +242 -261
- package/dist/index.mjs +243 -262
- package/dist/types/components/Form/Form.d.ts +2 -0
- package/dist/types/components/Form/SchemaFormContext.d.ts +4 -2
- package/dist/types/components/Form/components/IdViewer.d.ts +3 -1
- package/dist/types/components/Form/components/StringInputField.d.ts +8 -5
- package/dist/types/components/Form/useSchemaContext.d.ts +4 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3560,16 +3560,17 @@ const Field = React__namespace.forwardRef(function Field(props, ref) {
|
|
|
3560
3560
|
});
|
|
3561
3561
|
|
|
3562
3562
|
const useSchemaContext = () => {
|
|
3563
|
-
const { schema, serverUrl, order, ignore, onSubmit,
|
|
3563
|
+
const { schema, serverUrl, order, ignore, onSubmit, rowNumber, displayText, idMap, setIdMap, } = React.useContext(SchemaFormContext);
|
|
3564
3564
|
return {
|
|
3565
3565
|
schema,
|
|
3566
3566
|
serverUrl,
|
|
3567
3567
|
order,
|
|
3568
3568
|
ignore,
|
|
3569
3569
|
onSubmit,
|
|
3570
|
-
preLoadedValues,
|
|
3571
3570
|
rowNumber,
|
|
3572
3571
|
displayText,
|
|
3572
|
+
idMap,
|
|
3573
|
+
setIdMap,
|
|
3573
3574
|
};
|
|
3574
3575
|
};
|
|
3575
3576
|
|
|
@@ -3607,7 +3608,7 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
3607
3608
|
|
|
3608
3609
|
const IdPicker = ({ column, isMultiple = false }) => {
|
|
3609
3610
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3610
|
-
const { schema, serverUrl, displayText } = useSchemaContext();
|
|
3611
|
+
const { schema, serverUrl, displayText, idMap, setIdMap } = useSchemaContext();
|
|
3611
3612
|
const { fieldRequired } = displayText;
|
|
3612
3613
|
const { required } = schema;
|
|
3613
3614
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
@@ -3617,21 +3618,20 @@ const IdPicker = ({ column, isMultiple = false }) => {
|
|
|
3617
3618
|
const { total, showing, typeToSearch } = displayText;
|
|
3618
3619
|
const { gridColumn, gridRow, title, renderDisplay, foreign_key } = schema
|
|
3619
3620
|
.properties[column];
|
|
3620
|
-
const { table
|
|
3621
|
+
const { table, column: column_ref, display_column, } = foreign_key;
|
|
3621
3622
|
const [searchText, setSearchText] = React.useState();
|
|
3622
3623
|
const [limit, setLimit] = React.useState(10);
|
|
3623
3624
|
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
3624
3625
|
const [page, setPage] = React.useState(0);
|
|
3625
|
-
const [idMap, setIdMap] = React.useState({});
|
|
3626
3626
|
const ref = React.useRef(null);
|
|
3627
3627
|
const selectedIds = watch(column) ?? [];
|
|
3628
3628
|
const query = reactQuery.useQuery({
|
|
3629
|
-
queryKey: [`idpicker`, { searchText, limit, page }],
|
|
3629
|
+
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
3630
3630
|
queryFn: async () => {
|
|
3631
3631
|
const data = await getTableData({
|
|
3632
3632
|
serverUrl,
|
|
3633
3633
|
searching: searchText ?? "",
|
|
3634
|
-
in_table:
|
|
3634
|
+
in_table: table,
|
|
3635
3635
|
limit: limit,
|
|
3636
3636
|
offset: page * 10,
|
|
3637
3637
|
});
|
|
@@ -3651,33 +3651,8 @@ const IdPicker = ({ column, isMultiple = false }) => {
|
|
|
3651
3651
|
enabled: (searchText ?? "")?.length > 0,
|
|
3652
3652
|
staleTime: 300000,
|
|
3653
3653
|
});
|
|
3654
|
-
reactQuery.useQuery({
|
|
3655
|
-
queryKey: [`idpicker`, { selectedIds }],
|
|
3656
|
-
queryFn: async () => {
|
|
3657
|
-
const data = await getTableData({
|
|
3658
|
-
serverUrl,
|
|
3659
|
-
in_table: in_table,
|
|
3660
|
-
limit: 1,
|
|
3661
|
-
where: [{ id: column_ref, value: watchId }],
|
|
3662
|
-
});
|
|
3663
|
-
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
3664
|
-
return [
|
|
3665
|
-
item[column_ref],
|
|
3666
|
-
{
|
|
3667
|
-
...item,
|
|
3668
|
-
},
|
|
3669
|
-
];
|
|
3670
|
-
}));
|
|
3671
|
-
setIdMap((state) => {
|
|
3672
|
-
return { ...state, ...newMap };
|
|
3673
|
-
});
|
|
3674
|
-
return data;
|
|
3675
|
-
},
|
|
3676
|
-
enabled: (selectedIds ?? []).length > 0,
|
|
3677
|
-
staleTime: 300000,
|
|
3678
|
-
});
|
|
3679
3654
|
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
3680
|
-
const dataList =
|
|
3655
|
+
const dataList = data?.data ?? [];
|
|
3681
3656
|
const count = data?.count ?? 0;
|
|
3682
3657
|
const isDirty = (searchText?.length ?? 0) > 0;
|
|
3683
3658
|
const onSearchChange = async (event) => {
|
|
@@ -3753,32 +3728,16 @@ const DataListItem = React__namespace.forwardRef(function DataListItem(props, re
|
|
|
3753
3728
|
return (jsxRuntime.jsxs(react.DataList.Item, { ref: ref, ...rest, children: [jsxRuntime.jsxs(react.DataList.ItemLabel, { flex: grow ? "1" : undefined, children: [label, info && jsxRuntime.jsx(InfoTip, { children: info })] }), jsxRuntime.jsx(react.DataList.ItemValue, { flex: grow ? "1" : undefined, children: value }), children] }));
|
|
3754
3729
|
});
|
|
3755
3730
|
|
|
3756
|
-
const IdViewer = ({ value, column }) => {
|
|
3757
|
-
const { schema,
|
|
3731
|
+
const IdViewer = ({ value, column, dataListItemProps, }) => {
|
|
3732
|
+
const { schema, idMap } = useSchemaContext();
|
|
3758
3733
|
if (schema.properties == undefined) {
|
|
3759
3734
|
throw new Error("schema properties when using DatePicker");
|
|
3760
3735
|
}
|
|
3761
3736
|
const { title, foreign_key } = schema.properties[column];
|
|
3762
3737
|
if (foreign_key === undefined) {
|
|
3763
|
-
throw new Error(
|
|
3738
|
+
throw new Error("foreign_key when variant is id-picker");
|
|
3764
3739
|
}
|
|
3765
|
-
const {
|
|
3766
|
-
const query = reactQuery.useQuery({
|
|
3767
|
-
queryKey: [`idpicker`, table, value],
|
|
3768
|
-
queryFn: async () => {
|
|
3769
|
-
return await getTableData({
|
|
3770
|
-
serverUrl,
|
|
3771
|
-
in_table: foreginKeyColumn ?? '',
|
|
3772
|
-
where: [
|
|
3773
|
-
{
|
|
3774
|
-
id: column,
|
|
3775
|
-
value: value,
|
|
3776
|
-
},
|
|
3777
|
-
],
|
|
3778
|
-
});
|
|
3779
|
-
},
|
|
3780
|
-
staleTime: 10000,
|
|
3781
|
-
});
|
|
3740
|
+
const { display_column } = foreign_key;
|
|
3782
3741
|
const getDataListProps = (value) => {
|
|
3783
3742
|
if (value == undefined || value.length <= 0) {
|
|
3784
3743
|
return {
|
|
@@ -3790,7 +3749,10 @@ const IdViewer = ({ value, column }) => {
|
|
|
3790
3749
|
value: value,
|
|
3791
3750
|
};
|
|
3792
3751
|
};
|
|
3793
|
-
|
|
3752
|
+
if (value === undefined) {
|
|
3753
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "undefined" });
|
|
3754
|
+
}
|
|
3755
|
+
return (jsxRuntime.jsx(DataListItem, { label: `${title ?? snakeToLabel(column)}`, ...getDataListProps(idMap[value][display_column]), ...dataListItemProps }));
|
|
3794
3756
|
};
|
|
3795
3757
|
|
|
3796
3758
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
|
@@ -3948,156 +3910,71 @@ const DatePicker = ({ column }) => {
|
|
|
3948
3910
|
} })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: fieldRequired ?? "The field is requried" }))] }));
|
|
3949
3911
|
};
|
|
3950
3912
|
|
|
3951
|
-
|
|
3952
|
-
|
|
3913
|
+
function filterArray(array, searchTerm) {
|
|
3914
|
+
// Convert the search term to lower case for case-insensitive comparison
|
|
3915
|
+
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
|
3916
|
+
// Use the filter method to return an array of matching items
|
|
3917
|
+
return array.filter((item) => {
|
|
3918
|
+
// Convert each item to a string and check if it includes the search term
|
|
3919
|
+
return item.toString().toLowerCase().includes(lowerCaseSearchTerm);
|
|
3920
|
+
});
|
|
3921
|
+
}
|
|
3922
|
+
|
|
3923
|
+
const EnumPicker = ({ column, isMultiple = false }) => {
|
|
3924
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
3953
3925
|
const { schema, displayText } = useSchemaContext();
|
|
3954
|
-
const {
|
|
3926
|
+
const { fieldRequired, total, showing, typeToSearch } = displayText;
|
|
3955
3927
|
const { required } = schema;
|
|
3956
3928
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
3957
|
-
const entries = Object.entries(getValues(column) ?? {});
|
|
3958
|
-
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
3959
|
-
const [newKey, setNewKey] = React.useState();
|
|
3960
|
-
const [newValue, setNewValue] = React.useState();
|
|
3961
3929
|
if (schema.properties == undefined) {
|
|
3962
3930
|
throw new Error("schema properties when using DatePicker");
|
|
3963
3931
|
}
|
|
3964
|
-
const { gridColumn, gridRow, title } = schema.properties[column];
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
const hasContent = label || description || icon;
|
|
4011
|
-
const ContentWrapper = indicator ? react.RadioCard.ItemContent : React__namespace.Fragment;
|
|
4012
|
-
return (jsxRuntime.jsxs(react.RadioCard.Item, { ...rest, children: [jsxRuntime.jsx(react.RadioCard.ItemHiddenInput, { ref: ref, ...inputProps }), jsxRuntime.jsxs(react.RadioCard.ItemControl, { children: [indicatorPlacement === "start" && indicator, hasContent && (jsxRuntime.jsxs(ContentWrapper, { children: [icon, label && jsxRuntime.jsx(react.RadioCard.ItemText, { children: label }), description && (jsxRuntime.jsx(react.RadioCard.ItemDescription, { children: description })), indicatorPlacement === "inside" && indicator] })), indicatorPlacement === "end" && indicator] }), addon && jsxRuntime.jsx(react.RadioCard.ItemAddon, { children: addon })] }));
|
|
4013
|
-
});
|
|
4014
|
-
const RadioCardRoot = react.RadioCard.Root;
|
|
4015
|
-
react.RadioCard.Label;
|
|
4016
|
-
react.RadioCard.ItemIndicator;
|
|
4017
|
-
|
|
4018
|
-
const TagPicker = ({ column }) => {
|
|
4019
|
-
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4020
|
-
const { schema, serverUrl } = useSchemaContext();
|
|
4021
|
-
if (schema.properties == undefined) {
|
|
4022
|
-
throw new Error("schema properties undefined when using DatePicker");
|
|
4023
|
-
}
|
|
4024
|
-
const { gridColumn, gridRow, in_table, object_id_column } = schema.properties[column];
|
|
4025
|
-
if (in_table === undefined) {
|
|
4026
|
-
throw new Error("in_table is undefined when using TagPicker");
|
|
4027
|
-
}
|
|
4028
|
-
if (object_id_column === undefined) {
|
|
4029
|
-
throw new Error("object_id_column is undefined when using TagPicker");
|
|
4030
|
-
}
|
|
4031
|
-
const query = reactQuery.useQuery({
|
|
4032
|
-
queryKey: [`tagpicker`, in_table],
|
|
4033
|
-
queryFn: async () => {
|
|
4034
|
-
return await getTableData({
|
|
4035
|
-
serverUrl,
|
|
4036
|
-
in_table: "tables_tags_view",
|
|
4037
|
-
where: [
|
|
4038
|
-
{
|
|
4039
|
-
id: "table_name",
|
|
4040
|
-
value: [in_table],
|
|
4041
|
-
},
|
|
4042
|
-
],
|
|
4043
|
-
limit: 100,
|
|
4044
|
-
});
|
|
4045
|
-
},
|
|
4046
|
-
staleTime: 10000,
|
|
4047
|
-
});
|
|
4048
|
-
const object_id = watch(object_id_column);
|
|
4049
|
-
const existingTagsQuery = reactQuery.useQuery({
|
|
4050
|
-
queryKey: [`existing`, in_table, object_id_column, object_id],
|
|
4051
|
-
queryFn: async () => {
|
|
4052
|
-
return await getTableData({
|
|
4053
|
-
serverUrl,
|
|
4054
|
-
in_table: in_table,
|
|
4055
|
-
where: [
|
|
4056
|
-
{
|
|
4057
|
-
id: object_id_column,
|
|
4058
|
-
value: object_id[0],
|
|
4059
|
-
},
|
|
4060
|
-
],
|
|
4061
|
-
limit: 100,
|
|
4062
|
-
});
|
|
4063
|
-
},
|
|
4064
|
-
enabled: object_id != undefined,
|
|
4065
|
-
staleTime: 10000,
|
|
4066
|
-
});
|
|
4067
|
-
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4068
|
-
const dataList = data?.data ?? [];
|
|
4069
|
-
const existingTagList = existingTagsQuery.data?.data ?? [];
|
|
4070
|
-
if (!!object_id === false) {
|
|
4071
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
4072
|
-
}
|
|
4073
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: 4, gridColumn,
|
|
4074
|
-
gridRow, children: [isFetching && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isFetching" }), isLoading && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isLoading" }), isPending && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isPending" }), isError && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isError" }), dataList.map(({ parent_tag_name, all_tags, is_mutually_exclusive }) => {
|
|
4075
|
-
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: 2, children: [jsxRuntime.jsx(react.Text, { children: parent_tag_name }), is_mutually_exclusive && (jsxRuntime.jsx(RadioCardRoot, { defaultValue: "next", variant: "surface", onValueChange: (tagIds) => {
|
|
4076
|
-
const existedTags = Object.values(all_tags)
|
|
4077
|
-
.filter(({ id }) => {
|
|
4078
|
-
return existingTagList.some(({ tag_id }) => tag_id === id);
|
|
4079
|
-
})
|
|
4080
|
-
.map(({ id }) => {
|
|
4081
|
-
return id;
|
|
4082
|
-
});
|
|
4083
|
-
setValue(`${column}.${parent_tag_name}.current`, [
|
|
4084
|
-
tagIds.value,
|
|
4085
|
-
]);
|
|
4086
|
-
setValue(`${column}.${parent_tag_name}.old`, existedTags);
|
|
4087
|
-
}, children: jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 2, children: Object.entries(all_tags).map(([tagName, { id }]) => {
|
|
4088
|
-
if (existingTagList.some(({ tag_id }) => tag_id === id)) {
|
|
4089
|
-
return (jsxRuntime.jsx(RadioCardItem, { label: tagName, value: id, flex: "0 0 0%", disabled: true }, `${tagName}-${id}`));
|
|
4090
|
-
}
|
|
4091
|
-
return (jsxRuntime.jsx(RadioCardItem, { label: tagName, value: id, flex: "0 0 0%", colorPalette: "blue" }, `${tagName}-${id}`));
|
|
4092
|
-
}) }) })), !is_mutually_exclusive && (jsxRuntime.jsx(react.CheckboxGroup, { onValueChange: (tagIds) => {
|
|
4093
|
-
setValue(`${column}.${parent_tag_name}.current`, tagIds);
|
|
4094
|
-
}, children: jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 2, children: Object.entries(all_tags).map(([tagName, { id }]) => {
|
|
4095
|
-
if (existingTagList.some(({ tag_id }) => tag_id === id)) {
|
|
4096
|
-
return (jsxRuntime.jsx(CheckboxCard, { label: tagName, value: id, flex: "0 0 0%", disabled: true, colorPalette: "blue" }, `${tagName}-${id}`));
|
|
4097
|
-
}
|
|
4098
|
-
return (jsxRuntime.jsx(CheckboxCard, { label: tagName, value: id, flex: "0 0 0%" }, `${tagName}-${id}`));
|
|
4099
|
-
}) }) }))] }, `tag-${parent_tag_name}`));
|
|
4100
|
-
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
3932
|
+
const { gridColumn, gridRow, title, renderDisplay } = schema.properties[column];
|
|
3933
|
+
const [searchText, setSearchText] = React.useState();
|
|
3934
|
+
const [limit, setLimit] = React.useState(10);
|
|
3935
|
+
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
3936
|
+
const ref = React.useRef(null);
|
|
3937
|
+
const watchEnum = watch(column);
|
|
3938
|
+
const watchEnums = (watch(column) ?? []);
|
|
3939
|
+
const properties = (schema.properties[column] ?? {});
|
|
3940
|
+
const dataList = properties.enum ?? [];
|
|
3941
|
+
const count = properties.enum?.length ?? 0;
|
|
3942
|
+
const isDirty = (searchText?.length ?? 0) > 0;
|
|
3943
|
+
const onSearchChange = async (event) => {
|
|
3944
|
+
setSearchText(event.target.value);
|
|
3945
|
+
setLimit(10);
|
|
3946
|
+
};
|
|
3947
|
+
return (jsxRuntime.jsxs(Field, { label: `${title ?? snakeToLabel(column)}`, required: isRequired, alignItems: "stretch", gridColumn,
|
|
3948
|
+
gridRow, children: [isMultiple && (jsxRuntime.jsxs(react.Flex, { flexFlow: "wrap", gap: 1, children: [watchEnums.map((enumValue) => {
|
|
3949
|
+
const item = enumValue;
|
|
3950
|
+
if (item === undefined) {
|
|
3951
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: "undefined" });
|
|
3952
|
+
}
|
|
3953
|
+
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
3954
|
+
setSelectedEnums((state) => state.filter((id) => id != item));
|
|
3955
|
+
setValue(column, watchEnums.filter((id) => id != item));
|
|
3956
|
+
}, children: !!renderDisplay === true ? renderDisplay(item) : item }));
|
|
3957
|
+
}), jsxRuntime.jsx(Tag, { cursor: "pointer", onClick: () => {
|
|
3958
|
+
setOpenSearchResult(true);
|
|
3959
|
+
}, children: "Add" })] })), !isMultiple && (jsxRuntime.jsx(Button, { variant: "outline", onClick: () => {
|
|
3960
|
+
setOpenSearchResult(true);
|
|
3961
|
+
}, children: watchEnum })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: typeToSearch ?? "Type to search", onChange: (event) => {
|
|
3962
|
+
onSearchChange(event);
|
|
3963
|
+
setOpenSearchResult(true);
|
|
3964
|
+
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), jsxRuntime.jsx(react.Text, { children: `${total ?? "Total"}: ${count}, ${showing ?? "Showing"} ${limit}` }), jsxRuntime.jsxs(react.Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsxRuntime.jsx(react.Flex, { flexFlow: "column wrap", children: filterArray(dataList, searchText ?? "").map((item) => {
|
|
3965
|
+
const selected = isMultiple
|
|
3966
|
+
? watchEnums.some((enumValue) => item === enumValue)
|
|
3967
|
+
: watchEnum == item;
|
|
3968
|
+
return (jsxRuntime.jsx(react.Box, { cursor: "pointer", onClick: () => {
|
|
3969
|
+
if (!isMultiple) {
|
|
3970
|
+
setOpenSearchResult(false);
|
|
3971
|
+
setValue(column, item);
|
|
3972
|
+
return;
|
|
3973
|
+
}
|
|
3974
|
+
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
3975
|
+
setValue(column, [...newSet]);
|
|
3976
|
+
}, ...(selected ? { color: "gray.400/50" } : {}), children: !!renderDisplay === true ? renderDisplay(item) : item }, `${column}-${item}`));
|
|
3977
|
+
}) }), isDirty && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [dataList.length <= 0 && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "Empty Search Result" }), " "] }))] })] }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: fieldRequired ?? "The field is requried" }))] }));
|
|
4101
3978
|
};
|
|
4102
3979
|
|
|
4103
3980
|
function isEnteringWindow(_ref) {
|
|
@@ -4475,71 +4352,156 @@ const FilePicker = ({ column }) => {
|
|
|
4475
4352
|
}) }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: fieldRequired ?? "The field is requried" }))] }));
|
|
4476
4353
|
};
|
|
4477
4354
|
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
|
4481
|
-
// Use the filter method to return an array of matching items
|
|
4482
|
-
return array.filter((item) => {
|
|
4483
|
-
// Convert each item to a string and check if it includes the search term
|
|
4484
|
-
return item.toString().toLowerCase().includes(lowerCaseSearchTerm);
|
|
4485
|
-
});
|
|
4486
|
-
}
|
|
4487
|
-
|
|
4488
|
-
const EnumPicker = ({ column, isMultiple = false }) => {
|
|
4489
|
-
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4355
|
+
const ObjectInput = ({ column }) => {
|
|
4356
|
+
const { formState: { errors }, setValue, getValues, } = reactHookForm.useFormContext();
|
|
4490
4357
|
const { schema, displayText } = useSchemaContext();
|
|
4491
|
-
const {
|
|
4358
|
+
const { addNew, fieldRequired, save } = displayText;
|
|
4492
4359
|
const { required } = schema;
|
|
4493
4360
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4361
|
+
const entries = Object.entries(getValues(column) ?? {});
|
|
4362
|
+
const [showNewEntries, setShowNewEntries] = React.useState(false);
|
|
4363
|
+
const [newKey, setNewKey] = React.useState();
|
|
4364
|
+
const [newValue, setNewValue] = React.useState();
|
|
4494
4365
|
if (schema.properties == undefined) {
|
|
4495
4366
|
throw new Error("schema properties when using DatePicker");
|
|
4496
4367
|
}
|
|
4497
|
-
const { gridColumn, gridRow, title
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4368
|
+
const { gridColumn, gridRow, title } = schema.properties[column];
|
|
4369
|
+
return (jsxRuntime.jsxs(Field, { label: `${title ?? snakeToLabel(column)}`, required: isRequired, alignItems: "stretch", gridColumn, gridRow, children: [entries.map(([key, value]) => {
|
|
4370
|
+
return (jsxRuntime.jsxs(react.Grid, { templateColumns: "1fr 1fr auto", gap: 1, children: [jsxRuntime.jsx(react.Input, { value: key, onChange: (e) => {
|
|
4371
|
+
const filtered = entries.filter(([target]) => {
|
|
4372
|
+
return target !== key;
|
|
4373
|
+
});
|
|
4374
|
+
setValue(column, Object.fromEntries([...filtered, [e.target.value, value]]));
|
|
4375
|
+
}, autoComplete: "off" }), jsxRuntime.jsx(react.Input, { value: value, onChange: (e) => {
|
|
4376
|
+
setValue(column, {
|
|
4377
|
+
...getValues(column),
|
|
4378
|
+
[key]: e.target.value,
|
|
4379
|
+
});
|
|
4380
|
+
}, autoComplete: "off" }), jsxRuntime.jsx(react.IconButton, { variant: "ghost", onClick: () => {
|
|
4381
|
+
const filtered = entries.filter(([target]) => {
|
|
4382
|
+
return target !== key;
|
|
4383
|
+
});
|
|
4384
|
+
setValue(column, Object.fromEntries([...filtered]));
|
|
4385
|
+
}, children: jsxRuntime.jsx(cg.CgClose, {}) })] }));
|
|
4386
|
+
}), 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) => {
|
|
4387
|
+
setNewKey(e.target.value);
|
|
4388
|
+
}, autoComplete: "off" }), jsxRuntime.jsx(react.Input, { value: newValue, onChange: (e) => {
|
|
4389
|
+
setNewValue(e.target.value);
|
|
4390
|
+
}, autoComplete: "off" })] }) }), jsxRuntime.jsxs(react.Card.Footer, { justifyContent: "flex-end", children: [jsxRuntime.jsx(react.IconButton, { variant: "subtle", onClick: () => {
|
|
4391
|
+
setShowNewEntries(false);
|
|
4392
|
+
setNewKey(undefined);
|
|
4393
|
+
setNewValue(undefined);
|
|
4394
|
+
}, children: jsxRuntime.jsx(cg.CgClose, {}) }), jsxRuntime.jsx(Button, { onClick: () => {
|
|
4395
|
+
if (!!newKey === false) {
|
|
4396
|
+
setShowNewEntries(false);
|
|
4397
|
+
setNewKey(undefined);
|
|
4398
|
+
setNewValue(undefined);
|
|
4399
|
+
return;
|
|
4400
|
+
}
|
|
4401
|
+
setValue(column, Object.fromEntries([...entries, [newKey, newValue]]));
|
|
4402
|
+
setShowNewEntries(false);
|
|
4403
|
+
setNewKey(undefined);
|
|
4404
|
+
setNewValue(undefined);
|
|
4405
|
+
}, children: save ?? "Save" })] })] }) }), jsxRuntime.jsx(Button, { onClick: () => {
|
|
4406
|
+
setShowNewEntries(true);
|
|
4407
|
+
setNewKey(undefined);
|
|
4408
|
+
setNewValue(undefined);
|
|
4409
|
+
}, children: addNew ?? "Add New" }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: fieldRequired ?? "The field is requried" }))] }));
|
|
4410
|
+
};
|
|
4411
|
+
|
|
4412
|
+
const RadioCardItem = React__namespace.forwardRef(function RadioCardItem(props, ref) {
|
|
4413
|
+
const { inputProps, label, description, addon, icon, indicator = jsxRuntime.jsx(react.RadioCard.ItemIndicator, {}), indicatorPlacement = "end", ...rest } = props;
|
|
4414
|
+
const hasContent = label || description || icon;
|
|
4415
|
+
const ContentWrapper = indicator ? react.RadioCard.ItemContent : React__namespace.Fragment;
|
|
4416
|
+
return (jsxRuntime.jsxs(react.RadioCard.Item, { ...rest, children: [jsxRuntime.jsx(react.RadioCard.ItemHiddenInput, { ref: ref, ...inputProps }), jsxRuntime.jsxs(react.RadioCard.ItemControl, { children: [indicatorPlacement === "start" && indicator, hasContent && (jsxRuntime.jsxs(ContentWrapper, { children: [icon, label && jsxRuntime.jsx(react.RadioCard.ItemText, { children: label }), description && (jsxRuntime.jsx(react.RadioCard.ItemDescription, { children: description })), indicatorPlacement === "inside" && indicator] })), indicatorPlacement === "end" && indicator] }), addon && jsxRuntime.jsx(react.RadioCard.ItemAddon, { children: addon })] }));
|
|
4417
|
+
});
|
|
4418
|
+
const RadioCardRoot = react.RadioCard.Root;
|
|
4419
|
+
react.RadioCard.Label;
|
|
4420
|
+
react.RadioCard.ItemIndicator;
|
|
4421
|
+
|
|
4422
|
+
const TagPicker = ({ column }) => {
|
|
4423
|
+
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4424
|
+
const { schema, serverUrl } = useSchemaContext();
|
|
4425
|
+
if (schema.properties == undefined) {
|
|
4426
|
+
throw new Error("schema properties undefined when using DatePicker");
|
|
4427
|
+
}
|
|
4428
|
+
const { gridColumn, gridRow, in_table, object_id_column } = schema.properties[column];
|
|
4429
|
+
if (in_table === undefined) {
|
|
4430
|
+
throw new Error("in_table is undefined when using TagPicker");
|
|
4431
|
+
}
|
|
4432
|
+
if (object_id_column === undefined) {
|
|
4433
|
+
throw new Error("object_id_column is undefined when using TagPicker");
|
|
4434
|
+
}
|
|
4435
|
+
const query = reactQuery.useQuery({
|
|
4436
|
+
queryKey: [`tagpicker`, in_table],
|
|
4437
|
+
queryFn: async () => {
|
|
4438
|
+
return await getTableData({
|
|
4439
|
+
serverUrl,
|
|
4440
|
+
in_table: "tables_tags_view",
|
|
4441
|
+
where: [
|
|
4442
|
+
{
|
|
4443
|
+
id: "table_name",
|
|
4444
|
+
value: [in_table],
|
|
4445
|
+
},
|
|
4446
|
+
],
|
|
4447
|
+
limit: 100,
|
|
4448
|
+
});
|
|
4449
|
+
},
|
|
4450
|
+
staleTime: 10000,
|
|
4451
|
+
});
|
|
4452
|
+
const object_id = watch(object_id_column);
|
|
4453
|
+
const existingTagsQuery = reactQuery.useQuery({
|
|
4454
|
+
queryKey: [`existing`, in_table, object_id_column, object_id],
|
|
4455
|
+
queryFn: async () => {
|
|
4456
|
+
return await getTableData({
|
|
4457
|
+
serverUrl,
|
|
4458
|
+
in_table: in_table,
|
|
4459
|
+
where: [
|
|
4460
|
+
{
|
|
4461
|
+
id: object_id_column,
|
|
4462
|
+
value: object_id[0],
|
|
4463
|
+
},
|
|
4464
|
+
],
|
|
4465
|
+
limit: 100,
|
|
4466
|
+
});
|
|
4467
|
+
},
|
|
4468
|
+
enabled: object_id != undefined,
|
|
4469
|
+
staleTime: 10000,
|
|
4470
|
+
});
|
|
4471
|
+
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
4472
|
+
const dataList = data?.data ?? [];
|
|
4473
|
+
const existingTagList = existingTagsQuery.data?.data ?? [];
|
|
4474
|
+
if (!!object_id === false) {
|
|
4475
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
4476
|
+
}
|
|
4477
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: 4, gridColumn,
|
|
4478
|
+
gridRow, children: [isFetching && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isFetching" }), isLoading && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isLoading" }), isPending && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isPending" }), isError && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "isError" }), dataList.map(({ parent_tag_name, all_tags, is_mutually_exclusive }) => {
|
|
4479
|
+
return (jsxRuntime.jsxs(react.Flex, { flexFlow: "column", gap: 2, children: [jsxRuntime.jsx(react.Text, { children: parent_tag_name }), is_mutually_exclusive && (jsxRuntime.jsx(RadioCardRoot, { defaultValue: "next", variant: "surface", onValueChange: (tagIds) => {
|
|
4480
|
+
const existedTags = Object.values(all_tags)
|
|
4481
|
+
.filter(({ id }) => {
|
|
4482
|
+
return existingTagList.some(({ tag_id }) => tag_id === id);
|
|
4483
|
+
})
|
|
4484
|
+
.map(({ id }) => {
|
|
4485
|
+
return id;
|
|
4486
|
+
});
|
|
4487
|
+
setValue(`${column}.${parent_tag_name}.current`, [
|
|
4488
|
+
tagIds.value,
|
|
4489
|
+
]);
|
|
4490
|
+
setValue(`${column}.${parent_tag_name}.old`, existedTags);
|
|
4491
|
+
}, children: jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 2, children: Object.entries(all_tags).map(([tagName, { id }]) => {
|
|
4492
|
+
if (existingTagList.some(({ tag_id }) => tag_id === id)) {
|
|
4493
|
+
return (jsxRuntime.jsx(RadioCardItem, { label: tagName, value: id, flex: "0 0 0%", disabled: true }, `${tagName}-${id}`));
|
|
4494
|
+
}
|
|
4495
|
+
return (jsxRuntime.jsx(RadioCardItem, { label: tagName, value: id, flex: "0 0 0%", colorPalette: "blue" }, `${tagName}-${id}`));
|
|
4496
|
+
}) }) })), !is_mutually_exclusive && (jsxRuntime.jsx(react.CheckboxGroup, { onValueChange: (tagIds) => {
|
|
4497
|
+
setValue(`${column}.${parent_tag_name}.current`, tagIds);
|
|
4498
|
+
}, children: jsxRuntime.jsx(react.Flex, { flexFlow: "wrap", gap: 2, children: Object.entries(all_tags).map(([tagName, { id }]) => {
|
|
4499
|
+
if (existingTagList.some(({ tag_id }) => tag_id === id)) {
|
|
4500
|
+
return (jsxRuntime.jsx(CheckboxCard, { label: tagName, value: id, flex: "0 0 0%", disabled: true, colorPalette: "blue" }, `${tagName}-${id}`));
|
|
4501
|
+
}
|
|
4502
|
+
return (jsxRuntime.jsx(CheckboxCard, { label: tagName, value: id, flex: "0 0 0%" }, `${tagName}-${id}`));
|
|
4503
|
+
}) }) }))] }, `tag-${parent_tag_name}`));
|
|
4504
|
+
}), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: (errors[`${column}`]?.message ?? "No error message") }))] }));
|
|
4543
4505
|
};
|
|
4544
4506
|
|
|
4545
4507
|
const idPickerSanityCheck = (column, foreign_key) => {
|
|
@@ -4558,7 +4520,7 @@ const idPickerSanityCheck = (column, foreign_key) => {
|
|
|
4558
4520
|
}
|
|
4559
4521
|
};
|
|
4560
4522
|
const FormInternal = () => {
|
|
4561
|
-
const { schema, serverUrl, displayText, order, ignore, onSubmit, rowNumber } = useSchemaContext();
|
|
4523
|
+
const { schema, serverUrl, displayText, order, ignore, onSubmit, rowNumber, idMap, } = useSchemaContext();
|
|
4562
4524
|
const { title, submit, empty, cancel, submitSuccess, submitAgain, confirm } = displayText;
|
|
4563
4525
|
const methods = reactHookForm.useFormContext();
|
|
4564
4526
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
@@ -4665,8 +4627,7 @@ const FormInternal = () => {
|
|
|
4665
4627
|
if (variant === "id-picker") {
|
|
4666
4628
|
idPickerSanityCheck(column, foreign_key);
|
|
4667
4629
|
return (jsxRuntime.jsx(IdViewer, { value: (validatedData ?? {})[column], column,
|
|
4668
|
-
gridColumn,
|
|
4669
|
-
gridRow }, `form-${key}`));
|
|
4630
|
+
dataListItemProps: { gridColumn, gridRow } }, `form-${key}`));
|
|
4670
4631
|
}
|
|
4671
4632
|
if (variant === "date-picker") {
|
|
4672
4633
|
const value = (validatedData ?? {})[column];
|
|
@@ -4704,6 +4665,22 @@ const FormInternal = () => {
|
|
|
4704
4665
|
});
|
|
4705
4666
|
return (jsxRuntime.jsx(DataListItem, { gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 4", label: `${snakeToLabel(column)}`, ...getDataListProps(JSON.stringify(fileNames)) }, `form-${key}`));
|
|
4706
4667
|
}
|
|
4668
|
+
if (variant === "id-picker") {
|
|
4669
|
+
const value = (validatedData ?? {})[column];
|
|
4670
|
+
if (schema.properties == undefined) {
|
|
4671
|
+
throw new Error("schema properties when using DatePicker");
|
|
4672
|
+
}
|
|
4673
|
+
const { foreign_key } = schema.properties[column];
|
|
4674
|
+
if (foreign_key === undefined) {
|
|
4675
|
+
throw new Error("foreign_key when variant is id-picker");
|
|
4676
|
+
}
|
|
4677
|
+
const { display_column } = foreign_key;
|
|
4678
|
+
const mapped = value.map((item) => {
|
|
4679
|
+
return idMap[item][display_column];
|
|
4680
|
+
});
|
|
4681
|
+
return (jsxRuntime.jsxs(react.Grid, { flexFlow: "column", gridColumn,
|
|
4682
|
+
gridRow, children: [jsxRuntime.jsx(react.Text, { children: snakeToLabel(column) }), jsxRuntime.jsx(RecordDisplay, { object: mapped })] }, `form-${key}`));
|
|
4683
|
+
}
|
|
4707
4684
|
const objectString = JSON.stringify((validatedData ?? {})[column]);
|
|
4708
4685
|
return (jsxRuntime.jsx(DataListItem, { gridColumn: gridColumn ?? "span 4", gridRow: gridRow ?? "span 4", label: `${snakeToLabel(column)}`, ...getDataListProps(objectString) }, `form-${key}`));
|
|
4709
4686
|
}
|
|
@@ -4730,8 +4707,9 @@ const FormInternal = () => {
|
|
|
4730
4707
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
4731
4708
|
}
|
|
4732
4709
|
//@ts-expect-error TODO: add more fields to support form-creation
|
|
4733
|
-
const { type, variant,
|
|
4710
|
+
const { type, variant, foreign_key } = values;
|
|
4734
4711
|
if (type === "string") {
|
|
4712
|
+
// @ts-expect-error enum should exists
|
|
4735
4713
|
if ((values.enum ?? []).length > 0) {
|
|
4736
4714
|
return jsxRuntime.jsx(EnumPicker, { column: key }, `form-${key}`);
|
|
4737
4715
|
}
|
|
@@ -4777,6 +4755,7 @@ const FormInternal = () => {
|
|
|
4777
4755
|
const Form = ({ schema, serverUrl, order = [], ignore = [], onSubmit = undefined, preLoadedValues = {}, rowNumber = undefined, displayText = {}, }) => {
|
|
4778
4756
|
const queryClient = new reactQuery.QueryClient();
|
|
4779
4757
|
const methods = reactHookForm.useForm({ values: preLoadedValues });
|
|
4758
|
+
const [idMap, setIdMap] = React.useState({});
|
|
4780
4759
|
const { properties } = schema;
|
|
4781
4760
|
idListSanityCheck("order", order, properties);
|
|
4782
4761
|
idListSanityCheck("ignore", ignore, properties);
|
|
@@ -4790,6 +4769,8 @@ const Form = ({ schema, serverUrl, order = [], ignore = [], onSubmit = undefined
|
|
|
4790
4769
|
// @ts-expect-error TODO: find appropriate types
|
|
4791
4770
|
onSubmit,
|
|
4792
4771
|
rowNumber,
|
|
4772
|
+
idMap,
|
|
4773
|
+
setIdMap,
|
|
4793
4774
|
}, children: jsxRuntime.jsx(reactHookForm.FormProvider, { ...methods, children: jsxRuntime.jsx(FormInternal, {}) }) }) }));
|
|
4794
4775
|
};
|
|
4795
4776
|
|