@bsol-oss/react-datatable5 12.0.0-beta.84 → 12.0.0-beta.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +148 -203
- package/dist/index.mjs +151 -206
- package/package.json +6 -6
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -575,7 +575,7 @@ const PaginationItems = (props) => {
|
|
|
575
575
|
return page.type === "ellipsis" ? (jsxRuntime.jsx(PaginationEllipsis, { index: index, ...props }, index)) : (jsxRuntime.jsx(PaginationItem, { type: "page", value: page.value, ...props }, index));
|
|
576
576
|
}) }));
|
|
577
577
|
};
|
|
578
|
-
|
|
578
|
+
React__namespace.forwardRef(function PaginationPageText(props, ref) {
|
|
579
579
|
const { format = "compact", ...rest } = props;
|
|
580
580
|
const { page, totalPages, pageRange, count } = react.usePaginationContext();
|
|
581
581
|
const content = React__namespace.useMemo(() => {
|
|
@@ -4176,16 +4176,6 @@ const DateRangePicker = ({ column, schema, prefix, }) => {
|
|
|
4176
4176
|
}, monthsToDisplay: 2 })] }) })] }) }));
|
|
4177
4177
|
};
|
|
4178
4178
|
|
|
4179
|
-
function filterArray(array, searchTerm) {
|
|
4180
|
-
// Convert the search term to lower case for case-insensitive comparison
|
|
4181
|
-
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
|
4182
|
-
// Use the filter method to return an array of matching items
|
|
4183
|
-
return array.filter((item) => {
|
|
4184
|
-
// Convert each item to a string and check if it includes the search term
|
|
4185
|
-
return item.toString().toLowerCase().includes(lowerCaseSearchTerm);
|
|
4186
|
-
});
|
|
4187
|
-
}
|
|
4188
|
-
|
|
4189
4179
|
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
4190
4180
|
const { watch, formState: { errors }, setValue, } = reactHookForm.useFormContext();
|
|
4191
4181
|
const { enumPickerLabels } = useSchemaContext();
|
|
@@ -4193,89 +4183,74 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4193
4183
|
const { required, variant } = schema;
|
|
4194
4184
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4195
4185
|
const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
|
|
4196
|
-
const [searchText, setSearchText] = React.useState();
|
|
4197
|
-
const [limit, setLimit] = React.useState(10);
|
|
4198
|
-
const [openSearchResult, setOpenSearchResult] = React.useState();
|
|
4199
|
-
const ref = React.useRef(null);
|
|
4200
4186
|
const colLabel = formI18n.colLabel;
|
|
4201
4187
|
const watchEnum = watch(colLabel);
|
|
4202
4188
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4203
4189
|
const dataList = schema.enum ?? [];
|
|
4204
|
-
|
|
4205
|
-
const
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4190
|
+
// Current value for combobox (array format)
|
|
4191
|
+
const currentValue = isMultiple
|
|
4192
|
+
? watchEnums.filter((val) => val != null && val !== '')
|
|
4193
|
+
: watchEnum
|
|
4194
|
+
? [watchEnum]
|
|
4195
|
+
: [];
|
|
4196
|
+
// Transform enum data for combobox collection
|
|
4197
|
+
const comboboxItems = React.useMemo(() => {
|
|
4198
|
+
return dataList.map((item) => ({
|
|
4199
|
+
label: !!renderDisplay === true
|
|
4200
|
+
? String(renderDisplay(item))
|
|
4201
|
+
: formI18n.t(item),
|
|
4202
|
+
value: item,
|
|
4203
|
+
}));
|
|
4204
|
+
}, [dataList, renderDisplay, formI18n]);
|
|
4205
|
+
// Use filter hook for combobox
|
|
4206
|
+
const { contains } = react.useFilter({ sensitivity: 'base' });
|
|
4207
|
+
// Create collection for combobox
|
|
4208
|
+
const { collection, filter } = react.useListCollection({
|
|
4209
|
+
initialItems: comboboxItems,
|
|
4210
|
+
itemToString: (item) => item.label,
|
|
4211
|
+
itemToValue: (item) => item.value,
|
|
4212
|
+
filter: contains,
|
|
4213
|
+
});
|
|
4214
|
+
// Handle input value change (search)
|
|
4215
|
+
const handleInputValueChange = (details) => {
|
|
4216
|
+
filter(details.inputValue);
|
|
4217
|
+
};
|
|
4218
|
+
// Handle value change
|
|
4219
|
+
const handleValueChange = (details) => {
|
|
4220
|
+
if (isMultiple) {
|
|
4221
|
+
setValue(colLabel, details.value);
|
|
4222
|
+
}
|
|
4223
|
+
else {
|
|
4224
|
+
setValue(colLabel, details.value[0] || '');
|
|
4225
|
+
}
|
|
4209
4226
|
};
|
|
4210
4227
|
if (variant === 'radio') {
|
|
4211
4228
|
return (jsxRuntime.jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4212
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, {
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
}
|
|
4219
|
-
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4220
|
-
setValue(colLabel, [...newSet]);
|
|
4221
|
-
}, value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4229
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsxRuntime.jsx(react.RadioGroup.Root, { value: !isMultiple ? watchEnum : undefined, onValueChange: (details) => {
|
|
4230
|
+
if (!isMultiple) {
|
|
4231
|
+
setValue(colLabel, details.value);
|
|
4232
|
+
}
|
|
4233
|
+
}, children: jsxRuntime.jsx(react.HStack, { gap: "6", children: dataList.map((item) => {
|
|
4234
|
+
return (jsxRuntime.jsxs(react.RadioGroup.Item, { value: item, children: [jsxRuntime.jsx(react.RadioGroup.ItemHiddenInput, {}), jsxRuntime.jsx(react.RadioGroup.ItemIndicator, {}), jsxRuntime.jsx(react.RadioGroup.ItemText, { children: !!renderDisplay === true
|
|
4222
4235
|
? renderDisplay(item)
|
|
4223
4236
|
: formI18n.t(item) })] }, `${colLabel}-${item}`));
|
|
4224
4237
|
}) }) }) }));
|
|
4225
4238
|
}
|
|
4226
4239
|
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4227
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
}, justifyContent: 'start', children: !!watchEnum === false ? '' : formI18n.t(watchEnum ?? 'null') })), jsxRuntime.jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsxRuntime.jsx(PopoverTrigger, {}), jsxRuntime.jsx(PopoverContent, { portalled: false, children: jsxRuntime.jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: (event) => {
|
|
4242
|
-
onSearchChange(event);
|
|
4243
|
-
setOpenSearchResult(true);
|
|
4244
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${count}, ${enumPickerLabels?.showing ?? formI18n.t('showing')} ${limit}` })), jsxRuntime.jsxs(react.Grid, { overflow: 'auto', maxHeight: '20rem', children: [jsxRuntime.jsx(react.Flex, { flexFlow: 'column wrap', children: dataList
|
|
4245
|
-
.filter((item) => {
|
|
4246
|
-
const searchTerm = (searchText || '').toLowerCase();
|
|
4247
|
-
if (!searchTerm)
|
|
4248
|
-
return true;
|
|
4249
|
-
// Check if the original enum value contains the search text
|
|
4250
|
-
const enumValueMatch = item
|
|
4251
|
-
.toLowerCase()
|
|
4252
|
-
.includes(searchTerm);
|
|
4253
|
-
// Check if the display value (translation) contains the search text
|
|
4254
|
-
const displayValue = !!renderDisplay === true
|
|
4255
|
-
? renderDisplay(item)
|
|
4256
|
-
: formI18n.t(item);
|
|
4257
|
-
// Convert to string and check if it includes the search term
|
|
4258
|
-
const displayValueString = String(displayValue).toLowerCase();
|
|
4259
|
-
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4260
|
-
return enumValueMatch || displayValueMatch;
|
|
4261
|
-
})
|
|
4262
|
-
.map((item) => {
|
|
4263
|
-
const selected = isMultiple
|
|
4264
|
-
? watchEnums.some((enumValue) => item === enumValue)
|
|
4265
|
-
: watchEnum == item;
|
|
4266
|
-
return (jsxRuntime.jsx(react.Box, { cursor: 'pointer', onClick: () => {
|
|
4267
|
-
if (!isMultiple) {
|
|
4268
|
-
setOpenSearchResult(false);
|
|
4269
|
-
setValue(colLabel, item);
|
|
4270
|
-
return;
|
|
4271
|
-
}
|
|
4272
|
-
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4273
|
-
setValue(colLabel, [...newSet]);
|
|
4274
|
-
}, ...(selected ? { color: 'colorPalette.400/50' } : {}), children: !!renderDisplay === true
|
|
4275
|
-
? renderDisplay(item)
|
|
4276
|
-
: formI18n.t(item) }, `${colLabel}-${item}`));
|
|
4277
|
-
}) }), isDirty && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: dataList.length <= 0 && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4278
|
-
formI18n.t('empty_search_result') })) }))] })] }) })] })] }));
|
|
4240
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && currentValue.length > 0 && (jsxRuntime.jsx(react.Flex, { flexFlow: 'wrap', gap: 1, mb: 2, children: currentValue.map((enumValue) => {
|
|
4241
|
+
if (!enumValue) {
|
|
4242
|
+
return null;
|
|
4243
|
+
}
|
|
4244
|
+
return (jsxRuntime.jsx(Tag, { size: "lg", closable: true, onClick: () => {
|
|
4245
|
+
const newValue = currentValue.filter((val) => val !== enumValue);
|
|
4246
|
+
setValue(colLabel, newValue);
|
|
4247
|
+
}, children: !!renderDisplay === true
|
|
4248
|
+
? renderDisplay(enumValue)
|
|
4249
|
+
: formI18n.t(enumValue) }, enumValue));
|
|
4250
|
+
}) })), jsxRuntime.jsxs(react.Combobox.Root, { collection: collection, value: currentValue, onValueChange: handleValueChange, onInputValueChange: handleInputValueChange, multiple: isMultiple, closeOnSelect: !isMultiple, openOnClick: true, invalid: !!errors[colLabel], width: "100%", children: [jsxRuntime.jsxs(react.Combobox.Control, { children: [jsxRuntime.jsx(react.Combobox.Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search') }), jsxRuntime.jsxs(react.Combobox.IndicatorGroup, { children: [!isMultiple && currentValue.length > 0 && (jsxRuntime.jsx(react.Combobox.ClearTrigger, { onClick: () => {
|
|
4251
|
+
setValue(colLabel, '');
|
|
4252
|
+
} })), jsxRuntime.jsx(react.Combobox.Trigger, {})] })] }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Combobox.Positioner, { children: jsxRuntime.jsxs(react.Combobox.Content, { children: [showTotalAndLimit && (jsxRuntime.jsx(react.Text, { p: 2, fontSize: "sm", color: "fg.muted", children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${collection.items.length}` })), collection.items.length === 0 ? (jsxRuntime.jsx(react.Combobox.Empty, { children: enumPickerLabels?.emptySearchResult ??
|
|
4253
|
+
formI18n.t('empty_search_result') })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: collection.items.map((item, index) => (jsxRuntime.jsxs(react.Combobox.Item, { item: item, children: [jsxRuntime.jsx(react.Combobox.ItemText, { children: item.label }), jsxRuntime.jsx(react.Combobox.ItemIndicator, {})] }, item.value ?? `item-${index}`))) }))] }) }) })] })] }));
|
|
4279
4254
|
};
|
|
4280
4255
|
|
|
4281
4256
|
function isEnteringWindow(_ref) {
|
|
@@ -4667,9 +4642,7 @@ const MediaLibraryBrowser = ({ onFetchFiles, filterImageOnly = false, labels, en
|
|
|
4667
4642
|
: files;
|
|
4668
4643
|
const handleFileClick = (file) => {
|
|
4669
4644
|
if (multiple) {
|
|
4670
|
-
const currentSelection = Array.isArray(selectedFile)
|
|
4671
|
-
? selectedFile
|
|
4672
|
-
: [];
|
|
4645
|
+
const currentSelection = Array.isArray(selectedFile) ? selectedFile : [];
|
|
4673
4646
|
const isAlreadySelected = currentSelection.some((f) => f.id === file.id);
|
|
4674
4647
|
const newSelection = isAlreadySelected
|
|
4675
4648
|
? currentSelection.filter((f) => f.id !== file.id)
|
|
@@ -5036,15 +5009,6 @@ const FormMediaLibraryBrowser = ({ column, schema, prefix, }) => {
|
|
|
5036
5009
|
}) })] }));
|
|
5037
5010
|
};
|
|
5038
5011
|
|
|
5039
|
-
const ToggleTip = React__namespace.forwardRef(function ToggleTip(props, ref) {
|
|
5040
|
-
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
5041
|
-
return (jsxRuntime.jsxs(react.Popover.Root, { ...rest, positioning: { ...rest.positioning, gutter: 4 }, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: children }), jsxRuntime.jsx(react.Portal, { disabled: !portalled, container: portalRef, children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsxs(react.Popover.Content, { width: "auto", px: "2", py: "1", textStyle: "xs", rounded: "sm", ref: ref, children: [showArrow && (jsxRuntime.jsx(react.Popover.Arrow, { children: jsxRuntime.jsx(react.Popover.ArrowTip, {}) })), content] }) }) })] }));
|
|
5042
|
-
});
|
|
5043
|
-
const InfoTip = React__namespace.forwardRef(function InfoTip(props, ref) {
|
|
5044
|
-
const { children, ...rest } = props;
|
|
5045
|
-
return (jsxRuntime.jsx(ToggleTip, { content: children, ...rest, ref: ref, children: jsxRuntime.jsx(react.IconButton, { variant: "ghost", "aria-label": "info", size: "2xs", colorPalette: "colorPalette", children: jsxRuntime.jsx(hi.HiOutlineInformationCircle, {}) }) }));
|
|
5046
|
-
});
|
|
5047
|
-
|
|
5048
5012
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
5049
5013
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
5050
5014
|
throw new Error("The serverUrl is missing");
|
|
@@ -5081,10 +5045,8 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5081
5045
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5082
5046
|
const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
|
|
5083
5047
|
const [searchText, setSearchText] = React.useState('');
|
|
5084
|
-
const [
|
|
5085
|
-
const [
|
|
5086
|
-
const [page, setPage] = React.useState(0);
|
|
5087
|
-
const ref = React.useRef(null);
|
|
5048
|
+
const [debouncedSearchText, setDebouncedSearchText] = React.useState('');
|
|
5049
|
+
const [limit] = React.useState(50); // Increased limit for combobox
|
|
5088
5050
|
const colLabel = formI18n.colLabel;
|
|
5089
5051
|
const watchedValue = watch(colLabel);
|
|
5090
5052
|
const watchId = !isMultiple ? watchedValue : undefined;
|
|
@@ -5099,22 +5061,32 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5099
5061
|
: [];
|
|
5100
5062
|
// Use watched values if they exist (including empty string for single select),
|
|
5101
5063
|
// otherwise fall back to initial values from getValues()
|
|
5102
|
-
// This ensures the query can trigger on mount with initial values
|
|
5103
|
-
// For single: use watchId if it's not undefined/null, otherwise use initialId
|
|
5104
|
-
// For multiple: use watchIds if watchedValue is defined, otherwise use initialIds
|
|
5105
5064
|
const currentId = watchId !== undefined && watchId !== null ? watchId : initialId;
|
|
5106
5065
|
const currentIds = watchedValue !== undefined && watchedValue !== null && isMultiple
|
|
5107
5066
|
? watchIds
|
|
5108
5067
|
: initialIds;
|
|
5109
|
-
//
|
|
5068
|
+
// Current value for combobox (array format)
|
|
5069
|
+
const currentValue = isMultiple
|
|
5070
|
+
? currentIds.filter((id) => id != null && id !== '')
|
|
5071
|
+
: currentId
|
|
5072
|
+
? [currentId]
|
|
5073
|
+
: [];
|
|
5074
|
+
// Debounce search text to avoid too many API calls
|
|
5075
|
+
React.useEffect(() => {
|
|
5076
|
+
const timer = setTimeout(() => {
|
|
5077
|
+
setDebouncedSearchText(searchText);
|
|
5078
|
+
}, 300);
|
|
5079
|
+
return () => clearTimeout(timer);
|
|
5080
|
+
}, [searchText]);
|
|
5081
|
+
// Query for search results (async loading)
|
|
5110
5082
|
const query = reactQuery.useQuery({
|
|
5111
|
-
queryKey: [`idpicker`, { column, searchText, limit
|
|
5083
|
+
queryKey: [`idpicker`, { column, searchText: debouncedSearchText, limit }],
|
|
5112
5084
|
queryFn: async () => {
|
|
5113
5085
|
if (customQueryFn) {
|
|
5114
5086
|
const { data, idMap } = await customQueryFn({
|
|
5115
|
-
searching:
|
|
5087
|
+
searching: debouncedSearchText ?? '',
|
|
5116
5088
|
limit: limit,
|
|
5117
|
-
offset:
|
|
5089
|
+
offset: 0,
|
|
5118
5090
|
});
|
|
5119
5091
|
setIdMap((state) => {
|
|
5120
5092
|
return { ...state, ...idMap };
|
|
@@ -5123,10 +5095,10 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5123
5095
|
}
|
|
5124
5096
|
const data = await getTableData({
|
|
5125
5097
|
serverUrl,
|
|
5126
|
-
searching:
|
|
5098
|
+
searching: debouncedSearchText ?? '',
|
|
5127
5099
|
in_table: table,
|
|
5128
5100
|
limit: limit,
|
|
5129
|
-
offset:
|
|
5101
|
+
offset: 0,
|
|
5130
5102
|
});
|
|
5131
5103
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
5132
5104
|
return [
|
|
@@ -5141,12 +5113,12 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5141
5113
|
});
|
|
5142
5114
|
return data;
|
|
5143
5115
|
},
|
|
5144
|
-
enabled:
|
|
5116
|
+
enabled: true, // Always enabled for combobox
|
|
5145
5117
|
staleTime: 300000,
|
|
5146
5118
|
});
|
|
5147
5119
|
// Query for currently selected items (to display them properly)
|
|
5148
|
-
//
|
|
5149
|
-
|
|
5120
|
+
// This query is needed for side effects (populating idMap) even though the result isn't directly used
|
|
5121
|
+
reactQuery.useQuery({
|
|
5150
5122
|
queryKey: [
|
|
5151
5123
|
`idpicker-default`,
|
|
5152
5124
|
{
|
|
@@ -5156,11 +5128,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5156
5128
|
},
|
|
5157
5129
|
],
|
|
5158
5130
|
queryFn: async () => {
|
|
5159
|
-
// Use current values (which include initial) for the query
|
|
5160
5131
|
const queryId = currentId;
|
|
5161
5132
|
const queryIds = currentIds;
|
|
5162
5133
|
if (customQueryFn) {
|
|
5163
|
-
// For customQueryFn, pass where clause to fetch specific IDs
|
|
5164
5134
|
const { data, idMap } = await customQueryFn({
|
|
5165
5135
|
searching: '',
|
|
5166
5136
|
limit: isMultiple ? queryIds.length : 1,
|
|
@@ -5175,10 +5145,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5175
5145
|
if (!queryId && (!queryIds || queryIds.length === 0)) {
|
|
5176
5146
|
return { data: [] };
|
|
5177
5147
|
}
|
|
5178
|
-
const searchValue = isMultiple ? queryIds.join(',') : queryId;
|
|
5179
5148
|
const data = await getTableData({
|
|
5180
5149
|
serverUrl,
|
|
5181
|
-
searching:
|
|
5150
|
+
searching: '',
|
|
5182
5151
|
in_table: table,
|
|
5183
5152
|
where: [{ id: column_ref, value: isMultiple ? queryIds : queryId }],
|
|
5184
5153
|
limit: isMultiple ? queryIds.length : 1,
|
|
@@ -5201,101 +5170,77 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5201
5170
|
? Array.isArray(currentIds) && currentIds.length > 0
|
|
5202
5171
|
: !!currentId,
|
|
5203
5172
|
});
|
|
5204
|
-
// Effect to trigger initial data fetch when popover opens
|
|
5205
|
-
React.useEffect(() => {
|
|
5206
|
-
if (openSearchResult) {
|
|
5207
|
-
// Reset search text when opening the popover
|
|
5208
|
-
setSearchText('');
|
|
5209
|
-
// Reset page to first page
|
|
5210
|
-
setPage(0);
|
|
5211
|
-
// Fetch initial data
|
|
5212
|
-
query.refetch();
|
|
5213
|
-
}
|
|
5214
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5215
|
-
}, [openSearchResult]);
|
|
5216
|
-
const onSearchChange = async (event) => {
|
|
5217
|
-
setSearchText(event.target.value);
|
|
5218
|
-
setPage(0);
|
|
5219
|
-
query.refetch();
|
|
5220
|
-
};
|
|
5221
|
-
const handleLimitChange = (event) => {
|
|
5222
|
-
const newLimit = Number(event.target.value);
|
|
5223
|
-
setLimit(newLimit);
|
|
5224
|
-
// Reset to first page when changing limit
|
|
5225
|
-
setPage(0);
|
|
5226
|
-
// Trigger a new search with the updated limit
|
|
5227
|
-
query.refetch();
|
|
5228
|
-
};
|
|
5229
5173
|
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
5230
5174
|
const dataList = data?.data ?? [];
|
|
5231
|
-
|
|
5232
|
-
const
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5175
|
+
// Check if we're currently searching (user typed but debounce hasn't fired yet)
|
|
5176
|
+
const isSearching = searchText !== debouncedSearchText;
|
|
5177
|
+
// Transform data for combobox collection
|
|
5178
|
+
const comboboxItems = React.useMemo(() => {
|
|
5179
|
+
return dataList.map((item) => ({
|
|
5180
|
+
label: !!renderDisplay === true
|
|
5181
|
+
? String(renderDisplay(item))
|
|
5182
|
+
: String(item[display_column] ?? ''),
|
|
5183
|
+
value: String(item[column_ref]),
|
|
5184
|
+
raw: item,
|
|
5185
|
+
}));
|
|
5186
|
+
}, [dataList, display_column, column_ref, renderDisplay]);
|
|
5187
|
+
// Use filter hook for combobox
|
|
5188
|
+
const { contains } = react.useFilter({ sensitivity: 'base' });
|
|
5189
|
+
// Create collection for combobox
|
|
5190
|
+
const { collection, filter, set } = react.useListCollection({
|
|
5191
|
+
initialItems: comboboxItems,
|
|
5192
|
+
itemToString: (item) => item.label,
|
|
5193
|
+
itemToValue: (item) => item.value,
|
|
5194
|
+
filter: contains,
|
|
5195
|
+
});
|
|
5196
|
+
// Handle input value change (search)
|
|
5197
|
+
const handleInputValueChange = (details) => {
|
|
5198
|
+
setSearchText(details.inputValue);
|
|
5199
|
+
// Filter will be applied after data is fetched
|
|
5200
|
+
};
|
|
5201
|
+
// Handle value change
|
|
5202
|
+
const handleValueChange = (details) => {
|
|
5203
|
+
if (isMultiple) {
|
|
5204
|
+
setValue(colLabel, details.value);
|
|
5240
5205
|
}
|
|
5241
|
-
|
|
5242
|
-
|
|
5206
|
+
else {
|
|
5207
|
+
setValue(colLabel, details.value[0] || '');
|
|
5243
5208
|
}
|
|
5244
|
-
return record[display_column];
|
|
5245
5209
|
};
|
|
5210
|
+
// Update collection and filter when data changes
|
|
5211
|
+
React.useEffect(() => {
|
|
5212
|
+
if (dataList.length > 0 && comboboxItems.length > 0) {
|
|
5213
|
+
set(comboboxItems);
|
|
5214
|
+
// Apply filter to the collection using the immediate searchText for UI responsiveness
|
|
5215
|
+
if (searchText) {
|
|
5216
|
+
filter(searchText);
|
|
5217
|
+
}
|
|
5218
|
+
}
|
|
5219
|
+
// Only depend on dataList and searchText, not comboboxItems (which is derived from dataList)
|
|
5220
|
+
// set and filter are stable functions from useListCollection
|
|
5221
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5222
|
+
}, [dataList, searchText]);
|
|
5246
5223
|
return (jsxRuntime.jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
5247
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (jsxRuntime.
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
fontSize: '14px',
|
|
5268
|
-
}, 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) => {
|
|
5269
|
-
const selected = isMultiple
|
|
5270
|
-
? watchIds.some((id) => item[column_ref] === id)
|
|
5271
|
-
: watchId === item[column_ref];
|
|
5272
|
-
return (jsxRuntime.jsx(react.Box, { cursor: 'pointer', onClick: () => {
|
|
5273
|
-
if (!isMultiple) {
|
|
5274
|
-
setOpenSearchResult(false);
|
|
5275
|
-
setValue(colLabel, item[column_ref]);
|
|
5276
|
-
return;
|
|
5277
|
-
}
|
|
5278
|
-
// For multiple selection, don't add if already selected
|
|
5279
|
-
if (selected)
|
|
5280
|
-
return;
|
|
5281
|
-
const newSet = new Set([
|
|
5282
|
-
...(watchIds ?? []),
|
|
5283
|
-
item[column_ref],
|
|
5284
|
-
]);
|
|
5285
|
-
setValue(colLabel, [...newSet]);
|
|
5286
|
-
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
5287
|
-
? {
|
|
5288
|
-
color: 'colorPalette.400/50',
|
|
5289
|
-
fontWeight: 'bold',
|
|
5290
|
-
}
|
|
5291
|
-
: {}), children: !!renderDisplay === true
|
|
5292
|
-
? renderDisplay(item)
|
|
5293
|
-
: item[display_column] }, item[column_ref]));
|
|
5294
|
-
}) })) : (jsxRuntime.jsx(react.Text, { children: searchText
|
|
5295
|
-
? idPickerLabels?.emptySearchResult ??
|
|
5296
|
-
formI18n.t('empty_search_result')
|
|
5297
|
-
: idPickerLabels?.initialResults ??
|
|
5298
|
-
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, {})] }) })] }))] }) })] })] }));
|
|
5224
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && currentValue.length > 0 && (jsxRuntime.jsx(react.Flex, { flexFlow: 'wrap', gap: 1, mb: 2, children: currentValue.map((id) => {
|
|
5225
|
+
const item = idMap[id];
|
|
5226
|
+
if (item === undefined) {
|
|
5227
|
+
return (jsxRuntime.jsx(react.Text, { fontSize: "sm", children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
|
|
5228
|
+
}
|
|
5229
|
+
return (jsxRuntime.jsx(Tag, { closable: true, onClick: () => {
|
|
5230
|
+
const newValue = currentValue.filter((itemId) => itemId !== id);
|
|
5231
|
+
setValue(colLabel, newValue);
|
|
5232
|
+
}, children: !!renderDisplay === true
|
|
5233
|
+
? renderDisplay(item)
|
|
5234
|
+
: item[display_column] }, id));
|
|
5235
|
+
}) })), jsxRuntime.jsxs(react.Combobox.Root, { collection: collection, value: currentValue, onValueChange: handleValueChange, onInputValueChange: handleInputValueChange, multiple: isMultiple, closeOnSelect: !isMultiple, openOnClick: true, invalid: !!errors[colLabel], width: "100%", children: [jsxRuntime.jsxs(react.Combobox.Control, { children: [jsxRuntime.jsx(react.Combobox.Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search') }), jsxRuntime.jsxs(react.Combobox.IndicatorGroup, { children: [(isFetching || isLoading || isPending) && jsxRuntime.jsx(react.Spinner, { size: "xs" }), isError && (jsxRuntime.jsx(react.Icon, { color: "fg.error", children: jsxRuntime.jsx(bi.BiError, {}) })), !isMultiple && currentValue.length > 0 && (jsxRuntime.jsx(react.Combobox.ClearTrigger, { onClick: () => {
|
|
5236
|
+
setValue(colLabel, '');
|
|
5237
|
+
} })), jsxRuntime.jsx(react.Combobox.Trigger, {})] })] }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Combobox.Positioner, { children: jsxRuntime.jsx(react.Combobox.Content, { children: isError ? (jsxRuntime.jsx(react.Text, { p: 2, color: "fg.error", fontSize: "sm", children: formI18n.t('loading_failed') })) : isFetching || isLoading || isPending || isSearching ? (
|
|
5238
|
+
// Show skeleton items to prevent UI shift
|
|
5239
|
+
jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from({ length: 5 }).map((_, index) => (jsxRuntime.jsx(react.Flex, { p: 2, align: "center", gap: 2, children: jsxRuntime.jsx(react.Skeleton, { height: "20px", flex: "1" }) }, `skeleton-${index}`))) })) : collection.items.length === 0 ? (jsxRuntime.jsx(react.Combobox.Empty, { children: searchText
|
|
5240
|
+
? idPickerLabels?.emptySearchResult ??
|
|
5241
|
+
formI18n.t('empty_search_result')
|
|
5242
|
+
: idPickerLabels?.initialResults ??
|
|
5243
|
+
formI18n.t('initial_results') })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: collection.items.map((item, index) => (jsxRuntime.jsxs(react.Combobox.Item, { item: item, children: [jsxRuntime.jsx(react.Combobox.ItemText, { children: item.label }), jsxRuntime.jsx(react.Combobox.ItemIndicator, {})] }, item.value ?? `item-${index}`))) })) }) }) })] })] }));
|
|
5299
5244
|
};
|
|
5300
5245
|
|
|
5301
5246
|
const NumberInputRoot = React__namespace.forwardRef(function NumberInput(props, ref) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Tooltip as Tooltip$1, Group, InputElement, Icon, EmptyState as EmptyState$2, VStack, List, Table as Table$1, Checkbox as Checkbox$1, Card, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Image, Alert, Field as Field$1, Popover, Tabs, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading
|
|
2
|
+
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Tooltip as Tooltip$1, Group, InputElement, Icon, EmptyState as EmptyState$2, VStack, List, Table as Table$1, Checkbox as Checkbox$1, Card, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Image, Alert, Field as Field$1, Popover, useFilter, useListCollection, Combobox, Tabs, Skeleton, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading } from '@chakra-ui/react';
|
|
3
3
|
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import React__default, { createContext, useContext, useState, useEffect, useRef, forwardRef } from 'react';
|
|
5
|
+
import React__default, { createContext, useContext, useState, useEffect, useRef, useMemo, forwardRef } from 'react';
|
|
6
6
|
import { LuX, LuCheck, LuChevronRight, LuSearch, LuImage, LuFile } from 'react-icons/lu';
|
|
7
7
|
import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineChecklist, MdClear, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdDateRange } from 'react-icons/md';
|
|
8
8
|
import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
|
|
@@ -21,7 +21,7 @@ import { useQueryClient, useQuery } from '@tanstack/react-query';
|
|
|
21
21
|
import { IoReload } from 'react-icons/io5';
|
|
22
22
|
import { useDebounce } from '@uidotdev/usehooks';
|
|
23
23
|
import { BsExclamationCircleFill, BsClock } from 'react-icons/bs';
|
|
24
|
-
import { HiColorSwatch
|
|
24
|
+
import { HiColorSwatch } from 'react-icons/hi';
|
|
25
25
|
import { flexRender, createColumnHelper, makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel } from '@tanstack/react-table';
|
|
26
26
|
import { GrAscend, GrDescend } from 'react-icons/gr';
|
|
27
27
|
import { useTranslation } from 'react-i18next';
|
|
@@ -555,7 +555,7 @@ const PaginationItems = (props) => {
|
|
|
555
555
|
return page.type === "ellipsis" ? (jsx(PaginationEllipsis, { index: index, ...props }, index)) : (jsx(PaginationItem, { type: "page", value: page.value, ...props }, index));
|
|
556
556
|
}) }));
|
|
557
557
|
};
|
|
558
|
-
|
|
558
|
+
React.forwardRef(function PaginationPageText(props, ref) {
|
|
559
559
|
const { format = "compact", ...rest } = props;
|
|
560
560
|
const { page, totalPages, pageRange, count } = usePaginationContext();
|
|
561
561
|
const content = React.useMemo(() => {
|
|
@@ -4156,16 +4156,6 @@ const DateRangePicker = ({ column, schema, prefix, }) => {
|
|
|
4156
4156
|
}, monthsToDisplay: 2 })] }) })] }) }));
|
|
4157
4157
|
};
|
|
4158
4158
|
|
|
4159
|
-
function filterArray(array, searchTerm) {
|
|
4160
|
-
// Convert the search term to lower case for case-insensitive comparison
|
|
4161
|
-
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
|
4162
|
-
// Use the filter method to return an array of matching items
|
|
4163
|
-
return array.filter((item) => {
|
|
4164
|
-
// Convert each item to a string and check if it includes the search term
|
|
4165
|
-
return item.toString().toLowerCase().includes(lowerCaseSearchTerm);
|
|
4166
|
-
});
|
|
4167
|
-
}
|
|
4168
|
-
|
|
4169
4159
|
const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLimit = false, }) => {
|
|
4170
4160
|
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4171
4161
|
const { enumPickerLabels } = useSchemaContext();
|
|
@@ -4173,89 +4163,74 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
4173
4163
|
const { required, variant } = schema;
|
|
4174
4164
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
4175
4165
|
const { gridColumn = 'span 12', gridRow = 'span 1', renderDisplay } = schema;
|
|
4176
|
-
const [searchText, setSearchText] = useState();
|
|
4177
|
-
const [limit, setLimit] = useState(10);
|
|
4178
|
-
const [openSearchResult, setOpenSearchResult] = useState();
|
|
4179
|
-
const ref = useRef(null);
|
|
4180
4166
|
const colLabel = formI18n.colLabel;
|
|
4181
4167
|
const watchEnum = watch(colLabel);
|
|
4182
4168
|
const watchEnums = (watch(colLabel) ?? []);
|
|
4183
4169
|
const dataList = schema.enum ?? [];
|
|
4184
|
-
|
|
4185
|
-
const
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4170
|
+
// Current value for combobox (array format)
|
|
4171
|
+
const currentValue = isMultiple
|
|
4172
|
+
? watchEnums.filter((val) => val != null && val !== '')
|
|
4173
|
+
: watchEnum
|
|
4174
|
+
? [watchEnum]
|
|
4175
|
+
: [];
|
|
4176
|
+
// Transform enum data for combobox collection
|
|
4177
|
+
const comboboxItems = useMemo(() => {
|
|
4178
|
+
return dataList.map((item) => ({
|
|
4179
|
+
label: !!renderDisplay === true
|
|
4180
|
+
? String(renderDisplay(item))
|
|
4181
|
+
: formI18n.t(item),
|
|
4182
|
+
value: item,
|
|
4183
|
+
}));
|
|
4184
|
+
}, [dataList, renderDisplay, formI18n]);
|
|
4185
|
+
// Use filter hook for combobox
|
|
4186
|
+
const { contains } = useFilter({ sensitivity: 'base' });
|
|
4187
|
+
// Create collection for combobox
|
|
4188
|
+
const { collection, filter } = useListCollection({
|
|
4189
|
+
initialItems: comboboxItems,
|
|
4190
|
+
itemToString: (item) => item.label,
|
|
4191
|
+
itemToValue: (item) => item.value,
|
|
4192
|
+
filter: contains,
|
|
4193
|
+
});
|
|
4194
|
+
// Handle input value change (search)
|
|
4195
|
+
const handleInputValueChange = (details) => {
|
|
4196
|
+
filter(details.inputValue);
|
|
4197
|
+
};
|
|
4198
|
+
// Handle value change
|
|
4199
|
+
const handleValueChange = (details) => {
|
|
4200
|
+
if (isMultiple) {
|
|
4201
|
+
setValue(colLabel, details.value);
|
|
4202
|
+
}
|
|
4203
|
+
else {
|
|
4204
|
+
setValue(colLabel, details.value[0] || '');
|
|
4205
|
+
}
|
|
4189
4206
|
};
|
|
4190
4207
|
if (variant === 'radio') {
|
|
4191
4208
|
return (jsx(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4192
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsx(RadioGroup$1.Root, {
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
}
|
|
4199
|
-
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4200
|
-
setValue(colLabel, [...newSet]);
|
|
4201
|
-
}, value: item, children: [jsx(RadioGroup$1.ItemHiddenInput, {}), jsx(RadioGroup$1.ItemIndicator, {}), jsx(RadioGroup$1.ItemText, { children: !!renderDisplay === true
|
|
4209
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: jsx(RadioGroup$1.Root, { value: !isMultiple ? watchEnum : undefined, onValueChange: (details) => {
|
|
4210
|
+
if (!isMultiple) {
|
|
4211
|
+
setValue(colLabel, details.value);
|
|
4212
|
+
}
|
|
4213
|
+
}, children: jsx(HStack, { gap: "6", children: dataList.map((item) => {
|
|
4214
|
+
return (jsxs(RadioGroup$1.Item, { value: item, children: [jsx(RadioGroup$1.ItemHiddenInput, {}), jsx(RadioGroup$1.ItemIndicator, {}), jsx(RadioGroup$1.ItemText, { children: !!renderDisplay === true
|
|
4202
4215
|
? renderDisplay(item)
|
|
4203
4216
|
: formI18n.t(item) })] }, `${colLabel}-${item}`));
|
|
4204
4217
|
}) }) }) }));
|
|
4205
4218
|
}
|
|
4206
4219
|
return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
4207
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
}, justifyContent: 'start', children: !!watchEnum === false ? '' : formI18n.t(watchEnum ?? 'null') })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: 'bottom-start' }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { portalled: false, children: jsxs(PopoverBody, { display: 'grid', gap: 1, children: [jsx(Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search'), onChange: (event) => {
|
|
4222
|
-
onSearchChange(event);
|
|
4223
|
-
setOpenSearchResult(true);
|
|
4224
|
-
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${count}, ${enumPickerLabels?.showing ?? formI18n.t('showing')} ${limit}` })), jsxs(Grid, { overflow: 'auto', maxHeight: '20rem', children: [jsx(Flex, { flexFlow: 'column wrap', children: dataList
|
|
4225
|
-
.filter((item) => {
|
|
4226
|
-
const searchTerm = (searchText || '').toLowerCase();
|
|
4227
|
-
if (!searchTerm)
|
|
4228
|
-
return true;
|
|
4229
|
-
// Check if the original enum value contains the search text
|
|
4230
|
-
const enumValueMatch = item
|
|
4231
|
-
.toLowerCase()
|
|
4232
|
-
.includes(searchTerm);
|
|
4233
|
-
// Check if the display value (translation) contains the search text
|
|
4234
|
-
const displayValue = !!renderDisplay === true
|
|
4235
|
-
? renderDisplay(item)
|
|
4236
|
-
: formI18n.t(item);
|
|
4237
|
-
// Convert to string and check if it includes the search term
|
|
4238
|
-
const displayValueString = String(displayValue).toLowerCase();
|
|
4239
|
-
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
4240
|
-
return enumValueMatch || displayValueMatch;
|
|
4241
|
-
})
|
|
4242
|
-
.map((item) => {
|
|
4243
|
-
const selected = isMultiple
|
|
4244
|
-
? watchEnums.some((enumValue) => item === enumValue)
|
|
4245
|
-
: watchEnum == item;
|
|
4246
|
-
return (jsx(Box, { cursor: 'pointer', onClick: () => {
|
|
4247
|
-
if (!isMultiple) {
|
|
4248
|
-
setOpenSearchResult(false);
|
|
4249
|
-
setValue(colLabel, item);
|
|
4250
|
-
return;
|
|
4251
|
-
}
|
|
4252
|
-
const newSet = new Set([...(watchEnums ?? []), item]);
|
|
4253
|
-
setValue(colLabel, [...newSet]);
|
|
4254
|
-
}, ...(selected ? { color: 'colorPalette.400/50' } : {}), children: !!renderDisplay === true
|
|
4255
|
-
? renderDisplay(item)
|
|
4256
|
-
: formI18n.t(item) }, `${colLabel}-${item}`));
|
|
4257
|
-
}) }), isDirty && (jsx(Fragment, { children: dataList.length <= 0 && (jsx(Fragment, { children: enumPickerLabels?.emptySearchResult ??
|
|
4258
|
-
formI18n.t('empty_search_result') })) }))] })] }) })] })] }));
|
|
4220
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && currentValue.length > 0 && (jsx(Flex, { flexFlow: 'wrap', gap: 1, mb: 2, children: currentValue.map((enumValue) => {
|
|
4221
|
+
if (!enumValue) {
|
|
4222
|
+
return null;
|
|
4223
|
+
}
|
|
4224
|
+
return (jsx(Tag, { size: "lg", closable: true, onClick: () => {
|
|
4225
|
+
const newValue = currentValue.filter((val) => val !== enumValue);
|
|
4226
|
+
setValue(colLabel, newValue);
|
|
4227
|
+
}, children: !!renderDisplay === true
|
|
4228
|
+
? renderDisplay(enumValue)
|
|
4229
|
+
: formI18n.t(enumValue) }, enumValue));
|
|
4230
|
+
}) })), jsxs(Combobox.Root, { collection: collection, value: currentValue, onValueChange: handleValueChange, onInputValueChange: handleInputValueChange, multiple: isMultiple, closeOnSelect: !isMultiple, openOnClick: true, invalid: !!errors[colLabel], width: "100%", children: [jsxs(Combobox.Control, { children: [jsx(Combobox.Input, { placeholder: enumPickerLabels?.typeToSearch ?? formI18n.t('type_to_search') }), jsxs(Combobox.IndicatorGroup, { children: [!isMultiple && currentValue.length > 0 && (jsx(Combobox.ClearTrigger, { onClick: () => {
|
|
4231
|
+
setValue(colLabel, '');
|
|
4232
|
+
} })), jsx(Combobox.Trigger, {})] })] }), jsx(Portal, { children: jsx(Combobox.Positioner, { children: jsxs(Combobox.Content, { children: [showTotalAndLimit && (jsx(Text, { p: 2, fontSize: "sm", color: "fg.muted", children: `${enumPickerLabels?.total ?? formI18n.t('total')}: ${collection.items.length}` })), collection.items.length === 0 ? (jsx(Combobox.Empty, { children: enumPickerLabels?.emptySearchResult ??
|
|
4233
|
+
formI18n.t('empty_search_result') })) : (jsx(Fragment, { children: collection.items.map((item, index) => (jsxs(Combobox.Item, { item: item, children: [jsx(Combobox.ItemText, { children: item.label }), jsx(Combobox.ItemIndicator, {})] }, item.value ?? `item-${index}`))) }))] }) }) })] })] }));
|
|
4259
4234
|
};
|
|
4260
4235
|
|
|
4261
4236
|
function isEnteringWindow(_ref) {
|
|
@@ -4647,9 +4622,7 @@ const MediaLibraryBrowser = ({ onFetchFiles, filterImageOnly = false, labels, en
|
|
|
4647
4622
|
: files;
|
|
4648
4623
|
const handleFileClick = (file) => {
|
|
4649
4624
|
if (multiple) {
|
|
4650
|
-
const currentSelection = Array.isArray(selectedFile)
|
|
4651
|
-
? selectedFile
|
|
4652
|
-
: [];
|
|
4625
|
+
const currentSelection = Array.isArray(selectedFile) ? selectedFile : [];
|
|
4653
4626
|
const isAlreadySelected = currentSelection.some((f) => f.id === file.id);
|
|
4654
4627
|
const newSelection = isAlreadySelected
|
|
4655
4628
|
? currentSelection.filter((f) => f.id !== file.id)
|
|
@@ -5016,15 +4989,6 @@ const FormMediaLibraryBrowser = ({ column, schema, prefix, }) => {
|
|
|
5016
4989
|
}) })] }));
|
|
5017
4990
|
};
|
|
5018
4991
|
|
|
5019
|
-
const ToggleTip = React.forwardRef(function ToggleTip(props, ref) {
|
|
5020
|
-
const { showArrow, children, portalled = true, content, portalRef, ...rest } = props;
|
|
5021
|
-
return (jsxs(Popover.Root, { ...rest, positioning: { ...rest.positioning, gutter: 4 }, children: [jsx(Popover.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Popover.Positioner, { children: jsxs(Popover.Content, { width: "auto", px: "2", py: "1", textStyle: "xs", rounded: "sm", ref: ref, children: [showArrow && (jsx(Popover.Arrow, { children: jsx(Popover.ArrowTip, {}) })), content] }) }) })] }));
|
|
5022
|
-
});
|
|
5023
|
-
const InfoTip = React.forwardRef(function InfoTip(props, ref) {
|
|
5024
|
-
const { children, ...rest } = props;
|
|
5025
|
-
return (jsx(ToggleTip, { content: children, ...rest, ref: ref, children: jsx(IconButton, { variant: "ghost", "aria-label": "info", size: "2xs", colorPalette: "colorPalette", children: jsx(HiOutlineInformationCircle, {}) }) }));
|
|
5026
|
-
});
|
|
5027
|
-
|
|
5028
4992
|
const getTableData = async ({ serverUrl, in_table, searching = "", where = [], limit = 10, offset = 0, }) => {
|
|
5029
4993
|
if (serverUrl === undefined || serverUrl.length == 0) {
|
|
5030
4994
|
throw new Error("The serverUrl is missing");
|
|
@@ -5061,10 +5025,8 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5061
5025
|
const isRequired = required?.some((columnId) => columnId === column);
|
|
5062
5026
|
const { table, column: column_ref, display_column, customQueryFn, } = foreign_key;
|
|
5063
5027
|
const [searchText, setSearchText] = useState('');
|
|
5064
|
-
const [
|
|
5065
|
-
const [
|
|
5066
|
-
const [page, setPage] = useState(0);
|
|
5067
|
-
const ref = useRef(null);
|
|
5028
|
+
const [debouncedSearchText, setDebouncedSearchText] = useState('');
|
|
5029
|
+
const [limit] = useState(50); // Increased limit for combobox
|
|
5068
5030
|
const colLabel = formI18n.colLabel;
|
|
5069
5031
|
const watchedValue = watch(colLabel);
|
|
5070
5032
|
const watchId = !isMultiple ? watchedValue : undefined;
|
|
@@ -5079,22 +5041,32 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5079
5041
|
: [];
|
|
5080
5042
|
// Use watched values if they exist (including empty string for single select),
|
|
5081
5043
|
// otherwise fall back to initial values from getValues()
|
|
5082
|
-
// This ensures the query can trigger on mount with initial values
|
|
5083
|
-
// For single: use watchId if it's not undefined/null, otherwise use initialId
|
|
5084
|
-
// For multiple: use watchIds if watchedValue is defined, otherwise use initialIds
|
|
5085
5044
|
const currentId = watchId !== undefined && watchId !== null ? watchId : initialId;
|
|
5086
5045
|
const currentIds = watchedValue !== undefined && watchedValue !== null && isMultiple
|
|
5087
5046
|
? watchIds
|
|
5088
5047
|
: initialIds;
|
|
5089
|
-
//
|
|
5048
|
+
// Current value for combobox (array format)
|
|
5049
|
+
const currentValue = isMultiple
|
|
5050
|
+
? currentIds.filter((id) => id != null && id !== '')
|
|
5051
|
+
: currentId
|
|
5052
|
+
? [currentId]
|
|
5053
|
+
: [];
|
|
5054
|
+
// Debounce search text to avoid too many API calls
|
|
5055
|
+
useEffect(() => {
|
|
5056
|
+
const timer = setTimeout(() => {
|
|
5057
|
+
setDebouncedSearchText(searchText);
|
|
5058
|
+
}, 300);
|
|
5059
|
+
return () => clearTimeout(timer);
|
|
5060
|
+
}, [searchText]);
|
|
5061
|
+
// Query for search results (async loading)
|
|
5090
5062
|
const query = useQuery({
|
|
5091
|
-
queryKey: [`idpicker`, { column, searchText, limit
|
|
5063
|
+
queryKey: [`idpicker`, { column, searchText: debouncedSearchText, limit }],
|
|
5092
5064
|
queryFn: async () => {
|
|
5093
5065
|
if (customQueryFn) {
|
|
5094
5066
|
const { data, idMap } = await customQueryFn({
|
|
5095
|
-
searching:
|
|
5067
|
+
searching: debouncedSearchText ?? '',
|
|
5096
5068
|
limit: limit,
|
|
5097
|
-
offset:
|
|
5069
|
+
offset: 0,
|
|
5098
5070
|
});
|
|
5099
5071
|
setIdMap((state) => {
|
|
5100
5072
|
return { ...state, ...idMap };
|
|
@@ -5103,10 +5075,10 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5103
5075
|
}
|
|
5104
5076
|
const data = await getTableData({
|
|
5105
5077
|
serverUrl,
|
|
5106
|
-
searching:
|
|
5078
|
+
searching: debouncedSearchText ?? '',
|
|
5107
5079
|
in_table: table,
|
|
5108
5080
|
limit: limit,
|
|
5109
|
-
offset:
|
|
5081
|
+
offset: 0,
|
|
5110
5082
|
});
|
|
5111
5083
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
5112
5084
|
return [
|
|
@@ -5121,12 +5093,12 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5121
5093
|
});
|
|
5122
5094
|
return data;
|
|
5123
5095
|
},
|
|
5124
|
-
enabled:
|
|
5096
|
+
enabled: true, // Always enabled for combobox
|
|
5125
5097
|
staleTime: 300000,
|
|
5126
5098
|
});
|
|
5127
5099
|
// Query for currently selected items (to display them properly)
|
|
5128
|
-
//
|
|
5129
|
-
|
|
5100
|
+
// This query is needed for side effects (populating idMap) even though the result isn't directly used
|
|
5101
|
+
useQuery({
|
|
5130
5102
|
queryKey: [
|
|
5131
5103
|
`idpicker-default`,
|
|
5132
5104
|
{
|
|
@@ -5136,11 +5108,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5136
5108
|
},
|
|
5137
5109
|
],
|
|
5138
5110
|
queryFn: async () => {
|
|
5139
|
-
// Use current values (which include initial) for the query
|
|
5140
5111
|
const queryId = currentId;
|
|
5141
5112
|
const queryIds = currentIds;
|
|
5142
5113
|
if (customQueryFn) {
|
|
5143
|
-
// For customQueryFn, pass where clause to fetch specific IDs
|
|
5144
5114
|
const { data, idMap } = await customQueryFn({
|
|
5145
5115
|
searching: '',
|
|
5146
5116
|
limit: isMultiple ? queryIds.length : 1,
|
|
@@ -5155,10 +5125,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5155
5125
|
if (!queryId && (!queryIds || queryIds.length === 0)) {
|
|
5156
5126
|
return { data: [] };
|
|
5157
5127
|
}
|
|
5158
|
-
const searchValue = isMultiple ? queryIds.join(',') : queryId;
|
|
5159
5128
|
const data = await getTableData({
|
|
5160
5129
|
serverUrl,
|
|
5161
|
-
searching:
|
|
5130
|
+
searching: '',
|
|
5162
5131
|
in_table: table,
|
|
5163
5132
|
where: [{ id: column_ref, value: isMultiple ? queryIds : queryId }],
|
|
5164
5133
|
limit: isMultiple ? queryIds.length : 1,
|
|
@@ -5181,101 +5150,77 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5181
5150
|
? Array.isArray(currentIds) && currentIds.length > 0
|
|
5182
5151
|
: !!currentId,
|
|
5183
5152
|
});
|
|
5184
|
-
// Effect to trigger initial data fetch when popover opens
|
|
5185
|
-
useEffect(() => {
|
|
5186
|
-
if (openSearchResult) {
|
|
5187
|
-
// Reset search text when opening the popover
|
|
5188
|
-
setSearchText('');
|
|
5189
|
-
// Reset page to first page
|
|
5190
|
-
setPage(0);
|
|
5191
|
-
// Fetch initial data
|
|
5192
|
-
query.refetch();
|
|
5193
|
-
}
|
|
5194
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5195
|
-
}, [openSearchResult]);
|
|
5196
|
-
const onSearchChange = async (event) => {
|
|
5197
|
-
setSearchText(event.target.value);
|
|
5198
|
-
setPage(0);
|
|
5199
|
-
query.refetch();
|
|
5200
|
-
};
|
|
5201
|
-
const handleLimitChange = (event) => {
|
|
5202
|
-
const newLimit = Number(event.target.value);
|
|
5203
|
-
setLimit(newLimit);
|
|
5204
|
-
// Reset to first page when changing limit
|
|
5205
|
-
setPage(0);
|
|
5206
|
-
// Trigger a new search with the updated limit
|
|
5207
|
-
query.refetch();
|
|
5208
|
-
};
|
|
5209
5153
|
const { isLoading, isFetching, data, isPending, isError } = query;
|
|
5210
5154
|
const dataList = data?.data ?? [];
|
|
5211
|
-
|
|
5212
|
-
const
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5155
|
+
// Check if we're currently searching (user typed but debounce hasn't fired yet)
|
|
5156
|
+
const isSearching = searchText !== debouncedSearchText;
|
|
5157
|
+
// Transform data for combobox collection
|
|
5158
|
+
const comboboxItems = useMemo(() => {
|
|
5159
|
+
return dataList.map((item) => ({
|
|
5160
|
+
label: !!renderDisplay === true
|
|
5161
|
+
? String(renderDisplay(item))
|
|
5162
|
+
: String(item[display_column] ?? ''),
|
|
5163
|
+
value: String(item[column_ref]),
|
|
5164
|
+
raw: item,
|
|
5165
|
+
}));
|
|
5166
|
+
}, [dataList, display_column, column_ref, renderDisplay]);
|
|
5167
|
+
// Use filter hook for combobox
|
|
5168
|
+
const { contains } = useFilter({ sensitivity: 'base' });
|
|
5169
|
+
// Create collection for combobox
|
|
5170
|
+
const { collection, filter, set } = useListCollection({
|
|
5171
|
+
initialItems: comboboxItems,
|
|
5172
|
+
itemToString: (item) => item.label,
|
|
5173
|
+
itemToValue: (item) => item.value,
|
|
5174
|
+
filter: contains,
|
|
5175
|
+
});
|
|
5176
|
+
// Handle input value change (search)
|
|
5177
|
+
const handleInputValueChange = (details) => {
|
|
5178
|
+
setSearchText(details.inputValue);
|
|
5179
|
+
// Filter will be applied after data is fetched
|
|
5180
|
+
};
|
|
5181
|
+
// Handle value change
|
|
5182
|
+
const handleValueChange = (details) => {
|
|
5183
|
+
if (isMultiple) {
|
|
5184
|
+
setValue(colLabel, details.value);
|
|
5220
5185
|
}
|
|
5221
|
-
|
|
5222
|
-
|
|
5186
|
+
else {
|
|
5187
|
+
setValue(colLabel, details.value[0] || '');
|
|
5223
5188
|
}
|
|
5224
|
-
return record[display_column];
|
|
5225
5189
|
};
|
|
5190
|
+
// Update collection and filter when data changes
|
|
5191
|
+
useEffect(() => {
|
|
5192
|
+
if (dataList.length > 0 && comboboxItems.length > 0) {
|
|
5193
|
+
set(comboboxItems);
|
|
5194
|
+
// Apply filter to the collection using the immediate searchText for UI responsiveness
|
|
5195
|
+
if (searchText) {
|
|
5196
|
+
filter(searchText);
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
// Only depend on dataList and searchText, not comboboxItems (which is derived from dataList)
|
|
5200
|
+
// set and filter are stable functions from useListCollection
|
|
5201
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5202
|
+
}, [dataList, searchText]);
|
|
5226
5203
|
return (jsxs(Field, { label: formI18n.label(), required: isRequired, alignItems: 'stretch', gridColumn,
|
|
5227
|
-
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && (
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
fontSize: '14px',
|
|
5248
|
-
}, children: [jsx("option", { value: "5", children: "5" }), jsx("option", { value: "10", children: "10" }), jsx("option", { value: "20", children: "20" }), jsx("option", { value: "30", children: "30" })] }) })] }), jsx(Grid, { overflowY: 'auto', children: dataList.length > 0 ? (jsx(Flex, { flexFlow: 'column wrap', gap: 1, children: dataList.map((item) => {
|
|
5249
|
-
const selected = isMultiple
|
|
5250
|
-
? watchIds.some((id) => item[column_ref] === id)
|
|
5251
|
-
: watchId === item[column_ref];
|
|
5252
|
-
return (jsx(Box, { cursor: 'pointer', onClick: () => {
|
|
5253
|
-
if (!isMultiple) {
|
|
5254
|
-
setOpenSearchResult(false);
|
|
5255
|
-
setValue(colLabel, item[column_ref]);
|
|
5256
|
-
return;
|
|
5257
|
-
}
|
|
5258
|
-
// For multiple selection, don't add if already selected
|
|
5259
|
-
if (selected)
|
|
5260
|
-
return;
|
|
5261
|
-
const newSet = new Set([
|
|
5262
|
-
...(watchIds ?? []),
|
|
5263
|
-
item[column_ref],
|
|
5264
|
-
]);
|
|
5265
|
-
setValue(colLabel, [...newSet]);
|
|
5266
|
-
}, opacity: 0.7, _hover: { opacity: 1 }, ...(selected
|
|
5267
|
-
? {
|
|
5268
|
-
color: 'colorPalette.400/50',
|
|
5269
|
-
fontWeight: 'bold',
|
|
5270
|
-
}
|
|
5271
|
-
: {}), children: !!renderDisplay === true
|
|
5272
|
-
? renderDisplay(item)
|
|
5273
|
-
: item[display_column] }, item[column_ref]));
|
|
5274
|
-
}) })) : (jsx(Text, { children: searchText
|
|
5275
|
-
? idPickerLabels?.emptySearchResult ??
|
|
5276
|
-
formI18n.t('empty_search_result')
|
|
5277
|
-
: idPickerLabels?.initialResults ??
|
|
5278
|
-
formI18n.t('initial_results') })) }), jsx(PaginationRoot, { justifySelf: 'center', count: count, pageSize: limit, defaultPage: 1, page: page + 1, onPageChange: (e) => setPage(e.page - 1), children: jsxs(HStack, { gap: "4", children: [jsx(PaginationPrevTrigger, {}), count > 0 && jsx(PaginationPageText, {}), jsx(PaginationNextTrigger, {})] }) })] }))] }) })] })] }));
|
|
5204
|
+
gridRow, errorText: errors[`${colLabel}`] ? formI18n.required() : undefined, invalid: !!errors[colLabel], children: [isMultiple && currentValue.length > 0 && (jsx(Flex, { flexFlow: 'wrap', gap: 1, mb: 2, children: currentValue.map((id) => {
|
|
5205
|
+
const item = idMap[id];
|
|
5206
|
+
if (item === undefined) {
|
|
5207
|
+
return (jsx(Text, { fontSize: "sm", children: idPickerLabels?.undefined ?? formI18n.t('undefined') }, id));
|
|
5208
|
+
}
|
|
5209
|
+
return (jsx(Tag, { closable: true, onClick: () => {
|
|
5210
|
+
const newValue = currentValue.filter((itemId) => itemId !== id);
|
|
5211
|
+
setValue(colLabel, newValue);
|
|
5212
|
+
}, children: !!renderDisplay === true
|
|
5213
|
+
? renderDisplay(item)
|
|
5214
|
+
: item[display_column] }, id));
|
|
5215
|
+
}) })), jsxs(Combobox.Root, { collection: collection, value: currentValue, onValueChange: handleValueChange, onInputValueChange: handleInputValueChange, multiple: isMultiple, closeOnSelect: !isMultiple, openOnClick: true, invalid: !!errors[colLabel], width: "100%", children: [jsxs(Combobox.Control, { children: [jsx(Combobox.Input, { placeholder: idPickerLabels?.typeToSearch ?? formI18n.t('type_to_search') }), jsxs(Combobox.IndicatorGroup, { children: [(isFetching || isLoading || isPending) && jsx(Spinner, { size: "xs" }), isError && (jsx(Icon, { color: "fg.error", children: jsx(BiError, {}) })), !isMultiple && currentValue.length > 0 && (jsx(Combobox.ClearTrigger, { onClick: () => {
|
|
5216
|
+
setValue(colLabel, '');
|
|
5217
|
+
} })), jsx(Combobox.Trigger, {})] })] }), jsx(Portal, { children: jsx(Combobox.Positioner, { children: jsx(Combobox.Content, { children: isError ? (jsx(Text, { p: 2, color: "fg.error", fontSize: "sm", children: formI18n.t('loading_failed') })) : isFetching || isLoading || isPending || isSearching ? (
|
|
5218
|
+
// Show skeleton items to prevent UI shift
|
|
5219
|
+
jsx(Fragment, { children: Array.from({ length: 5 }).map((_, index) => (jsx(Flex, { p: 2, align: "center", gap: 2, children: jsx(Skeleton, { height: "20px", flex: "1" }) }, `skeleton-${index}`))) })) : collection.items.length === 0 ? (jsx(Combobox.Empty, { children: searchText
|
|
5220
|
+
? idPickerLabels?.emptySearchResult ??
|
|
5221
|
+
formI18n.t('empty_search_result')
|
|
5222
|
+
: idPickerLabels?.initialResults ??
|
|
5223
|
+
formI18n.t('initial_results') })) : (jsx(Fragment, { children: collection.items.map((item, index) => (jsxs(Combobox.Item, { item: item, children: [jsx(Combobox.ItemText, { children: item.label }), jsx(Combobox.ItemIndicator, {})] }, item.value ?? `item-${index}`))) })) }) }) })] })] }));
|
|
5279
5224
|
};
|
|
5280
5225
|
|
|
5281
5226
|
const NumberInputRoot = React.forwardRef(function NumberInput$1(props, ref) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bsol-oss/react-datatable5",
|
|
3
|
-
"version": "12.0.0-beta.
|
|
3
|
+
"version": "12.0.0-beta.86",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"@rollup/plugin-typescript": "^11.1.6",
|
|
63
63
|
"@storybook/addon-essentials": "^8.4.7",
|
|
64
64
|
"@storybook/addon-interactions": "^8.4.7",
|
|
65
|
-
"@storybook/addon-onboarding": "^
|
|
65
|
+
"@storybook/addon-onboarding": "^10.0.7",
|
|
66
66
|
"@storybook/blocks": "^8.4.7",
|
|
67
|
-
"@storybook/react": "^
|
|
68
|
-
"@storybook/react-vite": "^
|
|
67
|
+
"@storybook/react": "^10.0.7",
|
|
68
|
+
"@storybook/react-vite": "^10.0.7",
|
|
69
69
|
"@storybook/test": "^8.4.7",
|
|
70
70
|
"@types/ajv-errors": "^2.0.0",
|
|
71
71
|
"@types/json-schema": "^7.0.15",
|
|
@@ -81,12 +81,12 @@
|
|
|
81
81
|
"eslint": "^8.57.0",
|
|
82
82
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
83
83
|
"eslint-plugin-react-refresh": "^0.4.6",
|
|
84
|
-
"eslint-plugin-storybook": "^0.
|
|
84
|
+
"eslint-plugin-storybook": "^10.0.7",
|
|
85
85
|
"husky": "^9.1.7",
|
|
86
86
|
"lint-staged": "^16.2.5",
|
|
87
87
|
"prettier": "3.2.5",
|
|
88
88
|
"rollup-plugin-dts": "^6.1.0",
|
|
89
|
-
"storybook": "^
|
|
89
|
+
"storybook": "^10.0.7",
|
|
90
90
|
"typescript": "^5.2.2",
|
|
91
91
|
"vite": "^5.2.0"
|
|
92
92
|
},
|