Fix: Fixed the issue where agent log time could not be selected. (#13756)

### What problem does this PR solve?
Fix: Fixed the issue where agent log time could not be selected.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
balibabu
2026-03-24 16:02:26 +08:00
committed by GitHub
parent 9eb11bf65d
commit 48c60b8ce5
4 changed files with 375 additions and 72 deletions

View File

@ -0,0 +1,233 @@
'use client';
import * as React from 'react';
import {
DayPicker,
getDefaultClassNames,
type DayButton,
type Locale,
} from 'react-day-picker';
import { Button, buttonVariants } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from 'lucide-react';
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = 'label',
buttonVariant = 'ghost',
locale,
formatters,
components,
...props
}: React.ComponentProps<typeof DayPicker> & {
buttonVariant?: React.ComponentProps<typeof Button>['variant'];
}) {
const defaultClassNames = getDefaultClassNames();
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn(
'p-3 [--cell-radius:var(--radius)] [--cell-size:2.25rem] group/calendar bg-background',
className,
)}
captionLayout={captionLayout}
locale={locale}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString(locale?.code, { month: 'short' }),
...formatters,
}}
classNames={{
root: cn('w-fit', defaultClassNames.root),
months: cn(
'relative flex flex-col gap-4 md:flex-row',
defaultClassNames.months,
),
month: cn('flex w-full flex-col gap-4', defaultClassNames.month),
nav: cn(
'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1',
defaultClassNames.nav,
),
button_previous: cn(
buttonVariants({ variant: buttonVariant }),
'w-[var(--cell-size)] h-[var(--cell-size)] p-0 select-none aria-disabled:opacity-50',
defaultClassNames.button_previous,
),
button_next: cn(
buttonVariants({ variant: buttonVariant }),
'w-[var(--cell-size)] h-[var(--cell-size)] p-0 select-none aria-disabled:opacity-50',
defaultClassNames.button_next,
),
month_caption: cn(
'flex h-[var(--cell-size)] w-full items-center justify-center px-[var(--cell-size)]',
defaultClassNames.month_caption,
),
dropdowns: cn(
'flex h-[var(--cell-size)] w-full items-center justify-center gap-1.5 text-sm font-medium',
defaultClassNames.dropdowns,
),
dropdown_root: cn(
'cn-calendar-dropdown-root relative rounded-[var(--cell-radius)]',
defaultClassNames.dropdown_root,
),
dropdown: cn(
'absolute inset-0 bg-popover opacity-0',
defaultClassNames.dropdown,
),
caption_label: cn(
'font-medium select-none',
captionLayout === 'label'
? 'text-sm'
: 'cn-calendar-caption-label flex items-center gap-1 rounded-[var(--cell-radius)] text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground',
defaultClassNames.caption_label,
),
table: 'w-full border-collapse',
weekdays: cn('flex', defaultClassNames.weekdays),
weekday: cn(
'flex-1 rounded-[var(--cell-radius)] text-[0.8rem] font-normal text-muted-foreground select-none',
defaultClassNames.weekday,
),
week: cn('mt-2 flex w-full', defaultClassNames.week),
week_number_header: cn(
'w-[var(--cell-size)] select-none',
defaultClassNames.week_number_header,
),
week_number: cn(
'text-[0.8rem] text-muted-foreground select-none',
defaultClassNames.week_number,
),
day: cn(
'group/day relative aspect-square h-full w-full rounded-[var(--cell-radius)] p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-[var(--cell-radius)]',
props.showWeekNumber
? '[&:nth-child(2)[data-selected=true]_button]:rounded-l-[var(--cell-radius)]'
: '[&:first-child[data-selected=true]_button]:rounded-l-[var(--cell-radius)]',
defaultClassNames.day,
),
range_start: cn(
'relative isolate z-0 rounded-l-[var(--cell-radius)] bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted',
defaultClassNames.range_start,
),
range_middle: cn('rounded-none', defaultClassNames.range_middle),
range_end: cn(
'relative isolate z-0 rounded-r-[var(--cell-radius)] bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted',
defaultClassNames.range_end,
),
today: cn(
'rounded-[var(--cell-radius)] bg-muted text-foreground data-[selected=true]:rounded-none',
defaultClassNames.today,
),
outside: cn(
'text-muted-foreground aria-selected:text-muted-foreground',
defaultClassNames.outside,
),
disabled: cn(
'text-muted-foreground opacity-50',
defaultClassNames.disabled,
),
hidden: cn('invisible', defaultClassNames.hidden),
...classNames,
}}
components={{
Root: ({ className, rootRef, ...props }) => {
return (
<div
data-slot="calendar"
ref={rootRef}
className={cn(className)}
{...props}
/>
);
},
Chevron: ({ className, orientation, ...props }) => {
if (orientation === 'left') {
return (
<ChevronLeftIcon className={cn('size-4', className)} {...props} />
);
}
if (orientation === 'right') {
return (
<ChevronRightIcon
className={cn('size-4', className)}
{...props}
/>
);
}
return (
<ChevronDownIcon className={cn('size-4', className)} {...props} />
);
},
DayButton: ({ ...props }) => (
<CalendarDayButton locale={locale} {...props} />
),
WeekNumber: ({ children, ...props }) => {
return (
<td {...props}>
<div className="flex w-[var(--cell-size)] h-[var(--cell-size)] items-center justify-center text-center">
{children}
</div>
</td>
);
},
...components,
}}
{...props}
/>
);
}
function CalendarDayButton({
className,
day,
modifiers,
locale,
...props
}: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
const defaultClassNames = getDefaultClassNames();
const ref = React.useRef<HTMLButtonElement>(null);
React.useEffect(() => {
if (modifiers.focused) ref.current?.focus();
}, [modifiers.focused]);
return (
<Button
ref={ref}
variant="ghost"
size="icon"
data-day={day.date.toLocaleDateString(locale?.code)}
data-selected-single={
modifiers.selected &&
!modifiers.range_start &&
!modifiers.range_end &&
!modifiers.range_middle
}
data-range-start={modifiers.range_start}
data-range-end={modifiers.range_end}
data-range-middle={modifiers.range_middle}
className={cn(
'relative isolate z-10 flex aspect-square size-auto w-full min-w-[var(--cell-size)] flex-col gap-1 border-0 leading-none font-normal',
'group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50',
'data-[range-end=true]:rounded-[var(--cell-radius)] data-[range-end=true]:rounded-r-[var(--cell-radius)] data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground',
'data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground',
'data-[range-start=true]:rounded-[var(--cell-radius)] data-[range-start=true]:rounded-l-[var(--cell-radius)] data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground',
'data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground',
'dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70',
defaultClassNames.day,
className,
)}
{...props}
/>
);
}
export { Calendar, CalendarDayButton };

View File

@ -0,0 +1,57 @@
'use client';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
import { format } from 'date-fns';
import { CalendarIcon } from 'lucide-react';
import { PropsRangeRequired } from 'react-day-picker';
export function DatePickerWithRange({
selected,
...props
}: Omit<PropsRangeRequired, 'mode'>) {
// const [date, setDate] = React.useState<DateRange | undefined>({
// from: new Date(new Date().getFullYear(), 0, 20),
// to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),
// });
return (
<Popover>
<PopoverTrigger asChild>
<Button
variant="outline"
id="date-picker-range"
className="justify-start px-2.5 font-normal"
>
<CalendarIcon />
{selected?.from ? (
selected.to ? (
<>
{format(selected.from, 'LLL dd, y')} -{' '}
{format(selected.to, 'LLL dd, y')}
</>
) : (
format(selected.from, 'LLL dd, y')
)
) : (
<span>Pick a date</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="range"
selected={selected}
// defaultMonth={date?.from}
numberOfMonths={2}
{...props}
/>
</PopoverContent>
</Popover>
);
}