Feat: Filter document by running status and file type. #3221 (#7340)

### What problem does this PR solve?
Feat: Filter document by running status and file type. #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-04-27 14:39:05 +08:00
committed by GitHub
parent dadd8d9f94
commit bdebd1b2e3
17 changed files with 392 additions and 76 deletions

View File

@ -281,7 +281,10 @@ export function ChunkMethodDialog({
)}
/>
)}
<DatasetConfigurationContainer show={showOne || showMaxTokenNumber}>
<DatasetConfigurationContainer
show={showOne || showMaxTokenNumber}
className="space-y-3"
>
{showOne && <LayoutRecognizeFormField></LayoutRecognizeFormField>}
{showMaxTokenNumber && (
<>
@ -298,6 +301,7 @@ export function ChunkMethodDialog({
</DatasetConfigurationContainer>
<DatasetConfigurationContainer
show={showAutoKeywords(selectedTag) || showExcelToHtml}
className="space-y-3"
>
{showAutoKeywords(selectedTag) && (
<>

View File

@ -0,0 +1,163 @@
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
import { zodResolver } from '@hookform/resolvers/zod';
import { PropsWithChildren, useCallback, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { ZodArray, ZodString, z } from 'zod';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { FilterChange, FilterCollection, FilterValue } from './interface';
export type CheckboxFormMultipleProps = {
filters?: FilterCollection[];
value?: FilterValue;
onChange?: FilterChange;
};
function CheckboxFormMultiple({
filters = [],
value,
onChange,
}: CheckboxFormMultipleProps) {
const fieldsDict = filters?.reduce<Record<string, Array<any>>>((pre, cur) => {
pre[cur.field] = [];
return pre;
}, {});
const FormSchema = z.object(
filters.reduce<Record<string, ZodArray<ZodString, 'many'>>>((pre, cur) => {
pre[cur.field] = z.array(z.string());
// .refine((value) => value.some((item) => item), {
// message: 'You have to select at least one item.',
// });
return pre;
}, {}),
);
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: fieldsDict,
});
function onSubmit(data: z.infer<typeof FormSchema>) {
console.log('🚀 ~ onSubmit ~ data:', data);
// setOwnerIds(data.items);
onChange?.(data);
}
const onReset = useCallback(() => {
onChange?.(fieldsDict);
}, [fieldsDict, onChange]);
useEffect(() => {
form.reset(value);
}, [form, value]);
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8"
onReset={() => form.reset()}
>
{filters.map((x) => (
<FormField
key={x.field}
control={form.control}
name={x.field}
render={() => (
<FormItem>
<div className="mb-4">
<FormLabel className="text-base">{x.label}</FormLabel>
</div>
{x.list.map((item) => (
<FormField
key={item.id}
control={form.control}
name={x.field}
render={({ field }) => {
return (
<div className="flex items-center justify-between">
<FormItem
key={item.id}
className="flex flex-row space-x-3 space-y-0 items-center"
>
<FormControl>
<Checkbox
checked={field.value?.includes(item.id)}
onCheckedChange={(checked) => {
return checked
? field.onChange([...field.value, item.id])
: field.onChange(
field.value?.filter(
(value) => value !== item.id,
),
);
}}
/>
</FormControl>
<FormLabel className="text-lg">
{item.label}
</FormLabel>
</FormItem>
<span className=" text-sm">{item.count}</span>
</div>
);
}}
/>
))}
<FormMessage />
</FormItem>
)}
/>
))}
<div className="flex justify-between">
<Button
type="button"
variant={'outline'}
size={'sm'}
onClick={onReset}
>
Clear
</Button>
<Button type="submit" size={'sm'}>
Submit
</Button>
</div>
</form>
</Form>
);
}
export function FilterPopover({
children,
value,
onChange,
filters,
}: PropsWithChildren & CheckboxFormMultipleProps) {
return (
<Popover>
<PopoverTrigger asChild>{children}</PopoverTrigger>
<PopoverContent>
<CheckboxFormMultiple
onChange={onChange}
value={value}
filters={filters}
></CheckboxFormMultiple>
</PopoverContent>
</Popover>
);
}

View File

@ -1,19 +1,18 @@
import { ChevronDown } from 'lucide-react';
import React, {
ChangeEventHandler,
FunctionComponent,
PropsWithChildren,
ReactNode,
useMemo,
} from 'react';
import { Button, ButtonProps } from './ui/button';
import { SearchInput } from './ui/input';
import { Button, ButtonProps } from '../ui/button';
import { SearchInput } from '../ui/input';
import { CheckboxFormMultipleProps, FilterPopover } from './filter-popover';
interface IProps {
title?: string;
FilterPopover?: FunctionComponent<any>;
searchString?: string;
onSearchChange?: ChangeEventHandler<HTMLInputElement>;
count?: number;
showFilter?: boolean;
leftPanel?: ReactNode;
}
@ -32,25 +31,31 @@ const FilterButton = React.forwardRef<
export default function ListFilterBar({
title,
children,
FilterPopover,
searchString,
onSearchChange,
count,
showFilter = true,
leftPanel,
}: PropsWithChildren<IProps>) {
value,
onChange,
filters,
}: PropsWithChildren<IProps & CheckboxFormMultipleProps>) {
const filterCount = useMemo(() => {
return typeof value === 'object' && value !== null
? Object.values(value).reduce((pre, cur) => {
return pre + cur.length;
}, 0)
: 0;
}, [value]);
return (
<div className="flex justify-between mb-6 items-center">
<span className="text-3xl font-bold ">{leftPanel || title}</span>
<div className="flex gap-4 items-center">
{showFilter &&
(FilterPopover ? (
<FilterPopover>
<FilterButton count={count}></FilterButton>
</FilterPopover>
) : (
<FilterButton></FilterButton>
))}
{showFilter && (
<FilterPopover value={value} onChange={onChange} filters={filters}>
<FilterButton count={filterCount}></FilterButton>
</FilterPopover>
)}
<SearchInput
value={searchString}

View File

@ -0,0 +1,15 @@
export type FilterType = {
id: string;
label: string;
count: number;
};
export type FilterCollection = {
field: string;
label: string;
list: FilterType[];
};
export type FilterValue = Record<string, Array<string>>;
export type FilterChange = (value: FilterValue) => void;

View File

@ -0,0 +1,12 @@
import { useCallback, useState } from 'react';
import { FilterChange, FilterValue } from './interface';
export function useHandleFilterSubmit() {
const [filterValue, setFilterValue] = useState<FilterValue>({});
const handleFilterSubmit: FilterChange = useCallback((value) => {
setFilterValue(value);
}, []);
return { filterValue, setFilterValue, handleFilterSubmit };
}

View File

@ -76,7 +76,7 @@ const RaptorFormFields = () => {
)}
/>
{useRaptor && (
<>
<div className="space-y-3">
<FormField
control={form.control}
name={'parser_config.raptor.prompt'}
@ -137,7 +137,7 @@ const RaptorFormFields = () => {
</FormItem>
)}
/>
</>
</div>
)}
</>
);