@bsol-oss/react-datatable5 12.0.0-beta.38 → 12.0.0-beta.39
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.js +187 -43
- package/dist/index.mjs +188 -44
- package/dist/types/components/TimePicker/TimePicker.d.ts +10 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3904,15 +3904,18 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
3904
3904
|
setOpenSearchResult(true);
|
|
3905
3905
|
}, justifyContent: "start", children: watchEnum === undefined
|
|
3906
3906
|
? ""
|
|
3907
|
-
: translate.t(removeIndex(`${colLabel}.${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: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3907
|
+
: translate.t(removeIndex(`${colLabel}.${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, { children: jsxRuntime.jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsxRuntime.jsx(react.Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3908
3908
|
onSearchChange(event);
|
|
3909
3909
|
setOpenSearchResult(true);
|
|
3910
|
-
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.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: dataList
|
|
3910
|
+
}, autoComplete: "off", ref: ref }), jsxRuntime.jsx(PopoverTitle, {}), showTotalAndLimit && (jsxRuntime.jsx(react.Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.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: dataList
|
|
3911
|
+
.filter((item) => {
|
|
3911
3912
|
const searchTerm = (searchText || "").toLowerCase();
|
|
3912
3913
|
if (!searchTerm)
|
|
3913
3914
|
return true;
|
|
3914
3915
|
// Check if the original enum value contains the search text
|
|
3915
|
-
const enumValueMatch = item
|
|
3916
|
+
const enumValueMatch = item
|
|
3917
|
+
.toLowerCase()
|
|
3918
|
+
.includes(searchTerm);
|
|
3916
3919
|
// Check if the display value (translation) contains the search text
|
|
3917
3920
|
const displayValue = !!renderDisplay === true
|
|
3918
3921
|
? renderDisplay(item)
|
|
@@ -3921,7 +3924,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
3921
3924
|
const displayValueString = String(displayValue).toLowerCase();
|
|
3922
3925
|
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
3923
3926
|
return enumValueMatch || displayValueMatch;
|
|
3924
|
-
})
|
|
3927
|
+
})
|
|
3928
|
+
.map((item) => {
|
|
3925
3929
|
const selected = isMultiple
|
|
3926
3930
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3927
3931
|
: watchEnum == item;
|
|
@@ -4726,42 +4730,180 @@ const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
|
4726
4730
|
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
4727
4731
|
am: "am",
|
|
4728
4732
|
pm: "pm",
|
|
4729
|
-
}, onChange = () => { }, }) {
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
}
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4733
|
+
}, onChange = (_newValue) => { }, }) {
|
|
4734
|
+
// Refs for focus management
|
|
4735
|
+
const hourInputRef = React.useRef(null);
|
|
4736
|
+
const minuteInputRef = React.useRef(null);
|
|
4737
|
+
const meridiemInputRef = React.useRef(null);
|
|
4738
|
+
// Centralized handler for key events, value changes, and focus management
|
|
4739
|
+
const handleKeyDown = (e, field) => {
|
|
4740
|
+
const input = e.target;
|
|
4741
|
+
const value = input.value;
|
|
4742
|
+
// Handle navigation between fields
|
|
4743
|
+
if (e.key === "Tab") {
|
|
4744
|
+
// Tab is handled by the browser, no need to override
|
|
4745
|
+
return;
|
|
4746
|
+
}
|
|
4747
|
+
if (e.key === ":" && field === "hour") {
|
|
4748
|
+
e.preventDefault();
|
|
4749
|
+
minuteInputRef.current?.focus();
|
|
4750
|
+
return;
|
|
4751
|
+
}
|
|
4752
|
+
if (e.key === "Backspace" && value === "") {
|
|
4753
|
+
e.preventDefault();
|
|
4754
|
+
if (field === "minute") {
|
|
4755
|
+
hourInputRef.current?.focus();
|
|
4756
|
+
}
|
|
4757
|
+
else if (field === "meridiem") {
|
|
4758
|
+
minuteInputRef.current?.focus();
|
|
4759
|
+
}
|
|
4760
|
+
return;
|
|
4761
|
+
}
|
|
4762
|
+
// Handle number inputs
|
|
4763
|
+
if (field === "hour") {
|
|
4764
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4765
|
+
const newValue = value + e.key;
|
|
4766
|
+
const numValue = parseInt(newValue, 10);
|
|
4767
|
+
console.log("newValue", newValue, numValue);
|
|
4768
|
+
if (numValue > 12) {
|
|
4769
|
+
const digitValue = parseInt(e.key, 10);
|
|
4770
|
+
setHour(digitValue);
|
|
4771
|
+
onChange({ hour: digitValue, minute, meridiem });
|
|
4772
|
+
return;
|
|
4773
|
+
}
|
|
4774
|
+
// Auto-advance to minutes if we have a valid hour (1-12)
|
|
4775
|
+
if (numValue >= 1 && numValue <= 12) {
|
|
4776
|
+
// Set the hour value
|
|
4777
|
+
setHour(numValue);
|
|
4778
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4779
|
+
// Move to minute input
|
|
4780
|
+
e.preventDefault();
|
|
4781
|
+
minuteInputRef.current?.focus();
|
|
4782
|
+
}
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
else if (field === "minute") {
|
|
4786
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4787
|
+
const newValue = value + e.key;
|
|
4788
|
+
const numValue = parseInt(newValue, 10);
|
|
4789
|
+
if (numValue > 60) {
|
|
4790
|
+
const digitValue = parseInt(e.key, 10);
|
|
4791
|
+
setHour(digitValue);
|
|
4792
|
+
onChange({ hour, minute: digitValue, meridiem });
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4795
|
+
// Auto-advance to meridiem if we have a valid minute (0-59)
|
|
4796
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
4797
|
+
// Set the minute value
|
|
4798
|
+
setMinute(numValue);
|
|
4799
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4800
|
+
// Move to meridiem input
|
|
4801
|
+
e.preventDefault();
|
|
4802
|
+
meridiemInputRef.current?.focus();
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
else if (field === "meridiem") {
|
|
4807
|
+
const key = e.key.toLowerCase();
|
|
4808
|
+
if (key === "a") {
|
|
4809
|
+
e.preventDefault();
|
|
4810
|
+
setMeridiem("am");
|
|
4811
|
+
onChange({ hour, minute, meridiem: "am" });
|
|
4812
|
+
input.value = "am";
|
|
4813
|
+
}
|
|
4814
|
+
else if (key === "p") {
|
|
4815
|
+
e.preventDefault();
|
|
4816
|
+
setMeridiem("pm");
|
|
4817
|
+
onChange({ hour, minute, meridiem: "pm" });
|
|
4818
|
+
input.value = "pm";
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
};
|
|
4822
|
+
// Handle input blur events to validate and format values
|
|
4823
|
+
const handleBlur = (e, field) => {
|
|
4824
|
+
const value = e.target.value;
|
|
4825
|
+
if (field === "hour") {
|
|
4826
|
+
if (value === "") {
|
|
4827
|
+
if (hour !== null) {
|
|
4828
|
+
setHour(null);
|
|
4829
|
+
onChange({ hour: null, minute, meridiem });
|
|
4830
|
+
}
|
|
4831
|
+
return;
|
|
4832
|
+
}
|
|
4833
|
+
const numValue = parseInt(value, 10);
|
|
4834
|
+
if (isNaN(numValue) || numValue < 1 || numValue > 12) {
|
|
4835
|
+
setHour(null);
|
|
4836
|
+
onChange({ hour: null, minute, meridiem });
|
|
4837
|
+
}
|
|
4838
|
+
else if (hour !== numValue) {
|
|
4839
|
+
setHour(numValue);
|
|
4840
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
else if (field === "minute") {
|
|
4844
|
+
if (value === "") {
|
|
4845
|
+
if (minute !== null) {
|
|
4846
|
+
setMinute(null);
|
|
4847
|
+
onChange({ hour, minute: null, meridiem });
|
|
4848
|
+
}
|
|
4849
|
+
return;
|
|
4850
|
+
}
|
|
4851
|
+
const numValue = parseInt(value, 10);
|
|
4852
|
+
if (isNaN(numValue) || numValue < 0 || numValue > 59) {
|
|
4853
|
+
setMinute(null);
|
|
4854
|
+
onChange({ hour, minute: null, meridiem });
|
|
4855
|
+
}
|
|
4856
|
+
else if (minute !== numValue) {
|
|
4857
|
+
setMinute(numValue);
|
|
4858
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4859
|
+
}
|
|
4860
|
+
}
|
|
4861
|
+
else if (field === "meridiem") {
|
|
4862
|
+
if (value === "") {
|
|
4863
|
+
if (meridiem !== null) {
|
|
4864
|
+
setMeridiem(null);
|
|
4865
|
+
onChange({ hour, minute, meridiem: null });
|
|
4866
|
+
}
|
|
4867
|
+
return;
|
|
4868
|
+
}
|
|
4869
|
+
const lowerValue = value.toLowerCase();
|
|
4870
|
+
if (lowerValue !== "am" && lowerValue !== "pm") {
|
|
4871
|
+
if (lowerValue === "a") {
|
|
4872
|
+
setMeridiem("am");
|
|
4873
|
+
onChange({ hour, minute, meridiem: "am" });
|
|
4874
|
+
}
|
|
4875
|
+
else if (lowerValue === "p") {
|
|
4876
|
+
setMeridiem("pm");
|
|
4877
|
+
onChange({ hour, minute, meridiem: "pm" });
|
|
4878
|
+
}
|
|
4879
|
+
else {
|
|
4880
|
+
setMeridiem(null);
|
|
4881
|
+
onChange({ hour, minute, meridiem: null });
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
else if (meridiem !== lowerValue) {
|
|
4885
|
+
setMeridiem(lowerValue);
|
|
4886
|
+
onChange({ hour, minute, meridiem: lowerValue });
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
};
|
|
4890
|
+
// Handle meridiem button click
|
|
4891
|
+
const handleMeridiemClick = (newMeridiem) => {
|
|
4892
|
+
setMeridiem(newMeridiem);
|
|
4893
|
+
onChange({ hour, minute, meridiem: newMeridiem });
|
|
4894
|
+
};
|
|
4895
|
+
const handleClear = () => {
|
|
4896
|
+
setHour(null);
|
|
4897
|
+
setMinute(null);
|
|
4898
|
+
setMeridiem(null);
|
|
4899
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
4900
|
+
// Focus the hour field after clearing
|
|
4901
|
+
hourInputRef.current?.focus();
|
|
4902
|
+
};
|
|
4903
|
+
function handleFocus(event) {
|
|
4904
|
+
event.target.select();
|
|
4905
|
+
}
|
|
4906
|
+
return (jsxRuntime.jsx(react.Flex, { direction: "column", gap: 3, children: jsxRuntime.jsxs(react.Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsxRuntime.jsx(react.Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsxRuntime.jsx(react.Text, { children: ":" }), jsxRuntime.jsx(react.Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxRuntime.jsxs(react.Flex, { gap: "1", children: [jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsxRuntime.jsx(react.Button, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsxRuntime.jsx(react.Button, { onClick: handleClear, size: "sm", variant: "ghost", children: jsxRuntime.jsx(md.MdCancel, {}) })] }) }));
|
|
4765
4907
|
}
|
|
4766
4908
|
|
|
4767
4909
|
const TimePicker = ({ column, schema, prefix }) => {
|
|
@@ -4772,7 +4914,7 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4772
4914
|
const colLabel = `${prefix}${column}`;
|
|
4773
4915
|
const [open, setOpen] = React.useState(false);
|
|
4774
4916
|
const value = watch(colLabel);
|
|
4775
|
-
const formatedTime = dayjs(value).format("hh:mm A");
|
|
4917
|
+
const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
|
|
4776
4918
|
// Parse the initial time parts from the ISO time string (HH:mm:ss)
|
|
4777
4919
|
const parseTime = (isoTime) => {
|
|
4778
4920
|
if (!isoTime)
|
|
@@ -4801,6 +4943,8 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4801
4943
|
}, [value]);
|
|
4802
4944
|
// Convert hour, minute, meridiem to 24-hour ISO time string
|
|
4803
4945
|
const toIsoTime = (hour, minute, meridiem) => {
|
|
4946
|
+
if (hour === null || minute === null || meridiem === null)
|
|
4947
|
+
return null;
|
|
4804
4948
|
let h = hour;
|
|
4805
4949
|
if (meridiem === "am" && hour === 12)
|
|
4806
4950
|
h = 0;
|
|
@@ -4821,8 +4965,8 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4821
4965
|
gridRow, children: [jsxRuntime.jsxs(react.Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsxRuntime.jsx(react.Popover.Trigger, { asChild: true, children: jsxRuntime.jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
4822
4966
|
setOpen(true);
|
|
4823
4967
|
}, justifyContent: "start", children: [jsxRuntime.jsx(io.IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsxRuntime.jsx(react.Portal, { children: jsxRuntime.jsx(react.Popover.Positioner, { children: jsxRuntime.jsx(react.Popover.Content, { ref: containerRef, children: jsxRuntime.jsx(react.Popover.Body, { children: jsxRuntime.jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
4824
|
-
am: translate.t(removeIndex(
|
|
4825
|
-
pm: translate.t(removeIndex(
|
|
4968
|
+
am: translate.t(removeIndex(`common.am`)),
|
|
4969
|
+
pm: translate.t(removeIndex(`common.pm`)),
|
|
4826
4970
|
} }) }) }) }) })] }), errors[`${column}`] && (jsxRuntime.jsx(react.Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4827
4971
|
};
|
|
4828
4972
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Tooltip as Tooltip$1, Group, InputElement, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Textarea,
|
|
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, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Tooltip as Tooltip$1, Group, InputElement, Icon, List, Table as Table$1, Checkbox as Checkbox$1, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Accordion, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Textarea, Center, Heading } from '@chakra-ui/react';
|
|
3
3
|
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { createContext, useContext, useState, useEffect, useRef } from 'react';
|
|
@@ -3884,15 +3884,18 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
3884
3884
|
setOpenSearchResult(true);
|
|
3885
3885
|
}, justifyContent: "start", children: watchEnum === undefined
|
|
3886
3886
|
? ""
|
|
3887
|
-
: translate.t(removeIndex(`${colLabel}.${watchEnum}`)) })), jsxs(PopoverRoot, { open: openSearchResult, onOpenChange: (e) => setOpenSearchResult(e.open), closeOnInteractOutside: true, initialFocusEl: () => ref.current, positioning: { placement: "bottom-start" }, children: [jsx(PopoverTrigger, {}), jsx(PopoverContent, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3887
|
+
: translate.t(removeIndex(`${colLabel}.${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, { children: jsxs(PopoverBody, { display: "grid", gap: 1, children: [jsx(Input, { placeholder: translate.t(`${colLabel}.type_to_search`), onChange: (event) => {
|
|
3888
3888
|
onSearchChange(event);
|
|
3889
3889
|
setOpenSearchResult(true);
|
|
3890
|
-
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList
|
|
3890
|
+
}, autoComplete: "off", ref: ref }), jsx(PopoverTitle, {}), showTotalAndLimit && (jsx(Text, { children: `${translate.t(`${colLabel}.total`)}: ${count}, ${translate.t(`${colLabel}.showing`)} ${limit}` })), jsxs(Grid, { gridTemplateColumns: "repeat(auto-fit, minmax(15rem, 1fr))", overflow: "auto", maxHeight: "50vh", children: [jsx(Flex, { flexFlow: "column wrap", children: dataList
|
|
3891
|
+
.filter((item) => {
|
|
3891
3892
|
const searchTerm = (searchText || "").toLowerCase();
|
|
3892
3893
|
if (!searchTerm)
|
|
3893
3894
|
return true;
|
|
3894
3895
|
// Check if the original enum value contains the search text
|
|
3895
|
-
const enumValueMatch = item
|
|
3896
|
+
const enumValueMatch = item
|
|
3897
|
+
.toLowerCase()
|
|
3898
|
+
.includes(searchTerm);
|
|
3896
3899
|
// Check if the display value (translation) contains the search text
|
|
3897
3900
|
const displayValue = !!renderDisplay === true
|
|
3898
3901
|
? renderDisplay(item)
|
|
@@ -3901,7 +3904,8 @@ const EnumPicker = ({ column, isMultiple = false, schema, prefix, showTotalAndLi
|
|
|
3901
3904
|
const displayValueString = String(displayValue).toLowerCase();
|
|
3902
3905
|
const displayValueMatch = displayValueString.includes(searchTerm);
|
|
3903
3906
|
return enumValueMatch || displayValueMatch;
|
|
3904
|
-
})
|
|
3907
|
+
})
|
|
3908
|
+
.map((item) => {
|
|
3905
3909
|
const selected = isMultiple
|
|
3906
3910
|
? watchEnums.some((enumValue) => item === enumValue)
|
|
3907
3911
|
: watchEnum == item;
|
|
@@ -4706,42 +4710,180 @@ const TextAreaInput = ({ column, schema, prefix, }) => {
|
|
|
4706
4710
|
function TimePicker$1({ hour, setHour, minute, setMinute, meridiem, setMeridiem, meridiemLabel = {
|
|
4707
4711
|
am: "am",
|
|
4708
4712
|
pm: "pm",
|
|
4709
|
-
}, onChange = () => { }, }) {
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
}
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4713
|
+
}, onChange = (_newValue) => { }, }) {
|
|
4714
|
+
// Refs for focus management
|
|
4715
|
+
const hourInputRef = useRef(null);
|
|
4716
|
+
const minuteInputRef = useRef(null);
|
|
4717
|
+
const meridiemInputRef = useRef(null);
|
|
4718
|
+
// Centralized handler for key events, value changes, and focus management
|
|
4719
|
+
const handleKeyDown = (e, field) => {
|
|
4720
|
+
const input = e.target;
|
|
4721
|
+
const value = input.value;
|
|
4722
|
+
// Handle navigation between fields
|
|
4723
|
+
if (e.key === "Tab") {
|
|
4724
|
+
// Tab is handled by the browser, no need to override
|
|
4725
|
+
return;
|
|
4726
|
+
}
|
|
4727
|
+
if (e.key === ":" && field === "hour") {
|
|
4728
|
+
e.preventDefault();
|
|
4729
|
+
minuteInputRef.current?.focus();
|
|
4730
|
+
return;
|
|
4731
|
+
}
|
|
4732
|
+
if (e.key === "Backspace" && value === "") {
|
|
4733
|
+
e.preventDefault();
|
|
4734
|
+
if (field === "minute") {
|
|
4735
|
+
hourInputRef.current?.focus();
|
|
4736
|
+
}
|
|
4737
|
+
else if (field === "meridiem") {
|
|
4738
|
+
minuteInputRef.current?.focus();
|
|
4739
|
+
}
|
|
4740
|
+
return;
|
|
4741
|
+
}
|
|
4742
|
+
// Handle number inputs
|
|
4743
|
+
if (field === "hour") {
|
|
4744
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4745
|
+
const newValue = value + e.key;
|
|
4746
|
+
const numValue = parseInt(newValue, 10);
|
|
4747
|
+
console.log("newValue", newValue, numValue);
|
|
4748
|
+
if (numValue > 12) {
|
|
4749
|
+
const digitValue = parseInt(e.key, 10);
|
|
4750
|
+
setHour(digitValue);
|
|
4751
|
+
onChange({ hour: digitValue, minute, meridiem });
|
|
4752
|
+
return;
|
|
4753
|
+
}
|
|
4754
|
+
// Auto-advance to minutes if we have a valid hour (1-12)
|
|
4755
|
+
if (numValue >= 1 && numValue <= 12) {
|
|
4756
|
+
// Set the hour value
|
|
4757
|
+
setHour(numValue);
|
|
4758
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4759
|
+
// Move to minute input
|
|
4760
|
+
e.preventDefault();
|
|
4761
|
+
minuteInputRef.current?.focus();
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
else if (field === "minute") {
|
|
4766
|
+
if (e.key.match(/^[0-9]$/)) {
|
|
4767
|
+
const newValue = value + e.key;
|
|
4768
|
+
const numValue = parseInt(newValue, 10);
|
|
4769
|
+
if (numValue > 60) {
|
|
4770
|
+
const digitValue = parseInt(e.key, 10);
|
|
4771
|
+
setHour(digitValue);
|
|
4772
|
+
onChange({ hour, minute: digitValue, meridiem });
|
|
4773
|
+
return;
|
|
4774
|
+
}
|
|
4775
|
+
// Auto-advance to meridiem if we have a valid minute (0-59)
|
|
4776
|
+
if (numValue >= 0 && numValue <= 59) {
|
|
4777
|
+
// Set the minute value
|
|
4778
|
+
setMinute(numValue);
|
|
4779
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4780
|
+
// Move to meridiem input
|
|
4781
|
+
e.preventDefault();
|
|
4782
|
+
meridiemInputRef.current?.focus();
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
else if (field === "meridiem") {
|
|
4787
|
+
const key = e.key.toLowerCase();
|
|
4788
|
+
if (key === "a") {
|
|
4789
|
+
e.preventDefault();
|
|
4790
|
+
setMeridiem("am");
|
|
4791
|
+
onChange({ hour, minute, meridiem: "am" });
|
|
4792
|
+
input.value = "am";
|
|
4793
|
+
}
|
|
4794
|
+
else if (key === "p") {
|
|
4795
|
+
e.preventDefault();
|
|
4796
|
+
setMeridiem("pm");
|
|
4797
|
+
onChange({ hour, minute, meridiem: "pm" });
|
|
4798
|
+
input.value = "pm";
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4801
|
+
};
|
|
4802
|
+
// Handle input blur events to validate and format values
|
|
4803
|
+
const handleBlur = (e, field) => {
|
|
4804
|
+
const value = e.target.value;
|
|
4805
|
+
if (field === "hour") {
|
|
4806
|
+
if (value === "") {
|
|
4807
|
+
if (hour !== null) {
|
|
4808
|
+
setHour(null);
|
|
4809
|
+
onChange({ hour: null, minute, meridiem });
|
|
4810
|
+
}
|
|
4811
|
+
return;
|
|
4812
|
+
}
|
|
4813
|
+
const numValue = parseInt(value, 10);
|
|
4814
|
+
if (isNaN(numValue) || numValue < 1 || numValue > 12) {
|
|
4815
|
+
setHour(null);
|
|
4816
|
+
onChange({ hour: null, minute, meridiem });
|
|
4817
|
+
}
|
|
4818
|
+
else if (hour !== numValue) {
|
|
4819
|
+
setHour(numValue);
|
|
4820
|
+
onChange({ hour: numValue, minute, meridiem });
|
|
4821
|
+
}
|
|
4822
|
+
}
|
|
4823
|
+
else if (field === "minute") {
|
|
4824
|
+
if (value === "") {
|
|
4825
|
+
if (minute !== null) {
|
|
4826
|
+
setMinute(null);
|
|
4827
|
+
onChange({ hour, minute: null, meridiem });
|
|
4828
|
+
}
|
|
4829
|
+
return;
|
|
4830
|
+
}
|
|
4831
|
+
const numValue = parseInt(value, 10);
|
|
4832
|
+
if (isNaN(numValue) || numValue < 0 || numValue > 59) {
|
|
4833
|
+
setMinute(null);
|
|
4834
|
+
onChange({ hour, minute: null, meridiem });
|
|
4835
|
+
}
|
|
4836
|
+
else if (minute !== numValue) {
|
|
4837
|
+
setMinute(numValue);
|
|
4838
|
+
onChange({ hour, minute: numValue, meridiem });
|
|
4839
|
+
}
|
|
4840
|
+
}
|
|
4841
|
+
else if (field === "meridiem") {
|
|
4842
|
+
if (value === "") {
|
|
4843
|
+
if (meridiem !== null) {
|
|
4844
|
+
setMeridiem(null);
|
|
4845
|
+
onChange({ hour, minute, meridiem: null });
|
|
4846
|
+
}
|
|
4847
|
+
return;
|
|
4848
|
+
}
|
|
4849
|
+
const lowerValue = value.toLowerCase();
|
|
4850
|
+
if (lowerValue !== "am" && lowerValue !== "pm") {
|
|
4851
|
+
if (lowerValue === "a") {
|
|
4852
|
+
setMeridiem("am");
|
|
4853
|
+
onChange({ hour, minute, meridiem: "am" });
|
|
4854
|
+
}
|
|
4855
|
+
else if (lowerValue === "p") {
|
|
4856
|
+
setMeridiem("pm");
|
|
4857
|
+
onChange({ hour, minute, meridiem: "pm" });
|
|
4858
|
+
}
|
|
4859
|
+
else {
|
|
4860
|
+
setMeridiem(null);
|
|
4861
|
+
onChange({ hour, minute, meridiem: null });
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
else if (meridiem !== lowerValue) {
|
|
4865
|
+
setMeridiem(lowerValue);
|
|
4866
|
+
onChange({ hour, minute, meridiem: lowerValue });
|
|
4867
|
+
}
|
|
4868
|
+
}
|
|
4869
|
+
};
|
|
4870
|
+
// Handle meridiem button click
|
|
4871
|
+
const handleMeridiemClick = (newMeridiem) => {
|
|
4872
|
+
setMeridiem(newMeridiem);
|
|
4873
|
+
onChange({ hour, minute, meridiem: newMeridiem });
|
|
4874
|
+
};
|
|
4875
|
+
const handleClear = () => {
|
|
4876
|
+
setHour(null);
|
|
4877
|
+
setMinute(null);
|
|
4878
|
+
setMeridiem(null);
|
|
4879
|
+
onChange({ hour: null, minute: null, meridiem: null });
|
|
4880
|
+
// Focus the hour field after clearing
|
|
4881
|
+
hourInputRef.current?.focus();
|
|
4882
|
+
};
|
|
4883
|
+
function handleFocus(event) {
|
|
4884
|
+
event.target.select();
|
|
4885
|
+
}
|
|
4886
|
+
return (jsx(Flex, { direction: "column", gap: 3, children: jsxs(Grid, { justifyContent: "center", alignItems: "center", templateColumns: "60px 10px 60px 90px auto", gap: "2", width: "auto", minWidth: "250px", children: [jsx(Input, { ref: hourInputRef, type: "text", value: hour === null ? "" : hour.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "hour"), onBlur: (e) => handleBlur(e, "hour"), onFocus: handleFocus, placeholder: "HH", maxLength: 2, textAlign: "center" }), jsx(Text, { children: ":" }), jsx(Input, { ref: minuteInputRef, type: "text", value: minute === null ? "" : minute.toString().padStart(2, "0"), onKeyDown: (e) => handleKeyDown(e, "minute"), onBlur: (e) => handleBlur(e, "minute"), onFocus: handleFocus, placeholder: "MM", maxLength: 2, textAlign: "center" }), jsxs(Flex, { gap: "1", children: [jsx(Button$1, { size: "sm", colorScheme: meridiem === "am" ? "blue" : "gray", variant: meridiem === "am" ? "solid" : "outline", onClick: () => handleMeridiemClick("am"), width: "40px", children: meridiemLabel.am }), jsx(Button$1, { size: "sm", colorScheme: meridiem === "pm" ? "blue" : "gray", variant: meridiem === "pm" ? "solid" : "outline", onClick: () => handleMeridiemClick("pm"), width: "40px", children: meridiemLabel.pm })] }), jsx(Button$1, { onClick: handleClear, size: "sm", variant: "ghost", children: jsx(MdCancel, {}) })] }) }));
|
|
4745
4887
|
}
|
|
4746
4888
|
|
|
4747
4889
|
const TimePicker = ({ column, schema, prefix }) => {
|
|
@@ -4752,7 +4894,7 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4752
4894
|
const colLabel = `${prefix}${column}`;
|
|
4753
4895
|
const [open, setOpen] = useState(false);
|
|
4754
4896
|
const value = watch(colLabel);
|
|
4755
|
-
const formatedTime = dayjs(value).format("hh:mm A");
|
|
4897
|
+
const formatedTime = value ? dayjs(value).format("hh:mm A") : "";
|
|
4756
4898
|
// Parse the initial time parts from the ISO time string (HH:mm:ss)
|
|
4757
4899
|
const parseTime = (isoTime) => {
|
|
4758
4900
|
if (!isoTime)
|
|
@@ -4781,6 +4923,8 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4781
4923
|
}, [value]);
|
|
4782
4924
|
// Convert hour, minute, meridiem to 24-hour ISO time string
|
|
4783
4925
|
const toIsoTime = (hour, minute, meridiem) => {
|
|
4926
|
+
if (hour === null || minute === null || meridiem === null)
|
|
4927
|
+
return null;
|
|
4784
4928
|
let h = hour;
|
|
4785
4929
|
if (meridiem === "am" && hour === 12)
|
|
4786
4930
|
h = 0;
|
|
@@ -4801,8 +4945,8 @@ const TimePicker = ({ column, schema, prefix }) => {
|
|
|
4801
4945
|
gridRow, children: [jsxs(Popover.Root, { open: open, onOpenChange: (e) => setOpen(e.open), closeOnInteractOutside: true, children: [jsx(Popover.Trigger, { asChild: true, children: jsxs(Button, { size: "sm", variant: "outline", onClick: () => {
|
|
4802
4946
|
setOpen(true);
|
|
4803
4947
|
}, justifyContent: "start", children: [jsx(IoMdClock, {}), value !== undefined ? `${formatedTime}` : ""] }) }), jsx(Portal, { children: jsx(Popover.Positioner, { children: jsx(Popover.Content, { ref: containerRef, children: jsx(Popover.Body, { children: jsx(TimePicker$1, { hour: hour, setHour: setHour, minute: minute, setMinute: setMinute, meridiem: meridiem, setMeridiem: setMeridiem, onChange: handleTimeChange, meridiemLabel: {
|
|
4804
|
-
am: translate.t(removeIndex(
|
|
4805
|
-
pm: translate.t(removeIndex(
|
|
4948
|
+
am: translate.t(removeIndex(`common.am`)),
|
|
4949
|
+
pm: translate.t(removeIndex(`common.pm`)),
|
|
4806
4950
|
} }) }) }) }) })] }), errors[`${column}`] && (jsx(Text, { color: "red.400", children: translate.t(removeIndex(`${colLabel}.field_required`)) }))] }));
|
|
4807
4951
|
};
|
|
4808
4952
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from "react";
|
|
1
2
|
interface TimePickerProps {
|
|
2
|
-
hour: number;
|
|
3
|
-
setHour:
|
|
4
|
-
minute: number;
|
|
5
|
-
setMinute:
|
|
6
|
-
meridiem: "am" | "pm";
|
|
7
|
-
setMeridiem:
|
|
3
|
+
hour: number | null;
|
|
4
|
+
setHour: Dispatch<SetStateAction<number | null>>;
|
|
5
|
+
minute: number | null;
|
|
6
|
+
setMinute: Dispatch<SetStateAction<number | null>>;
|
|
7
|
+
meridiem: "am" | "pm" | null;
|
|
8
|
+
setMeridiem: Dispatch<SetStateAction<"am" | "pm" | null>>;
|
|
8
9
|
onChange?: (newValue: {
|
|
9
|
-
hour: number;
|
|
10
|
-
minute: number;
|
|
11
|
-
meridiem: "am" | "pm";
|
|
10
|
+
hour: number | null;
|
|
11
|
+
minute: number | null;
|
|
12
|
+
meridiem: "am" | "pm" | null;
|
|
12
13
|
}) => void;
|
|
13
14
|
meridiemLabel?: {
|
|
14
15
|
am: string;
|