From 11470906cfaa0112cb7595641d5cfd6b4c04868c Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Fri, 23 Jan 2026 16:55:43 +0800 Subject: [PATCH] Fix: Metadata time Picker (#12796) ### What problem does this PR solve? Fix: Metadata time Picker ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- web/src/components/ui/input-date.tsx | 75 ++++++++++++++----- web/src/components/ui/popover.tsx | 18 ++++- web/src/components/ui/time-picker.tsx | 73 +++++++++--------- .../metedata/manage-modal-column.tsx | 54 ++++++++----- 4 files changed, 143 insertions(+), 77 deletions(-) diff --git a/web/src/components/ui/input-date.tsx b/web/src/components/ui/input-date.tsx index 101e582b8..0cf091307 100644 --- a/web/src/components/ui/input-date.tsx +++ b/web/src/components/ui/input-date.tsx @@ -10,6 +10,8 @@ import { Locale } from 'date-fns'; import dayjs from 'dayjs'; import { Calendar as CalendarIcon } from 'lucide-react'; import * as React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button } from './button'; import { TimePicker } from './time-picker'; // import TimePicker from 'react-time-picker'; interface DateInputProps extends Omit< @@ -22,9 +24,8 @@ interface DateInputProps extends Omit< dateFormat?: string; timeFormat?: string; showTimeSelectOnly?: boolean; - showTimeInput?: boolean; - timeInputLabel?: string; locale?: Locale; // Support for internationalization + openChange?: (open: boolean) => void; } const DateInput = React.forwardRef( @@ -37,41 +38,45 @@ const DateInput = React.forwardRef( timeFormat = 'HH:mm:ss', showTimeSelect = false, showTimeSelectOnly = false, - showTimeInput = false, - timeInputLabel = '', + openChange, ...props }, ref, ) => { + const { t } = useTranslation(); + const [selectedDate, setSelectedDate] = React.useState( + value, + ); const [open, setOpen] = React.useState(false); const handleDateSelect = (date: Date | undefined) => { - if (value) { - const valueDate = dayjs(value); + if (selectedDate) { + const valueDate = dayjs(selectedDate); date?.setHours(valueDate.hour()); date?.setMinutes(valueDate.minute()); date?.setSeconds(valueDate.second()); } - onChange?.(date); - // setOpen(false); + setSelectedDate(date); + // onChange?.(date); }; const handleTimeSelect = (date: Date | undefined) => { - const valueDate = dayjs(value); - if (value) { + const valueDate = dayjs(selectedDate); + if (selectedDate) { date?.setFullYear(valueDate.year()); date?.setMonth(valueDate.month()); date?.setDate(valueDate.date()); } if (date) { - onChange?.(date); + // onChange?.(date); + setSelectedDate(date); } else { valueDate?.hour(0); valueDate?.minute(0); valueDate?.second(0); - onChange?.(valueDate.toDate()); + // onChange?.(valueDate.toDate()); + setSelectedDate(valueDate.toDate()); } - // setOpen(false); }; // Determine display format based on the type of date picker @@ -84,14 +89,23 @@ const DateInput = React.forwardRef( // Format the date according to the specified format const formattedValue = React.useMemo(() => { - return value && !isNaN(value.getTime()) - ? dayjs(value).format(displayFormat) + return selectedDate && !isNaN(selectedDate.getTime()) + ? dayjs(selectedDate).format(displayFormat) : ''; - }, [value, displayFormat]); + }, [selectedDate, displayFormat]); + + const handleOpenChange = (open: boolean) => { + setOpen(open); + openChange?.(open); + }; return (
- +
( {showTimeSelect && ( { handleTimeSelect(value); }} @@ -126,6 +140,29 @@ const DateInput = React.forwardRef( /> // )} +
+ + +
diff --git a/web/src/components/ui/popover.tsx b/web/src/components/ui/popover.tsx index 562329e5e..9ec1057ca 100644 --- a/web/src/components/ui/popover.tsx +++ b/web/src/components/ui/popover.tsx @@ -5,20 +5,32 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -const Popover = (props: PopoverPrimitive.PopoverProps) => { - const { children, open: openState, onOpenChange } = props; +interface PopoverProps extends PopoverPrimitive.PopoverProps { + disableOutsideClick?: boolean; +} + +const Popover = ({ + children, + open: openState, + onOpenChange, + disableOutsideClick = false, +}: PopoverProps) => { const [open, setOpen] = React.useState(true); React.useEffect(() => { setOpen(!!openState); }, [openState]); const handleOnOpenChange = React.useCallback( (e: boolean) => { + if (disableOutsideClick && !e) { + return; + } + if (onOpenChange) { onOpenChange?.(e); } setOpen(e); }, - [onOpenChange], + [onOpenChange, disableOutsideClick], ); return ( diff --git a/web/src/components/ui/time-picker.tsx b/web/src/components/ui/time-picker.tsx index e782c1e87..48e238f42 100644 --- a/web/src/components/ui/time-picker.tsx +++ b/web/src/components/ui/time-picker.tsx @@ -153,7 +153,7 @@ const TimePicker = forwardRef( bordered = true, disabledTime, hideDisabledOptions = false, - inputReadOnly = false, + inputReadOnly = true, use12Hours = false, size = 'middle', status, @@ -495,47 +495,48 @@ const TimePicker = forwardRef( onOpenChange={handleOpenChange} modal={false} // Use non-modal dialog box, consistent with Ant Design behavior > -
- -
- {allowClear && value && inputValue && ( - - )} - + +
+ +
+ {allowClear && value && inputValue && ( + + )} +
{suffixIcon || ( )}
- +
-
+ { - if (editingValue) { - setTableData((prev) => { - return prev.map((row) => { - if (row.field === editingValue.field) { - const updatedValues = row.values.map((v) => - v === editingValue.value ? editingValue.newValue : v, - ); - return { ...row, values: updatedValues }; - } - return row; + const saveEditedValue = useCallback( + (newValue?: { field: string; value: string; newValue: string }) => { + const realValue = newValue || editingValue; + if (realValue) { + setTableData((prev) => { + return prev.map((row) => { + if (row.field === realValue.field) { + const updatedValues = row.values.map((v) => + v === realValue.value ? realValue.newValue : v, + ); + return { ...row, values: updatedValues }; + } + return row; + }); }); - }); - setEditingValue(null); - setShouldSave(true); - } - }, [editingValue, setTableData, setShouldSave]); + setEditingValue(null); + setShouldSave(true); + } + }, + [editingValue, setTableData, setShouldSave], + ); const cancelEditValue = () => { setEditingValue(null); @@ -214,15 +218,23 @@ export const useMetadataColumns = ({ { - setEditingValue({ + console.log('value', value); + const newValue = { ...editingValue, newValue: formatDate( value, 'YYYY-MM-DDTHH:mm:ss', ), - }); + }; + setEditingValue(newValue); + saveEditedValue(newValue); // onValueChange(index, formatDate(value), true); }} + // openChange={(open) => { + // console.log('open', open); + // if (!open) { + // } + // }} showTimeSelect={true} /> )} @@ -261,7 +273,11 @@ export const useMetadataColumns = ({ aria-label="Edit" >
-
{value}
+
+ {row.original.valueType === metadataValueTypeEnum.time + ? formatDate(value, 'DD/MM/YYYY HH:mm:ss') + : value} +
{isDeleteSingleValue && (