mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-01-19 03:35:11 +08:00
Fix:Some bugs (#12648)
### What problem does this PR solve? Fix: Modified and optimized the metadata condition card component. Fix: Use startOfDay and endOfDay to ensure the date range includes a full day. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -1,4 +1,3 @@
|
||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@ -18,13 +17,16 @@ import { Separator } from '@/components/ui/separator';
|
||||
import { SwitchLogicOperator, SwitchOperatorOptions } from '@/constants/agent';
|
||||
import { useBuildSwitchOperatorOptions } from '@/hooks/logic-hooks/use-build-operator-options';
|
||||
import { useFetchKnowledgeMetadata } from '@/hooks/use-knowledge-request';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { PromptEditor } from '@/pages/agent/form/components/prompt-editor';
|
||||
import { Plus, X } from 'lucide-react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useFieldArray, useFormContext, useWatch } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LogicalOperator } from '../logical-operator';
|
||||
import { Card, CardContent } from '../ui/card';
|
||||
import { InputSelect } from '../ui/input-select';
|
||||
import { RAGFlowSelect } from '../ui/select';
|
||||
|
||||
export function MetadataFilterConditions({
|
||||
kbIds,
|
||||
@ -62,13 +64,14 @@ export function MetadataFilterConditions({
|
||||
[append, fields.length, form, logic],
|
||||
);
|
||||
|
||||
const RenderField = ({
|
||||
function ConditionCards({
|
||||
fieldName,
|
||||
index,
|
||||
}: {
|
||||
fieldName: string;
|
||||
index: number;
|
||||
}) => {
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
const key = useWatch({ name: fieldName });
|
||||
const valueOptions = useMemo(() => {
|
||||
@ -83,14 +86,18 @@ export function MetadataFilterConditions({
|
||||
}, [key]);
|
||||
|
||||
return (
|
||||
<section className="flex gap-2">
|
||||
<div className="flex-1 flex flex-col gap-2 min-w-0">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="flex gap-1">
|
||||
<Card
|
||||
className={cn(
|
||||
'relative bg-transparent border-input-border border flex-1 min-w-0',
|
||||
)}
|
||||
>
|
||||
<section className="p-2 bg-bg-card flex justify-between items-center">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={fieldName}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1 overflow-hidden min-w-0">
|
||||
<FormItem className="flex-1 min-w-0">
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
@ -101,55 +108,61 @@ export function MetadataFilterConditions({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Separator className="w-1 text-text-secondary" />
|
||||
<div className="flex items-center">
|
||||
<Separator orientation="vertical" className="h-2.5" />
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`${name}.${index}.op`}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<RAGFlowSelect
|
||||
{...field}
|
||||
options={switchOperatorOptions}
|
||||
onlyShowSelectedIcon
|
||||
triggerClassName="w-30 bg-transparent border-none"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<CardContent className="p-4 ">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`${name}.${index}.op`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1 overflow-hidden min-w-0">
|
||||
name={`${name}.${index}.value`}
|
||||
render={({ field: valueField }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<SelectWithSearch
|
||||
{...field}
|
||||
options={switchOperatorOptions}
|
||||
></SelectWithSearch>
|
||||
{canReference ? (
|
||||
<PromptEditor
|
||||
{...valueField}
|
||||
multiLine={false}
|
||||
showToolbar={false}
|
||||
></PromptEditor>
|
||||
) : (
|
||||
<InputSelect
|
||||
placeholder={t('common.pleaseInput')}
|
||||
{...valueField}
|
||||
options={valueOptions}
|
||||
className="w-full"
|
||||
/>
|
||||
)}
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`${name}.${index}.value`}
|
||||
render={({ field: valueField }) => (
|
||||
<FormItem className="flex-1 overflow-hidden min-w-0">
|
||||
<FormControl>
|
||||
{canReference ? (
|
||||
<PromptEditor
|
||||
{...valueField}
|
||||
multiLine={false}
|
||||
showToolbar={false}
|
||||
></PromptEditor>
|
||||
) : (
|
||||
<InputSelect
|
||||
placeholder={t('common.pleaseInput')}
|
||||
{...valueField}
|
||||
options={valueOptions}
|
||||
className="w-full"
|
||||
/>
|
||||
)}
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Button variant={'ghost'} onClick={() => remove(index)}>
|
||||
<X className="text-text-sub-title-invert " />
|
||||
<X />
|
||||
</Button>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
return (
|
||||
<section className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
@ -177,7 +190,11 @@ export function MetadataFilterConditions({
|
||||
{fields.map((field, index) => {
|
||||
const typeField = `${name}.${index}.key`;
|
||||
return (
|
||||
<RenderField key={field.id} fieldName={typeField} index={index} />
|
||||
<ConditionCards
|
||||
key={field.id}
|
||||
fieldName={typeField}
|
||||
index={index}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@ -1,15 +1,3 @@
|
||||
import {
|
||||
endOfMonth,
|
||||
endOfYear,
|
||||
format,
|
||||
startOfMonth,
|
||||
startOfYear,
|
||||
subDays,
|
||||
subMonths,
|
||||
subYears,
|
||||
} from 'date-fns';
|
||||
import { useEffect, useId, useState } from 'react';
|
||||
|
||||
import { Calendar, DateRange } from '@/components/originui/calendar';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
@ -18,7 +6,20 @@ import {
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
import { cn } from '@/lib/utils';
|
||||
import {
|
||||
endOfDay,
|
||||
endOfMonth,
|
||||
endOfYear,
|
||||
format,
|
||||
startOfDay,
|
||||
startOfMonth,
|
||||
startOfYear,
|
||||
subDays,
|
||||
subMonths,
|
||||
subYears,
|
||||
} from 'date-fns';
|
||||
import { CalendarIcon } from 'lucide-react';
|
||||
import { useEffect, useId, useState } from 'react';
|
||||
|
||||
const CalendarComp = ({
|
||||
selectDateRange,
|
||||
@ -27,20 +28,20 @@ const CalendarComp = ({
|
||||
}: ITimeRangePickerProps) => {
|
||||
const today = new Date();
|
||||
const yesterday = {
|
||||
from: subDays(today, 1),
|
||||
to: subDays(today, 1),
|
||||
from: startOfDay(subDays(today, 1)),
|
||||
to: endOfDay(subDays(today, 1)),
|
||||
};
|
||||
const last7Days = {
|
||||
from: subDays(today, 6),
|
||||
to: today,
|
||||
from: startOfDay(subDays(today, 6)),
|
||||
to: endOfDay(today),
|
||||
};
|
||||
const last30Days = {
|
||||
from: subDays(today, 29),
|
||||
to: today,
|
||||
from: startOfDay(subDays(today, 29)),
|
||||
to: endOfDay(today),
|
||||
};
|
||||
const monthToDate = {
|
||||
from: startOfMonth(today),
|
||||
to: today,
|
||||
to: endOfDay(today),
|
||||
};
|
||||
const lastMonth = {
|
||||
from: startOfMonth(subMonths(today, 1)),
|
||||
@ -48,7 +49,7 @@ const CalendarComp = ({
|
||||
};
|
||||
const yearToDate = {
|
||||
from: startOfYear(today),
|
||||
to: today,
|
||||
to: endOfDay(today),
|
||||
};
|
||||
const lastYear = {
|
||||
from: startOfYear(subYears(today, 1)),
|
||||
@ -65,9 +66,7 @@ const CalendarComp = ({
|
||||
];
|
||||
const [month, setMonth] = useState(today);
|
||||
const [date, setDate] = useState<DateRange>(selectDateRange || last7Days);
|
||||
useEffect(() => {
|
||||
onSelect?.(date);
|
||||
}, [date, onSelect]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="rounded-md border">
|
||||
@ -80,11 +79,13 @@ const CalendarComp = ({
|
||||
size="sm"
|
||||
className="w-full justify-start"
|
||||
onClick={() => {
|
||||
setDate({
|
||||
from: today,
|
||||
to: today,
|
||||
});
|
||||
const newDateRange = {
|
||||
from: startOfDay(today),
|
||||
to: endOfDay(today),
|
||||
};
|
||||
setDate(newDateRange);
|
||||
setMonth(today);
|
||||
onSelect?.(newDateRange);
|
||||
}}
|
||||
>
|
||||
Today
|
||||
@ -98,6 +99,7 @@ const CalendarComp = ({
|
||||
onClick={() => {
|
||||
setDate(dateRange.value);
|
||||
setMonth(dateRange.value.to);
|
||||
onSelect?.(dateRange.value);
|
||||
}}
|
||||
>
|
||||
{dateRange.key}
|
||||
@ -111,7 +113,13 @@ const CalendarComp = ({
|
||||
selected={date}
|
||||
onSelect={(newDate) => {
|
||||
if (newDate) {
|
||||
setDate(newDate as DateRange);
|
||||
const dateRange = newDate as DateRange;
|
||||
const newDateRange = {
|
||||
from: startOfDay(dateRange.from),
|
||||
to: dateRange.to ? endOfDay(dateRange.to) : undefined,
|
||||
};
|
||||
setDate(newDateRange);
|
||||
onSelect?.(newDateRange);
|
||||
}
|
||||
}}
|
||||
month={month}
|
||||
@ -130,7 +138,7 @@ const CalendarComp = ({
|
||||
|
||||
export type ITimeRangePickerProps = {
|
||||
onSelect: (e: DateRange) => void;
|
||||
selectDateRange: DateRange;
|
||||
selectDateRange?: DateRange;
|
||||
className?: string;
|
||||
};
|
||||
const TimeRangePicker = ({
|
||||
@ -140,11 +148,40 @@ const TimeRangePicker = ({
|
||||
}: ITimeRangePickerProps) => {
|
||||
const id = useId();
|
||||
const today = new Date();
|
||||
|
||||
// Initialize without timezone conversion
|
||||
const [date, setDate] = useState<DateRange | undefined>(
|
||||
selectDateRange || { from: today, to: today },
|
||||
selectDateRange
|
||||
? {
|
||||
from: startOfDay(selectDateRange.from),
|
||||
to: selectDateRange.to ? endOfDay(selectDateRange.to) : undefined,
|
||||
}
|
||||
: {
|
||||
from: startOfDay(today),
|
||||
to: endOfDay(today),
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setDate(selectDateRange);
|
||||
if (!selectDateRange || !selectDateRange.from) return;
|
||||
|
||||
try {
|
||||
const fromDate = new Date(selectDateRange.from);
|
||||
const toDate = selectDateRange.to
|
||||
? new Date(selectDateRange.to)
|
||||
: undefined;
|
||||
|
||||
if (isNaN(fromDate.getTime())) return;
|
||||
|
||||
if (toDate && isNaN(toDate.getTime())) return;
|
||||
|
||||
setDate({
|
||||
from: startOfDay(fromDate),
|
||||
to: toDate ? endOfDay(toDate) : undefined,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error updating date range from props:', error);
|
||||
}
|
||||
}, [selectDateRange]);
|
||||
const onChange = (e: DateRange | undefined) => {
|
||||
if (!e) return;
|
||||
|
||||
Reference in New Issue
Block a user