mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Fix: Bug fixes and removed previous settings page code - Modified the default text color class name in the FileStatusBadge component - Adjusted the FilterType interface definition for ListFilterBar to support JSX labels and an optional count field - Removed redundant changeRaptor callback functions and comment blocks in RaptorFormFields - Corrected the isHorizontal check logic in SliderInputFormField - Optimized the Command component's scrolling behavior and enhanced its event handling - Adjusted the TooltipContent style to support automatic scrollbar display - Removed the old settings page ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: jinhai <haijin.chn@gmail.com> Signed-off-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: balibabu <cike8899@users.noreply.github.com> Co-authored-by: Kevin Hu <kevinhu.sh@gmail.com> Co-authored-by: Lynn <lynn_inf@hotmail.com> Co-authored-by: 纷繁下的无奈 <zhileihuang@126.com> Co-authored-by: huangzl <huangzl@shinemo.com> Co-authored-by: writinwaters <93570324+writinwaters@users.noreply.github.com> Co-authored-by: Wilmer <33392318@qq.com> Co-authored-by: Adrian Weidig <adrianweidig@gmx.net> Co-authored-by: Zhichang Yu <yuzhichang@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Yongteng Lei <yongtengrey@outlook.com> Co-authored-by: Liu An <asiro@qq.com> Co-authored-by: buua436 <66937541+buua436@users.noreply.github.com> Co-authored-by: BadwomanCraZY <511528396@qq.com> Co-authored-by: cucusenok <31804608+cucusenok@users.noreply.github.com> Co-authored-by: Russell Valentine <russ@coldstonelabs.org> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Billy Bao <newyorkupperbay@gmail.com> Co-authored-by: Zhedong Cen <cenzhedong2@126.com> Co-authored-by: TensorNull <129579691+TensorNull@users.noreply.github.com> Co-authored-by: TensorNull <tensor.null@gmail.com> Co-authored-by: TeslaZY <TeslaZY@outlook.com> Co-authored-by: Ajay <160579663+aybanda@users.noreply.github.com> Co-authored-by: AB <aj@Ajays-MacBook-Air.local> Co-authored-by: 天海蒼灆 <huangaoqin@tecpie.com> Co-authored-by: He Wang <wanghechn@qq.com> Co-authored-by: Atsushi Hatakeyama <atu729@icloud.com> Co-authored-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: Mohamed Mathari <155896313+melmathari@users.noreply.github.com> Co-authored-by: Mohamed Mathari <nocodeventure@Mac-mini-van-Mohamed.fritz.box> Co-authored-by: Stephen Hu <stephenhu@seismic.com> Co-authored-by: Shaun Zhang <zhangwfjh@users.noreply.github.com> Co-authored-by: zhimeng123 <60221886+zhimeng123@users.noreply.github.com> Co-authored-by: mxc <mxc@example.com> Co-authored-by: Dominik Novotný <50611433+SgtMarmite@users.noreply.github.com> Co-authored-by: EVGENY M <168018528+rjohny55@users.noreply.github.com> Co-authored-by: mcoder6425 <mcoder64@gmail.com> Co-authored-by: lemsn <lemsn@msn.com> Co-authored-by: lemsn <lemsn@126.com> Co-authored-by: Adrian Gora <47756404+adagora@users.noreply.github.com> Co-authored-by: Womsxd <45663319+Womsxd@users.noreply.github.com> Co-authored-by: FatMii <39074672+FatMii@users.noreply.github.com>
This commit is contained in:
@ -26,7 +26,7 @@ const FileStatusBadge: FC<StatusBadgeProps> = ({ status, name }) => {
|
|||||||
case RunningStatus.UNSTART:
|
case RunningStatus.UNSTART:
|
||||||
return `bg-[rgba(250,173,20,0.1)] text-state-warning`;
|
return `bg-[rgba(250,173,20,0.1)] text-state-warning`;
|
||||||
default:
|
default:
|
||||||
return 'bg-gray-500/10 text-white';
|
return 'bg-gray-500/10 text-text-secondary';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ const FileStatusBadge: FC<StatusBadgeProps> = ({ status, name }) => {
|
|||||||
case RunningStatus.UNSTART:
|
case RunningStatus.UNSTART:
|
||||||
return `bg-[rgba(250,173,20,1)] text-state-warning`;
|
return `bg-[rgba(250,173,20,1)] text-state-warning`;
|
||||||
default:
|
default:
|
||||||
return 'bg-gray-500/10 text-white';
|
return `bg-[rgba(117,120,122,1)] text-text-secondary`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
export type FilterType = {
|
export type FilterType = {
|
||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string | JSX.Element;
|
||||||
count: number;
|
count?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FilterCollection = {
|
export type FilterCollection = {
|
||||||
|
|||||||
@ -67,19 +67,6 @@ const RaptorFormFields = ({
|
|||||||
const { t } = useTranslate('knowledgeConfiguration');
|
const { t } = useTranslate('knowledgeConfiguration');
|
||||||
const useRaptor = useWatch({ name: UseRaptorField });
|
const useRaptor = useWatch({ name: UseRaptorField });
|
||||||
|
|
||||||
const changeRaptor = useCallback(
|
|
||||||
(isUseRaptor: boolean) => {
|
|
||||||
if (isUseRaptor) {
|
|
||||||
form.setValue(MaxTokenField, 256);
|
|
||||||
form.setValue(ThresholdField, 0.1);
|
|
||||||
form.setValue(MaxCluster, 64);
|
|
||||||
form.setValue(RandomSeedField, 0);
|
|
||||||
form.setValue(Prompt, t('promptText'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[form],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleGenerate = useCallback(() => {
|
const handleGenerate = useCallback(() => {
|
||||||
form.setValue(RandomSeedField, random(10000));
|
form.setValue(RandomSeedField, random(10000));
|
||||||
}, [form]);
|
}, [form]);
|
||||||
@ -90,10 +77,6 @@ const RaptorFormFields = ({
|
|||||||
control={form.control}
|
control={form.control}
|
||||||
name={UseRaptorField}
|
name={UseRaptorField}
|
||||||
render={({ field }) => {
|
render={({ field }) => {
|
||||||
// if (typeof field.value === 'undefined') {
|
|
||||||
// // default value set
|
|
||||||
// form.setValue('parser_config.raptor.use_raptor', false);
|
|
||||||
// }
|
|
||||||
return (
|
return (
|
||||||
<FormItem
|
<FormItem
|
||||||
defaultChecked={false}
|
defaultChecked={false}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export function SliderInputFormField({
|
|||||||
}: SliderInputFormFieldProps) {
|
}: SliderInputFormFieldProps) {
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
|
|
||||||
const isHorizontal = useMemo(() => layout === FormLayout.Vertical, [layout]);
|
const isHorizontal = useMemo(() => layout !== FormLayout.Vertical, [layout]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormField
|
<FormField
|
||||||
|
|||||||
@ -26,7 +26,7 @@ Command.displayName = CommandPrimitive.displayName;
|
|||||||
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
||||||
return (
|
return (
|
||||||
<Dialog {...props}>
|
<Dialog {...props}>
|
||||||
<DialogContent className="overflow-hidden p-0 shadow-lg">
|
<DialogContent className="overflow-auto p-0 shadow-lg">
|
||||||
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||||
{children}
|
{children}
|
||||||
</Command>
|
</Command>
|
||||||
@ -58,9 +58,18 @@ const CommandList = React.forwardRef<
|
|||||||
React.ElementRef<typeof CommandPrimitive.List>,
|
React.ElementRef<typeof CommandPrimitive.List>,
|
||||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
||||||
>(({ className, ...props }, ref) => (
|
>(({ className, ...props }, ref) => (
|
||||||
|
/**
|
||||||
|
* Solve the problem of the scroll wheel not working
|
||||||
|
* onWheel={(e) => e.stopPropagation()}
|
||||||
|
onMouseEnter={(e) => e.currentTarget.focus()}
|
||||||
|
tabIndex={-1}
|
||||||
|
*/
|
||||||
<CommandPrimitive.List
|
<CommandPrimitive.List
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
|
className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
|
||||||
|
onWheel={(e) => e.stopPropagation()}
|
||||||
|
onMouseEnter={(e) => e.currentTarget.focus()}
|
||||||
|
tabIndex={-1}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|||||||
@ -20,7 +20,7 @@ const TooltipContent = React.forwardRef<
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={cn(
|
className={cn(
|
||||||
'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-w-[20vw]',
|
'z-50 overflow-auto scrollbar-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-w-[20vw]',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@ -48,9 +48,10 @@ export const ObjectContainer = (props: IObjContainerProps) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeEditIndex !== undefined && editDivRef.current) {
|
if (activeEditIndex !== undefined && editDivRef.current) {
|
||||||
editDivRef.current.focus();
|
editDivRef.current.focus();
|
||||||
editDivRef.current.textContent = content.value;
|
editDivRef.current.textContent = content.value as string;
|
||||||
|
editDivRef.current.style.whiteSpace = 'pre-wrap';
|
||||||
}
|
}
|
||||||
}, [activeEditIndex, content]);
|
}, [activeEditIndex, content, editDivRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -33,7 +33,8 @@ const useFetchFileLogList = () => {
|
|||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const { searchString, handleInputChange } = useHandleSearchChange();
|
const { searchString, handleInputChange } = useHandleSearchChange();
|
||||||
const { pagination, setPagination } = useGetPaginationWithRouter();
|
const { pagination, setPagination } = useGetPaginationWithRouter();
|
||||||
const { filterValue, handleFilterSubmit } = useHandleFilterSubmit();
|
const { filterValue, setFilterValue, handleFilterSubmit } =
|
||||||
|
useHandleFilterSubmit();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const [active, setActive] = useState<(typeof LogTabs)[keyof typeof LogTabs]>(
|
const [active, setActive] = useState<(typeof LogTabs)[keyof typeof LogTabs]>(
|
||||||
LogTabs.FILE_LOGS,
|
LogTabs.FILE_LOGS,
|
||||||
@ -89,6 +90,7 @@ const useFetchFileLogList = () => {
|
|||||||
active,
|
active,
|
||||||
setActive,
|
setActive,
|
||||||
filterValue,
|
filterValue,
|
||||||
|
setFilterValue,
|
||||||
handleFilterSubmit,
|
handleFilterSubmit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
|
import FileStatusBadge from '@/components/file-status-badge';
|
||||||
import { FilterCollection } from '@/components/list-filter-bar/interface';
|
import { FilterCollection } from '@/components/list-filter-bar/interface';
|
||||||
import SvgIcon from '@/components/svg-icon';
|
import SvgIcon from '@/components/svg-icon';
|
||||||
import { useIsDarkTheme } from '@/components/theme-provider';
|
import { useIsDarkTheme } from '@/components/theme-provider';
|
||||||
import { AntToolTip } from '@/components/ui/tooltip';
|
import { AntToolTip } from '@/components/ui/tooltip';
|
||||||
|
import { RunningStatusMap } from '@/constants/knowledge';
|
||||||
import { useFetchDocumentList } from '@/hooks/use-document-request';
|
import { useFetchDocumentList } from '@/hooks/use-document-request';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { CircleQuestionMark } from 'lucide-react';
|
import { CircleQuestionMark } from 'lucide-react';
|
||||||
import { FC, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RunningStatus, RunningStatusMap } from '../dataset/constant';
|
import { RunningStatus } from '../dataset/constant';
|
||||||
import { LogTabs } from './dataset-common';
|
import { LogTabs } from './dataset-common';
|
||||||
import { DatasetFilter } from './dataset-filter';
|
import { DatasetFilter } from './dataset-filter';
|
||||||
import { useFetchFileLogList, useFetchOverviewTital } from './hook';
|
import { useFetchFileLogList, useFetchOverviewTital } from './hook';
|
||||||
@ -84,34 +85,6 @@ const CardFooterProcess: FC<CardFooterProcessProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const filters = [
|
|
||||||
{
|
|
||||||
field: 'operation_status',
|
|
||||||
label: t('knowledgeDetails.status'),
|
|
||||||
list: Object.values(RunningStatus).map((value) => {
|
|
||||||
// const value = key as RunningStatus;
|
|
||||||
console.log(value);
|
|
||||||
return {
|
|
||||||
id: value,
|
|
||||||
label: RunningStatusMap[value].label,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'types',
|
|
||||||
label: t('knowledgeDetails.task'),
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
id: 'Parse',
|
|
||||||
label: 'Parse',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Download',
|
|
||||||
label: 'Download',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const FileLogsPage: FC = () => {
|
const FileLogsPage: FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -169,10 +142,56 @@ const FileLogsPage: FC = () => {
|
|||||||
setPagination,
|
setPagination,
|
||||||
active,
|
active,
|
||||||
filterValue,
|
filterValue,
|
||||||
|
setFilterValue,
|
||||||
handleFilterSubmit,
|
handleFilterSubmit,
|
||||||
setActive,
|
setActive,
|
||||||
} = useFetchFileLogList();
|
} = useFetchFileLogList();
|
||||||
|
|
||||||
|
const filters = useMemo(() => {
|
||||||
|
const filterCollection: FilterCollection[] = [
|
||||||
|
{
|
||||||
|
field: 'operation_status',
|
||||||
|
label: t('knowledgeDetails.status'),
|
||||||
|
list: Object.values(RunningStatus).map((value) => {
|
||||||
|
// const value = key as RunningStatus;
|
||||||
|
console.log(value);
|
||||||
|
return {
|
||||||
|
id: value,
|
||||||
|
// label: RunningStatusMap[value].label,
|
||||||
|
label: (
|
||||||
|
<FileStatusBadge
|
||||||
|
status={value as RunningStatus}
|
||||||
|
name={RunningStatusMap[value as RunningStatus]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// field: 'types',
|
||||||
|
// label: t('knowledgeDetails.task'),
|
||||||
|
// list: [
|
||||||
|
// {
|
||||||
|
// id: 'Parse',
|
||||||
|
// label: 'Parse',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// id: 'Download',
|
||||||
|
// label: 'Download',
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
if (active === LogTabs.FILE_LOGS) {
|
||||||
|
return filterCollection;
|
||||||
|
}
|
||||||
|
if (active === LogTabs.DATASET_LOGS) {
|
||||||
|
const list = filterCollection.filter((item, index) => index === 0);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}, [active, t]);
|
||||||
|
|
||||||
const tableList = useMemo(() => {
|
const tableList = useMemo(() => {
|
||||||
console.log('tableList', tableOriginData);
|
console.log('tableList', tableOriginData);
|
||||||
if (tableOriginData && tableOriginData.logs?.length) {
|
if (tableOriginData && tableOriginData.logs?.length) {
|
||||||
@ -187,6 +206,7 @@ const FileLogsPage: FC = () => {
|
|||||||
}, [tableOriginData]);
|
}, [tableOriginData]);
|
||||||
|
|
||||||
const changeActiveLogs = (active: (typeof LogTabs)[keyof typeof LogTabs]) => {
|
const changeActiveLogs = (active: (typeof LogTabs)[keyof typeof LogTabs]) => {
|
||||||
|
setFilterValue({});
|
||||||
setActive(active);
|
setActive(active);
|
||||||
};
|
};
|
||||||
const handlePaginationChange = (page: number, pageSize: number) => {
|
const handlePaginationChange = (page: number, pageSize: number) => {
|
||||||
|
|||||||
@ -1,157 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormDescription,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from '@/components/ui/select';
|
|
||||||
import { FormSlider } from '@/components/ui/slider';
|
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
|
||||||
import ChunkMethodCard from './chunk-method-card';
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
parser_id: z.string().min(1, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
a: z.number().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
b: z.string().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
c: z.number().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
d: z.string().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function AdvancedSettingForm() {
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
parser_id: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
|
||||||
console.log(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="a"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-2/5">
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<FormSlider {...field}></FormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<ChunkMethodCard></ChunkMethodCard>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="a"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-2/5">
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<FormSlider {...field}></FormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="b"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-2/5">
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select a verified email to display" />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="m@example.com">m@example.com</SelectItem>
|
|
||||||
<SelectItem value="m@google.com">m@google.com</SelectItem>
|
|
||||||
<SelectItem value="m@support.com">m@support.com</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="c"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-2/5">
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<FormSlider {...field}></FormSlider>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="d"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-2/5">
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Textarea {...field}></Textarea>
|
|
||||||
</FormControl>
|
|
||||||
<FormDescription>
|
|
||||||
This is your public display name.
|
|
||||||
</FormDescription>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button size={'sm'} type="submit" className="w-2/5">
|
|
||||||
Test
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { MultiSelect } from '@/components/ui/multi-select';
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from '@/components/ui/select';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { Cat, Dog, Fish, Rabbit, Turtle } from 'lucide-react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
const frameworksList = [
|
|
||||||
{ value: 'react', label: 'React', icon: Turtle },
|
|
||||||
{ value: 'angular', label: 'Angular', icon: Cat },
|
|
||||||
{ value: 'vue', label: 'Vue', icon: Dog },
|
|
||||||
{ value: 'svelte', label: 'Svelte', icon: Rabbit },
|
|
||||||
{ value: 'ember', label: 'Ember', icon: Fish },
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function BasicSettingForm() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
name: z.string().min(1),
|
|
||||||
a: z.number().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
language: z.string().min(1, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
c: z.number().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
d: z.string().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: '',
|
|
||||||
language: 'English',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [selectedFrameworks, setSelectedFrameworks] = useState<string[]>([
|
|
||||||
'react',
|
|
||||||
'angular',
|
|
||||||
]);
|
|
||||||
|
|
||||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
|
||||||
console.log(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('name')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="d"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="language"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('language')}</FormLabel>
|
|
||||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select a verified email to display" />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="m@example.com">m@example.com</SelectItem>
|
|
||||||
<SelectItem value="m@google.com">m@google.com</SelectItem>
|
|
||||||
<SelectItem value="m@support.com">m@support.com</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="c"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>Username</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<MultiSelect
|
|
||||||
options={frameworksList}
|
|
||||||
onValueChange={setSelectedFrameworks}
|
|
||||||
defaultValue={selectedFrameworks}
|
|
||||||
placeholder="Select frameworks"
|
|
||||||
variant="inverted"
|
|
||||||
maxCount={0}
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
import SvgIcon from '@/components/svg-icon';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { useSelectParserList } from '@/hooks/user-setting-hooks';
|
|
||||||
import { Col, Divider, Empty, Row, Typography } from 'antd';
|
|
||||||
import DOMPurify from 'dompurify';
|
|
||||||
import camelCase from 'lodash/camelCase';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import styles from './index.less';
|
|
||||||
import { TagTabs } from './tag-tabs';
|
|
||||||
import { ImageMap } from './utils';
|
|
||||||
|
|
||||||
const { Text } = Typography;
|
|
||||||
|
|
||||||
const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
|
|
||||||
const parserList = useSelectParserList();
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
|
|
||||||
const item = useMemo(() => {
|
|
||||||
const item = parserList.find((x) => x.value === chunkMethod);
|
|
||||||
if (item) {
|
|
||||||
return {
|
|
||||||
title: item.label,
|
|
||||||
description: t(camelCase(item.value)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return { title: '', description: '' };
|
|
||||||
}, [parserList, chunkMethod, t]);
|
|
||||||
|
|
||||||
const imageList = useMemo(() => {
|
|
||||||
if (chunkMethod in ImageMap) {
|
|
||||||
return ImageMap[chunkMethod as keyof typeof ImageMap];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}, [chunkMethod]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className={styles.categoryPanelWrapper}>
|
|
||||||
{imageList.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<h5 className="font-semibold text-base mt-0 mb-1">
|
|
||||||
{`"${item.title}" ${t('methodTitle')}`}
|
|
||||||
</h5>
|
|
||||||
<p
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: DOMPurify.sanitize(item.description),
|
|
||||||
}}
|
|
||||||
></p>
|
|
||||||
<h5 className="font-semibold text-base mt-4 mb-1">{`"${item.title}" ${t('methodExamples')}`}</h5>
|
|
||||||
<Text>{t('methodExamplesDescription')}</Text>
|
|
||||||
<Row gutter={[10, 10]} className={styles.imageRow}>
|
|
||||||
{imageList.map((x) => (
|
|
||||||
<Col span={12} key={x}>
|
|
||||||
<SvgIcon
|
|
||||||
name={x}
|
|
||||||
width={'100%'}
|
|
||||||
className={styles.image}
|
|
||||||
></SvgIcon>
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</Row>
|
|
||||||
<h5 className="font-semibold text-base mt-4 mb-1">
|
|
||||||
{item.title} {t('dialogueExamplesTitle')}
|
|
||||||
</h5>
|
|
||||||
<Divider></Divider>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Empty description={''} image={null}>
|
|
||||||
<p>{t('methodEmpty')}</p>
|
|
||||||
<SvgIcon name={'chunk-method/chunk-empty'} width={'100%'}></SvgIcon>
|
|
||||||
</Empty>
|
|
||||||
)}
|
|
||||||
{chunkMethod === 'tag' && <TagTabs></TagTabs>}
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CategoryPanel;
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
import SvgIcon from '@/components/svg-icon';
|
|
||||||
import { Card } from '@/components/ui/card';
|
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import {
|
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from '@/components/ui/select';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { useSelectParserList } from '@/hooks/user-setting-hooks';
|
|
||||||
import { Col, Divider, Empty, Row, Typography } from 'antd';
|
|
||||||
import DOMPurify from 'dompurify';
|
|
||||||
import camelCase from 'lodash/camelCase';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import styles from './index.less';
|
|
||||||
import { ImageMap } from './utils';
|
|
||||||
|
|
||||||
const { Title, Text } = Typography;
|
|
||||||
|
|
||||||
const CategoryPanel = ({ chunkMethod }: { chunkMethod: string }) => {
|
|
||||||
const parserList = useSelectParserList();
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
|
|
||||||
const item = useMemo(() => {
|
|
||||||
const item = parserList.find((x) => x.value === chunkMethod);
|
|
||||||
if (item) {
|
|
||||||
return {
|
|
||||||
title: item.label,
|
|
||||||
description: t(camelCase(item.value)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return { title: '', description: '' };
|
|
||||||
}, [parserList, chunkMethod, t]);
|
|
||||||
|
|
||||||
const imageList = useMemo(() => {
|
|
||||||
if (chunkMethod in ImageMap) {
|
|
||||||
return ImageMap[chunkMethod as keyof typeof ImageMap];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}, [chunkMethod]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className={styles.categoryPanelWrapper}>
|
|
||||||
{imageList.length > 0 ? (
|
|
||||||
<>
|
|
||||||
<Title level={5} className={styles.topTitle}>
|
|
||||||
{`"${item.title}" ${t('methodTitle')}`}
|
|
||||||
</Title>
|
|
||||||
<p
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: DOMPurify.sanitize(item.description),
|
|
||||||
}}
|
|
||||||
></p>
|
|
||||||
<Title level={5}>{`"${item.title}" ${t('methodExamples')}`}</Title>
|
|
||||||
<Text>{t('methodExamplesDescription')}</Text>
|
|
||||||
<Row gutter={[10, 10]} className={styles.imageRow}>
|
|
||||||
{imageList.map((x) => (
|
|
||||||
<Col span={12} key={x}>
|
|
||||||
<SvgIcon
|
|
||||||
name={x}
|
|
||||||
width={'100%'}
|
|
||||||
className={styles.image}
|
|
||||||
></SvgIcon>
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</Row>
|
|
||||||
<Title level={5}>
|
|
||||||
{item.title} {t('dialogueExamplesTitle')}
|
|
||||||
</Title>
|
|
||||||
<Divider></Divider>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Empty description={''} image={null}>
|
|
||||||
<p>{t('methodEmpty')}</p>
|
|
||||||
<SvgIcon name={'chunk-method/chunk-empty'} width={'100%'}></SvgIcon>
|
|
||||||
</Empty>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function ChunkMethodCard() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card className="border-0 p-6 mb-8 flex">
|
|
||||||
<div className="w-2/5">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="parser_id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('chunkMethod')}</FormLabel>
|
|
||||||
<Select onValueChange={field.onChange} defaultValue={field.value}>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Select a verified email to display" />
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="m@example.com">m@example.com</SelectItem>
|
|
||||||
<SelectItem value="m@google.com">m@google.com</SelectItem>
|
|
||||||
<SelectItem value="m@support.com">m@support.com</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<CategoryPanel chunkMethod=""></CategoryPanel>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import { useFormContext, useWatch } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { DocumentParserType } from '@/constants/knowledge';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { AudioConfiguration } from './configuration/audio';
|
|
||||||
import { BookConfiguration } from './configuration/book';
|
|
||||||
import { EmailConfiguration } from './configuration/email';
|
|
||||||
import { KnowledgeGraphConfiguration } from './configuration/knowledge-graph';
|
|
||||||
import { LawsConfiguration } from './configuration/laws';
|
|
||||||
import { ManualConfiguration } from './configuration/manual';
|
|
||||||
import { NaiveConfiguration } from './configuration/naive';
|
|
||||||
import { OneConfiguration } from './configuration/one';
|
|
||||||
import { PaperConfiguration } from './configuration/paper';
|
|
||||||
import { PictureConfiguration } from './configuration/picture';
|
|
||||||
import { PresentationConfiguration } from './configuration/presentation';
|
|
||||||
import { QAConfiguration } from './configuration/qa';
|
|
||||||
import { ResumeConfiguration } from './configuration/resume';
|
|
||||||
import { TableConfiguration } from './configuration/table';
|
|
||||||
import { TagConfiguration } from './configuration/tag';
|
|
||||||
import { SavingButton } from './saving-button';
|
|
||||||
|
|
||||||
const ConfigurationComponentMap = {
|
|
||||||
[DocumentParserType.Naive]: NaiveConfiguration,
|
|
||||||
[DocumentParserType.Qa]: QAConfiguration,
|
|
||||||
[DocumentParserType.Resume]: ResumeConfiguration,
|
|
||||||
[DocumentParserType.Manual]: ManualConfiguration,
|
|
||||||
[DocumentParserType.Table]: TableConfiguration,
|
|
||||||
[DocumentParserType.Paper]: PaperConfiguration,
|
|
||||||
[DocumentParserType.Book]: BookConfiguration,
|
|
||||||
[DocumentParserType.Laws]: LawsConfiguration,
|
|
||||||
[DocumentParserType.Presentation]: PresentationConfiguration,
|
|
||||||
[DocumentParserType.Picture]: PictureConfiguration,
|
|
||||||
[DocumentParserType.One]: OneConfiguration,
|
|
||||||
[DocumentParserType.Audio]: AudioConfiguration,
|
|
||||||
[DocumentParserType.Email]: EmailConfiguration,
|
|
||||||
[DocumentParserType.Tag]: TagConfiguration,
|
|
||||||
[DocumentParserType.KnowledgeGraph]: KnowledgeGraphConfiguration,
|
|
||||||
};
|
|
||||||
|
|
||||||
function EmptyComponent() {
|
|
||||||
return <div></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ChunkMethodForm() {
|
|
||||||
const form = useFormContext();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const finalParserId: DocumentParserType = useWatch({
|
|
||||||
control: form.control,
|
|
||||||
name: 'parser_id',
|
|
||||||
});
|
|
||||||
|
|
||||||
const ConfigurationComponent = useMemo(() => {
|
|
||||||
return finalParserId
|
|
||||||
? ConfigurationComponentMap[finalParserId]
|
|
||||||
: EmptyComponent;
|
|
||||||
}, [finalParserId]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="h-full flex flex-col">
|
|
||||||
<div className="overflow-auto flex-1 min-h-0">
|
|
||||||
<ConfigurationComponent></ConfigurationComponent>
|
|
||||||
</div>
|
|
||||||
<div className="text-right pt-4 flex justify-end gap-3">
|
|
||||||
<Button
|
|
||||||
type="reset"
|
|
||||||
className="bg-transparent text-color-white hover:bg-transparent border-gray-500 border-[1px]"
|
|
||||||
onClick={() => {
|
|
||||||
form.reset();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.cancel')}
|
|
||||||
</Button>
|
|
||||||
<SavingButton></SavingButton>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { t } from 'i18next';
|
|
||||||
import { X } from 'lucide-react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import CategoryPanel from './category-panel';
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
tab = 'generalForm',
|
|
||||||
parserId,
|
|
||||||
}: {
|
|
||||||
tab: 'generalForm' | 'chunkMethodForm';
|
|
||||||
parserId: string;
|
|
||||||
}) => {
|
|
||||||
const [visible, setVisible] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn('hidden flex-1', {
|
|
||||||
'flex flex-col': tab === 'chunkMethodForm',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => {
|
|
||||||
setVisible(!visible);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('knowledgeDetails.learnMore')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="bg-[#FFF]/10 p-[20px] rounded-[12px] mt-[10px] relative flex-1 overflow-auto"
|
|
||||||
style={{ display: visible ? 'block' : 'none' }}
|
|
||||||
>
|
|
||||||
<CategoryPanel chunkMethod={parserId}></CategoryPanel>
|
|
||||||
<div
|
|
||||||
className="absolute right-1 top-1 cursor-pointer hover:text-[#FFF]/30"
|
|
||||||
onClick={() => {
|
|
||||||
setVisible(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<X />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { FormContainer, FormContainerProps } from '@/components/form-container';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { PropsWithChildren } from 'react';
|
|
||||||
|
|
||||||
export function ConfigurationFormContainer({
|
|
||||||
children,
|
|
||||||
className,
|
|
||||||
}: FormContainerProps) {
|
|
||||||
return (
|
|
||||||
<FormContainer className={cn('p-10', className)}>{children}</FormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MainContainer({ children }: PropsWithChildren) {
|
|
||||||
return <section className="space-y-5">{children}</section>;
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function AudioConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</>
|
|
||||||
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function BookConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom className="p-10"></GraphRagItems>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,287 +0,0 @@
|
|||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Radio } from '@/components/ui/radio';
|
|
||||||
import { RAGFlowSelect } from '@/components/ui/select';
|
|
||||||
import { Switch } from '@/components/ui/switch';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { ArrowUpRight } from 'lucide-react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import {
|
|
||||||
useHasParsedDocument,
|
|
||||||
useSelectChunkMethodList,
|
|
||||||
useSelectEmbeddingModelOptions,
|
|
||||||
} from '../hooks';
|
|
||||||
|
|
||||||
export function ChunkMethodItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
// const handleChunkMethodSelectChange = useHandleChunkMethodSelectChange(form);
|
|
||||||
const parserList = useSelectChunkMethodList();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'parser_id'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="flex items-center">
|
|
||||||
<FormLabel
|
|
||||||
required
|
|
||||||
tooltip={t('chunkMethodTip')}
|
|
||||||
className="text-sm text-muted-foreground whitespace-wrap w-1/4"
|
|
||||||
>
|
|
||||||
{t('chunkMethod')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="w-3/4 ">
|
|
||||||
<FormControl>
|
|
||||||
<RAGFlowSelect
|
|
||||||
{...field}
|
|
||||||
options={parserList}
|
|
||||||
placeholder={t('chunkMethodPlaceholder')}
|
|
||||||
// onChange={handleChunkMethodSelectChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function EmbeddingModelItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
const embeddingModelOptions = useSelectEmbeddingModelOptions();
|
|
||||||
const disabled = useHasParsedDocument();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'embd_id'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="flex items-center">
|
|
||||||
<FormLabel
|
|
||||||
required
|
|
||||||
tooltip={t('embeddingModelTip')}
|
|
||||||
className="text-sm whitespace-wrap w-1/4"
|
|
||||||
>
|
|
||||||
{t('embeddingModel')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-muted-foreground w-3/4">
|
|
||||||
<FormControl>
|
|
||||||
<RAGFlowSelect
|
|
||||||
{...field}
|
|
||||||
options={embeddingModelOptions}
|
|
||||||
disabled={disabled}
|
|
||||||
placeholder={t('embeddingModelPlaceholder')}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ParseTypeItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'parseType'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="">
|
|
||||||
<FormLabel
|
|
||||||
tooltip={t('parseTypeTip')}
|
|
||||||
className="text-sm whitespace-wrap "
|
|
||||||
>
|
|
||||||
{t('parseType')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
<FormControl>
|
|
||||||
<Radio.Group {...field}>
|
|
||||||
<div className="w-3/4 flex gap-2 justify-between text-muted-foreground">
|
|
||||||
<Radio value={1}>{t('builtIn')}</Radio>
|
|
||||||
<Radio value={2}>{t('manualSetup')}</Radio>
|
|
||||||
</div>
|
|
||||||
</Radio.Group>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DataFlowItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'data_flow'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="">
|
|
||||||
<div className="flex gap-2 justify-between ">
|
|
||||||
<FormLabel
|
|
||||||
tooltip={t('dataFlowTip')}
|
|
||||||
className="text-sm text-text-primary whitespace-wrap "
|
|
||||||
>
|
|
||||||
{t('dataFlow')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-sm flex text-text-primary">
|
|
||||||
{t('buildItFromScratch')}
|
|
||||||
<ArrowUpRight size={14} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
<FormControl>
|
|
||||||
<RAGFlowSelect
|
|
||||||
{...field}
|
|
||||||
placeholder={t('dataFlowPlaceholder')}
|
|
||||||
options={[{ value: '0', label: t('dataFlowDefault') }]}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DataExtractKnowledgeItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{' '}
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'extractKnowledgeGraph'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="">
|
|
||||||
<FormLabel
|
|
||||||
tooltip={t('extractKnowledgeGraphTip')}
|
|
||||||
className="text-sm whitespace-wrap "
|
|
||||||
>
|
|
||||||
{t('extractKnowledgeGraph')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
<FormControl>
|
|
||||||
<Switch
|
|
||||||
checked={field.value}
|
|
||||||
onCheckedChange={field.onChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>{' '}
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'useRAPTORToEnhanceRetrieval'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="">
|
|
||||||
<FormLabel
|
|
||||||
tooltip={t('useRAPTORToEnhanceRetrievalTip')}
|
|
||||||
className="text-sm whitespace-wrap "
|
|
||||||
>
|
|
||||||
{t('useRAPTORToEnhanceRetrieval')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
<FormControl>
|
|
||||||
<Switch
|
|
||||||
checked={field.value}
|
|
||||||
onCheckedChange={field.onChange}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TeamItem() {
|
|
||||||
const { t } = useTranslate('knowledgeConfiguration');
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name={'team'}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="">
|
|
||||||
<FormLabel
|
|
||||||
tooltip={t('teamTip')}
|
|
||||||
className="text-sm whitespace-wrap "
|
|
||||||
>
|
|
||||||
<span className="text-destructive mr-1"> *</span>
|
|
||||||
{t('team')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="text-muted-foreground">
|
|
||||||
<FormControl>
|
|
||||||
<RAGFlowSelect
|
|
||||||
{...field}
|
|
||||||
placeholder={t('teamPlaceholder')}
|
|
||||||
options={[{ value: '0', label: t('teamDefault') }]}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function EmailConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</>
|
|
||||||
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
import { DelimiterFormField } from '@/components/delimiter-form-field';
|
|
||||||
import { EntityTypesFormField } from '@/components/entity-types-form-field';
|
|
||||||
import { MaxTokenNumberFormField } from '@/components/max-token-number-from-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function KnowledgeGraphConfiguration() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<>
|
|
||||||
<EntityTypesFormField></EntityTypesFormField>
|
|
||||||
<MaxTokenNumberFormField max={8192 * 2}></MaxTokenNumberFormField>
|
|
||||||
<DelimiterFormField></DelimiterFormField>
|
|
||||||
</>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function LawsConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function ManualConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { DelimiterFormField } from '@/components/delimiter-form-field';
|
|
||||||
import { ExcelToHtmlFormField } from '@/components/excel-to-html-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import { MaxTokenNumberFormField } from '@/components/max-token-number-from-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function NaiveConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
<MaxTokenNumberFormField initialValue={512}></MaxTokenNumberFormField>
|
|
||||||
<DelimiterFormField></DelimiterFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
<ExcelToHtmlFormField></ExcelToHtmlFormField>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
<GraphRagItems></GraphRagItems>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function OneConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function PaperConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function PictureConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import {
|
|
||||||
AutoKeywordsFormField,
|
|
||||||
AutoQuestionsFormField,
|
|
||||||
} from '@/components/auto-keywords-form-field';
|
|
||||||
import { LayoutRecognizeFormField } from '@/components/layout-recognize-form-field';
|
|
||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields';
|
|
||||||
import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields';
|
|
||||||
import {
|
|
||||||
ConfigurationFormContainer,
|
|
||||||
MainContainer,
|
|
||||||
} from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function PresentationConfiguration() {
|
|
||||||
return (
|
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<AutoKeywordsFormField></AutoKeywordsFormField>
|
|
||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<RaptorFormFields></RaptorFormFields>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<GraphRagItems marginBottom></GraphRagItems>
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function QAConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { TagItems } from '../tag-item';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function ResumeConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
|
|
||||||
<TagItems></TagItems>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function TableConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import PageRankFormField from '@/components/page-rank-form-field';
|
|
||||||
import { ConfigurationFormContainer } from '../configuration-form-container';
|
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
|
||||||
|
|
||||||
export function TagConfiguration() {
|
|
||||||
return (
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
<EmbeddingModelItem></EmbeddingModelItem>
|
|
||||||
|
|
||||||
<PageRankFormField></PageRankFormField>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
export const formSchema = z.object({
|
|
||||||
name: z.string().min(1, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
description: z.string().min(2, {
|
|
||||||
message: 'Username must be at least 2 characters.',
|
|
||||||
}),
|
|
||||||
// avatar: z.instanceof(File),
|
|
||||||
avatar: z.any().nullish(),
|
|
||||||
permission: z.string().optional(),
|
|
||||||
parser_id: z.string(),
|
|
||||||
embd_id: z.string(),
|
|
||||||
parser_config: z
|
|
||||||
.object({
|
|
||||||
layout_recognize: z.string(),
|
|
||||||
chunk_token_num: z.number(),
|
|
||||||
delimiter: z.string(),
|
|
||||||
auto_keywords: z.number().optional(),
|
|
||||||
auto_questions: z.number().optional(),
|
|
||||||
html4excel: z.boolean(),
|
|
||||||
tag_kb_ids: z.array(z.string()).nullish(),
|
|
||||||
topn_tags: z.number().optional(),
|
|
||||||
raptor: z
|
|
||||||
.object({
|
|
||||||
use_raptor: z.boolean().optional(),
|
|
||||||
prompt: z.string().optional(),
|
|
||||||
max_token: z.number().optional(),
|
|
||||||
threshold: z.number().optional(),
|
|
||||||
max_cluster: z.number().optional(),
|
|
||||||
random_seed: z.number().optional(),
|
|
||||||
})
|
|
||||||
.refine(
|
|
||||||
(data) => {
|
|
||||||
if (data.use_raptor && !data.prompt) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Prompt is required',
|
|
||||||
path: ['prompt'],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
graphrag: z
|
|
||||||
.object({
|
|
||||||
use_graphrag: z.boolean().optional(),
|
|
||||||
entity_types: z.array(z.string()).optional(),
|
|
||||||
method: z.string().optional(),
|
|
||||||
resolution: z.boolean().optional(),
|
|
||||||
community: z.boolean().optional(),
|
|
||||||
})
|
|
||||||
.refine(
|
|
||||||
(data) => {
|
|
||||||
if (
|
|
||||||
data.use_graphrag &&
|
|
||||||
(!data.entity_types || data.entity_types.length === 0)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: 'Please enter Entity types',
|
|
||||||
path: ['entity_types'],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
})
|
|
||||||
.optional(),
|
|
||||||
pagerank: z.number(),
|
|
||||||
// icon: z.array(z.instanceof(File)),
|
|
||||||
});
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
import { AvatarUpload } from '@/components/avatar-upload';
|
|
||||||
import { FormContainer } from '@/components/form-container';
|
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { PermissionFormField } from './permission-form-field';
|
|
||||||
import { GeneralSavingButton } from './saving-button';
|
|
||||||
|
|
||||||
export function GeneralForm() {
|
|
||||||
const form = useFormContext();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<FormContainer className="space-y-10 p-10">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="items-center space-y-0">
|
|
||||||
<div className="flex">
|
|
||||||
<FormLabel className="text-sm text-muted-foreground whitespace-nowrap w-1/4">
|
|
||||||
<span className="text-red-600">*</span>
|
|
||||||
{t('common.name')}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl className="w-3/4">
|
|
||||||
<Input {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="avatar"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="items-center space-y-0">
|
|
||||||
<div className="flex">
|
|
||||||
<FormLabel className="text-sm text-muted-foreground whitespace-nowrap w-1/4">
|
|
||||||
{t('setting.avatar')}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl className="w-3/4">
|
|
||||||
<AvatarUpload {...field}></AvatarUpload>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="description"
|
|
||||||
render={({ field }) => {
|
|
||||||
// null initialize empty string
|
|
||||||
if (typeof field.value === 'object' && !field.value) {
|
|
||||||
form.setValue('description', ' ');
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<FormItem className="items-center space-y-0">
|
|
||||||
<div className="flex">
|
|
||||||
<FormLabel className="text-sm text-muted-foreground whitespace-nowrap w-1/4">
|
|
||||||
{t('flow.description')}
|
|
||||||
</FormLabel>
|
|
||||||
<FormControl className="w-3/4">
|
|
||||||
<Input {...field}></Input>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<PermissionFormField></PermissionFormField>
|
|
||||||
</FormContainer>
|
|
||||||
<div className="text-right pt-4 flex justify-end gap-3">
|
|
||||||
<Button
|
|
||||||
type="reset"
|
|
||||||
variant={'outline'}
|
|
||||||
onClick={() => {
|
|
||||||
form.reset();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.cancel')}
|
|
||||||
</Button>
|
|
||||||
<GeneralSavingButton></GeneralSavingButton>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
import { LlmModelType } from '@/constants/knowledge';
|
|
||||||
import { useSetModalState } from '@/hooks/common-hooks';
|
|
||||||
|
|
||||||
import { useSelectLlmOptionsByModelType } from '@/hooks/llm-hooks';
|
|
||||||
import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request';
|
|
||||||
import { useSelectParserList } from '@/hooks/user-setting-hooks';
|
|
||||||
import { useIsFetching } from '@tanstack/react-query';
|
|
||||||
import { pick } from 'lodash';
|
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
|
||||||
import { UseFormReturn } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
|
||||||
import { formSchema } from './form-schema';
|
|
||||||
|
|
||||||
// The value that does not need to be displayed in the analysis method Select
|
|
||||||
const HiddenFields = ['email', 'picture', 'audio'];
|
|
||||||
|
|
||||||
export function useSelectChunkMethodList() {
|
|
||||||
const parserList = useSelectParserList();
|
|
||||||
|
|
||||||
return parserList.filter((x) => !HiddenFields.some((y) => y === x.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useSelectEmbeddingModelOptions() {
|
|
||||||
const allOptions = useSelectLlmOptionsByModelType();
|
|
||||||
return allOptions[LlmModelType.Embedding];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useHasParsedDocument() {
|
|
||||||
const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration();
|
|
||||||
return knowledgeDetails.chunk_num > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useFetchKnowledgeConfigurationOnMount = (
|
|
||||||
form: UseFormReturn<z.infer<typeof formSchema>, any, undefined>,
|
|
||||||
) => {
|
|
||||||
const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const parser_config = {
|
|
||||||
...form.formState?.defaultValues?.parser_config,
|
|
||||||
...knowledgeDetails.parser_config,
|
|
||||||
};
|
|
||||||
const formValues = {
|
|
||||||
...pick({ ...knowledgeDetails, parser_config: parser_config }, [
|
|
||||||
'description',
|
|
||||||
'name',
|
|
||||||
'permission',
|
|
||||||
'embd_id',
|
|
||||||
'parser_id',
|
|
||||||
'language',
|
|
||||||
'parser_config',
|
|
||||||
'pagerank',
|
|
||||||
'avatar',
|
|
||||||
]),
|
|
||||||
};
|
|
||||||
form.reset(formValues);
|
|
||||||
}, [form, knowledgeDetails]);
|
|
||||||
|
|
||||||
return knowledgeDetails;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useSelectKnowledgeDetailsLoading = () =>
|
|
||||||
useIsFetching({ queryKey: ['fetchKnowledgeDetail'] }) > 0;
|
|
||||||
|
|
||||||
export const useRenameKnowledgeTag = () => {
|
|
||||||
const [tag, setTag] = useState<string>('');
|
|
||||||
const {
|
|
||||||
visible: tagRenameVisible,
|
|
||||||
hideModal: hideTagRenameModal,
|
|
||||||
showModal: showFileRenameModal,
|
|
||||||
} = useSetModalState();
|
|
||||||
|
|
||||||
const handleShowTagRenameModal = useCallback(
|
|
||||||
(record: string) => {
|
|
||||||
setTag(record);
|
|
||||||
showFileRenameModal();
|
|
||||||
},
|
|
||||||
[showFileRenameModal],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
initialName: tag,
|
|
||||||
tagRenameVisible,
|
|
||||||
hideTagRenameModal,
|
|
||||||
showTagRenameModal: handleShowTagRenameModal,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
.tags {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preset {
|
|
||||||
display: flex;
|
|
||||||
height: 80px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 5px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
width: 100px;
|
|
||||||
border-left: 1px solid rgba(0, 0, 0, 0.4);
|
|
||||||
margin: 10px 0px;
|
|
||||||
padding: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.configurationWrapper {
|
|
||||||
padding: 0 52px;
|
|
||||||
.buttonWrapper {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.variableSlider {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.categoryPanelWrapper {
|
|
||||||
.topTitle {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
.imageRow {
|
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
.image {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,138 +0,0 @@
|
|||||||
import { Form } from '@/components/ui/form';
|
|
||||||
import {
|
|
||||||
Tabs,
|
|
||||||
TabsContent,
|
|
||||||
TabsList,
|
|
||||||
TabsTrigger,
|
|
||||||
} from '@/components/ui/tabs-underlined';
|
|
||||||
import { DocumentParserType } from '@/constants/knowledge';
|
|
||||||
import { PermissionRole } from '@/constants/permission';
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { z } from 'zod';
|
|
||||||
import { TopTitle } from '../dataset-title';
|
|
||||||
import { ChunkMethodForm } from './chunk-method-form';
|
|
||||||
import ChunkMethodLearnMore from './chunk-method-learn-more';
|
|
||||||
import { formSchema } from './form-schema';
|
|
||||||
import { GeneralForm } from './general-form';
|
|
||||||
import { useFetchKnowledgeConfigurationOnMount } from './hooks';
|
|
||||||
|
|
||||||
const enum DocumentType {
|
|
||||||
DeepDOC = 'DeepDOC',
|
|
||||||
PlainText = 'Plain Text',
|
|
||||||
}
|
|
||||||
|
|
||||||
const initialEntityTypes = [
|
|
||||||
'organization',
|
|
||||||
'person',
|
|
||||||
'geo',
|
|
||||||
'event',
|
|
||||||
'category',
|
|
||||||
];
|
|
||||||
|
|
||||||
const enum MethodValue {
|
|
||||||
General = 'general',
|
|
||||||
Light = 'light',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function DatasetSettings() {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: '',
|
|
||||||
parser_id: DocumentParserType.Naive,
|
|
||||||
permission: PermissionRole.Me,
|
|
||||||
parser_config: {
|
|
||||||
layout_recognize: DocumentType.DeepDOC,
|
|
||||||
chunk_token_num: 512,
|
|
||||||
delimiter: `\n`,
|
|
||||||
auto_keywords: 0,
|
|
||||||
auto_questions: 0,
|
|
||||||
html4excel: false,
|
|
||||||
topn_tags: 3,
|
|
||||||
raptor: {
|
|
||||||
use_raptor: false,
|
|
||||||
},
|
|
||||||
graphrag: {
|
|
||||||
use_graphrag: false,
|
|
||||||
entity_types: initialEntityTypes,
|
|
||||||
method: MethodValue.Light,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pagerank: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
useFetchKnowledgeConfigurationOnMount(form);
|
|
||||||
|
|
||||||
const [currentTab, setCurrentTab] = useState<
|
|
||||||
'generalForm' | 'chunkMethodForm'
|
|
||||||
>('generalForm'); // currnet Tab state
|
|
||||||
|
|
||||||
const parserId = useWatch({
|
|
||||||
control: form.control,
|
|
||||||
name: 'parser_id',
|
|
||||||
});
|
|
||||||
|
|
||||||
async function onSubmit(data: z.infer<typeof formSchema>) {
|
|
||||||
console.log('🚀 ~ DatasetSettings ~ data:', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="p-5 h-full flex flex-col">
|
|
||||||
<TopTitle
|
|
||||||
title={t('knowledgeDetails.configuration')}
|
|
||||||
description={t('knowledgeConfiguration.titleDescription')}
|
|
||||||
></TopTitle>
|
|
||||||
<div className="flex gap-14 flex-1 min-h-0">
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
|
||||||
className="space-y-6 flex-1"
|
|
||||||
>
|
|
||||||
<Tabs
|
|
||||||
defaultValue="generalForm"
|
|
||||||
onValueChange={(val) => {
|
|
||||||
setCurrentTab(val);
|
|
||||||
}}
|
|
||||||
className="h-full flex flex-col"
|
|
||||||
>
|
|
||||||
<TabsList className="grid bg-transparent grid-cols-2 rounded-none text-foreground">
|
|
||||||
<TabsTrigger
|
|
||||||
value="generalForm"
|
|
||||||
className="group bg-transparent p-0 !border-transparent"
|
|
||||||
>
|
|
||||||
<div className="flex w-full h-full justify-center items-center">
|
|
||||||
<span className="h-full group-data-[state=active]:border-b-2 border-foreground ">
|
|
||||||
{t('knowledgeDetails.general')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</TabsTrigger>
|
|
||||||
<TabsTrigger
|
|
||||||
value="chunkMethodForm"
|
|
||||||
className="group bg-transparent p-0 !border-transparent"
|
|
||||||
>
|
|
||||||
<div className="flex w-full h-full justify-center items-center">
|
|
||||||
<span className="h-full group-data-[state=active]:border-b-2 border-foreground ">
|
|
||||||
{t('knowledgeDetails.chunkMethodTab')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</TabsTrigger>
|
|
||||||
</TabsList>
|
|
||||||
<TabsContent value="generalForm" className="flex-1 min-h-0">
|
|
||||||
<GeneralForm></GeneralForm>
|
|
||||||
</TabsContent>
|
|
||||||
<TabsContent value="chunkMethodForm" className="flex-1 min-h-0">
|
|
||||||
<ChunkMethodForm></ChunkMethodForm>
|
|
||||||
</TabsContent>
|
|
||||||
</Tabs>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
<ChunkMethodLearnMore tab={currentTab} parserId={parserId} />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { SelectWithSearch } from '@/components/originui/select-with-search';
|
|
||||||
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
|
||||||
import { PermissionRole } from '@/constants/permission';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
export function PermissionFormField() {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const teamOptions = useMemo(() => {
|
|
||||||
return Object.values(PermissionRole).map((x) => ({
|
|
||||||
label: t('knowledgeConfiguration.' + x),
|
|
||||||
value: x,
|
|
||||||
}));
|
|
||||||
}, [t]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RAGFlowFormItem
|
|
||||||
name="permission"
|
|
||||||
label={t('knowledgeConfiguration.permissions')}
|
|
||||||
tooltip={t('knowledgeConfiguration.permissionsTip')}
|
|
||||||
horizontal
|
|
||||||
>
|
|
||||||
<SelectWithSearch
|
|
||||||
options={teamOptions}
|
|
||||||
triggerClassName="w-3/4"
|
|
||||||
></SelectWithSearch>
|
|
||||||
</RAGFlowFormItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import { ButtonLoading } from '@/components/ui/button';
|
|
||||||
import { useUpdateKnowledge } from '@/hooks/use-knowledge-request';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { useFormContext } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { useParams } from 'umi';
|
|
||||||
|
|
||||||
export function GeneralSavingButton() {
|
|
||||||
const form = useFormContext();
|
|
||||||
const { saveKnowledgeConfiguration, loading: submitLoading } =
|
|
||||||
useUpdateKnowledge();
|
|
||||||
const { id: kb_id } = useParams();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const defaultValues = useMemo(
|
|
||||||
() => form.formState.defaultValues ?? {},
|
|
||||||
[form.formState.defaultValues],
|
|
||||||
);
|
|
||||||
const parser_id = defaultValues['parser_id'];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ButtonLoading
|
|
||||||
type="button"
|
|
||||||
loading={submitLoading}
|
|
||||||
onClick={() => {
|
|
||||||
(async () => {
|
|
||||||
let isValidate = await form.trigger('name');
|
|
||||||
const { name, description, permission, avatar } = form.getValues();
|
|
||||||
|
|
||||||
if (isValidate) {
|
|
||||||
saveKnowledgeConfiguration({
|
|
||||||
kb_id,
|
|
||||||
parser_id,
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
avatar,
|
|
||||||
permission,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.save')}
|
|
||||||
</ButtonLoading>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SavingButton() {
|
|
||||||
const { saveKnowledgeConfiguration, loading: submitLoading } =
|
|
||||||
useUpdateKnowledge();
|
|
||||||
const form = useFormContext();
|
|
||||||
const { id: kb_id } = useParams();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ButtonLoading
|
|
||||||
loading={submitLoading}
|
|
||||||
onClick={() => {
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
let beValid = await form.formControl.trigger();
|
|
||||||
if (beValid) {
|
|
||||||
form.handleSubmit(async (values) => {
|
|
||||||
console.log('saveKnowledgeConfiguration: ', values);
|
|
||||||
delete values['avatar'];
|
|
||||||
await saveKnowledgeConfiguration({
|
|
||||||
kb_id,
|
|
||||||
...values,
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
} finally {
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.save')}
|
|
||||||
</ButtonLoading>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,155 +0,0 @@
|
|||||||
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
|
||||||
import { SliderInputFormField } from '@/components/slider-input-form-field';
|
|
||||||
import {
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { MultiSelect } from '@/components/ui/multi-select';
|
|
||||||
import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks';
|
|
||||||
import { Flex, Form, InputNumber, Select, Slider, Space } from 'antd';
|
|
||||||
import DOMPurify from 'dompurify';
|
|
||||||
import { useFormContext, useWatch } from 'react-hook-form';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
export const TagSetItem = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const form = useFormContext();
|
|
||||||
|
|
||||||
const { list: knowledgeList } = useFetchKnowledgeList(true);
|
|
||||||
|
|
||||||
const knowledgeOptions = knowledgeList
|
|
||||||
.filter((x) => x.parser_id === 'tag')
|
|
||||||
.map((x) => ({
|
|
||||||
label: x.name,
|
|
||||||
value: x.id,
|
|
||||||
icon: () => (
|
|
||||||
<Space>
|
|
||||||
<RAGFlowAvatar
|
|
||||||
name={x.name}
|
|
||||||
avatar={x.avatar}
|
|
||||||
className="size-4"
|
|
||||||
></RAGFlowAvatar>
|
|
||||||
</Space>
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="parser_config.tag_kb_ids"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className=" items-center space-y-0 ">
|
|
||||||
<div className="flex items-center">
|
|
||||||
<FormLabel
|
|
||||||
className="text-sm text-muted-foreground whitespace-nowrap w-1/4"
|
|
||||||
tooltip={
|
|
||||||
<div
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: DOMPurify.sanitize(
|
|
||||||
t('knowledgeConfiguration.tagSetTip'),
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.tagSet')}
|
|
||||||
</FormLabel>
|
|
||||||
<div className="w-3/4">
|
|
||||||
<FormControl>
|
|
||||||
<MultiSelect
|
|
||||||
options={knowledgeOptions}
|
|
||||||
onValueChange={field.onChange}
|
|
||||||
placeholder={t('chat.knowledgeBasesMessage')}
|
|
||||||
variant="inverted"
|
|
||||||
maxCount={10}
|
|
||||||
{...field}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex pt-1">
|
|
||||||
<div className="w-1/4"></div>
|
|
||||||
<FormMessage />
|
|
||||||
</div>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form.Item
|
|
||||||
label={t('knowledgeConfiguration.tagSet')}
|
|
||||||
name={['parser_config', 'tag_kb_ids']}
|
|
||||||
tooltip={
|
|
||||||
<div
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: DOMPurify.sanitize(t('knowledgeConfiguration.tagSetTip')),
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
message: t('chat.knowledgeBasesMessage'),
|
|
||||||
type: 'array',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Select
|
|
||||||
mode="multiple"
|
|
||||||
options={knowledgeOptions}
|
|
||||||
placeholder={t('chat.knowledgeBasesMessage')}
|
|
||||||
></Select>
|
|
||||||
</Form.Item>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TopNTagsItem = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SliderInputFormField
|
|
||||||
name={'parser_config.topn_tags'}
|
|
||||||
label={t('knowledgeConfiguration.topnTags')}
|
|
||||||
max={10}
|
|
||||||
min={1}
|
|
||||||
defaultValue={3}
|
|
||||||
></SliderInputFormField>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form.Item label={t('knowledgeConfiguration.topnTags')}>
|
|
||||||
<Flex gap={20} align="center">
|
|
||||||
<Flex flex={1}>
|
|
||||||
<Form.Item
|
|
||||||
name={['parser_config', 'topn_tags']}
|
|
||||||
noStyle
|
|
||||||
initialValue={3}
|
|
||||||
>
|
|
||||||
<Slider max={10} min={1} style={{ width: '100%' }} />
|
|
||||||
</Form.Item>
|
|
||||||
</Flex>
|
|
||||||
<Form.Item name={['parser_config', 'topn_tags']} noStyle>
|
|
||||||
<InputNumber max={10} min={1} />
|
|
||||||
</Form.Item>
|
|
||||||
</Flex>
|
|
||||||
</Form.Item>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TagItems() {
|
|
||||||
const form = useFormContext();
|
|
||||||
const ids: string[] = useWatch({
|
|
||||||
control: form.control,
|
|
||||||
name: 'parser_config.tag_kb_ids',
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TagSetItem></TagSetItem>
|
|
||||||
{Array.isArray(ids) && ids.length > 0 && <TopNTagsItem></TopNTagsItem>}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,305 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import {
|
|
||||||
ColumnDef,
|
|
||||||
ColumnFiltersState,
|
|
||||||
SortingState,
|
|
||||||
VisibilityState,
|
|
||||||
flexRender,
|
|
||||||
getCoreRowModel,
|
|
||||||
getFilteredRowModel,
|
|
||||||
getPaginationRowModel,
|
|
||||||
getSortedRowModel,
|
|
||||||
useReactTable,
|
|
||||||
} from '@tanstack/react-table';
|
|
||||||
import { ArrowUpDown, Pencil, Trash2 } from 'lucide-react';
|
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
import { ConfirmDeleteDialog } from '@/components/confirm-delete-dialog';
|
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from '@/components/ui/table';
|
|
||||||
import {
|
|
||||||
Tooltip,
|
|
||||||
TooltipContent,
|
|
||||||
TooltipProvider,
|
|
||||||
TooltipTrigger,
|
|
||||||
} from '@/components/ui/tooltip';
|
|
||||||
import { useDeleteTag, useFetchTagList } from '@/hooks/knowledge-hooks';
|
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { useRenameKnowledgeTag } from '../hooks';
|
|
||||||
import { RenameDialog } from './rename-dialog';
|
|
||||||
|
|
||||||
export type ITag = {
|
|
||||||
tag: string;
|
|
||||||
frequency: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TagTable() {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const { list } = useFetchTagList();
|
|
||||||
const [tagList, setTagList] = useState<ITag[]>([]);
|
|
||||||
|
|
||||||
const [sorting, setSorting] = React.useState<SortingState>([]);
|
|
||||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
const [columnVisibility, setColumnVisibility] =
|
|
||||||
React.useState<VisibilityState>({});
|
|
||||||
const [rowSelection, setRowSelection] = useState({});
|
|
||||||
|
|
||||||
const { deleteTag } = useDeleteTag();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTagList(list.map((x) => ({ tag: x[0], frequency: x[1] })));
|
|
||||||
}, [list]);
|
|
||||||
|
|
||||||
const handleDeleteTag = useCallback(
|
|
||||||
(tags: string[]) => () => {
|
|
||||||
deleteTag(tags);
|
|
||||||
},
|
|
||||||
[deleteTag],
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
showTagRenameModal,
|
|
||||||
hideTagRenameModal,
|
|
||||||
tagRenameVisible,
|
|
||||||
initialName,
|
|
||||||
} = useRenameKnowledgeTag();
|
|
||||||
|
|
||||||
const columns: ColumnDef<ITag>[] = [
|
|
||||||
{
|
|
||||||
id: 'select',
|
|
||||||
header: ({ table }) => (
|
|
||||||
<Checkbox
|
|
||||||
checked={
|
|
||||||
table.getIsAllPageRowsSelected() ||
|
|
||||||
(table.getIsSomePageRowsSelected() && 'indeterminate')
|
|
||||||
}
|
|
||||||
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
|
|
||||||
aria-label="Select all"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<Checkbox
|
|
||||||
checked={row.getIsSelected()}
|
|
||||||
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
|
||||||
aria-label="Select row"
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
enableSorting: false,
|
|
||||||
enableHiding: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'tag',
|
|
||||||
header: ({ column }) => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.tagName')}
|
|
||||||
<ArrowUpDown />
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const value: string = row.getValue('tag');
|
|
||||||
return <div>{value}</div>;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'frequency',
|
|
||||||
header: ({ column }) => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}
|
|
||||||
>
|
|
||||||
{t('knowledgeConfiguration.frequency')}
|
|
||||||
<ArrowUpDown />
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cell: ({ row }) => (
|
|
||||||
<div className="capitalize ">{row.getValue('frequency')}</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'actions',
|
|
||||||
enableHiding: false,
|
|
||||||
header: t('common.action'),
|
|
||||||
cell: ({ row }) => {
|
|
||||||
return (
|
|
||||||
<div className="flex gap-1">
|
|
||||||
<Tooltip>
|
|
||||||
<ConfirmDeleteDialog onOk={handleDeleteTag([row.original.tag])}>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button variant="ghost" size="icon">
|
|
||||||
<Trash2 />
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
</ConfirmDeleteDialog>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>{t('common.delete')}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => showTagRenameModal(row.original.tag)}
|
|
||||||
>
|
|
||||||
<Pencil />
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>{t('common.rename')}</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const table = useReactTable({
|
|
||||||
data: tagList,
|
|
||||||
columns,
|
|
||||||
onSortingChange: setSorting,
|
|
||||||
onColumnFiltersChange: setColumnFilters,
|
|
||||||
getCoreRowModel: getCoreRowModel(),
|
|
||||||
getPaginationRowModel: getPaginationRowModel(),
|
|
||||||
getSortedRowModel: getSortedRowModel(),
|
|
||||||
getFilteredRowModel: getFilteredRowModel(),
|
|
||||||
onColumnVisibilityChange: setColumnVisibility,
|
|
||||||
onRowSelectionChange: setRowSelection,
|
|
||||||
state: {
|
|
||||||
sorting,
|
|
||||||
columnFilters,
|
|
||||||
columnVisibility,
|
|
||||||
rowSelection,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectedRowLength = table.getFilteredSelectedRowModel().rows.length;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TooltipProvider>
|
|
||||||
<div className="w-full">
|
|
||||||
<div className="flex items-center justify-between py-4 ">
|
|
||||||
<Input
|
|
||||||
placeholder={t('knowledgeConfiguration.searchTags')}
|
|
||||||
value={(table.getColumn('tag')?.getFilterValue() as string) ?? ''}
|
|
||||||
onChange={(event) =>
|
|
||||||
table.getColumn('tag')?.setFilterValue(event.target.value)
|
|
||||||
}
|
|
||||||
className="w-1/2"
|
|
||||||
/>
|
|
||||||
{selectedRowLength > 0 && (
|
|
||||||
<ConfirmDeleteDialog
|
|
||||||
onOk={handleDeleteTag(
|
|
||||||
table
|
|
||||||
.getFilteredSelectedRowModel()
|
|
||||||
.rows.map((x) => x.original.tag),
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Button variant="outline" size="icon">
|
|
||||||
<Trash2 />
|
|
||||||
</Button>
|
|
||||||
</ConfirmDeleteDialog>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<Table rootClassName="rounded-none border max-h-80 overflow-y-auto">
|
|
||||||
<TableHeader className="bg-[#39393b]">
|
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
|
||||||
<TableRow key={headerGroup.id}>
|
|
||||||
{headerGroup.headers.map((header) => {
|
|
||||||
return (
|
|
||||||
<TableHead key={header.id}>
|
|
||||||
{header.isPlaceholder
|
|
||||||
? null
|
|
||||||
: flexRender(
|
|
||||||
header.column.columnDef.header,
|
|
||||||
header.getContext(),
|
|
||||||
)}
|
|
||||||
</TableHead>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody>
|
|
||||||
{table.getRowModel().rows?.length ? (
|
|
||||||
table.getRowModel().rows.map((row) => (
|
|
||||||
<TableRow
|
|
||||||
key={row.id}
|
|
||||||
data-state={row.getIsSelected() && 'selected'}
|
|
||||||
>
|
|
||||||
{row.getVisibleCells().map((cell) => (
|
|
||||||
<TableCell key={cell.id}>
|
|
||||||
{flexRender(
|
|
||||||
cell.column.columnDef.cell,
|
|
||||||
cell.getContext(),
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
colSpan={columns.length}
|
|
||||||
className="h-24 text-center"
|
|
||||||
>
|
|
||||||
No results.
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center justify-end space-x-2 py-4">
|
|
||||||
<div className="flex-1 text-sm text-muted-foreground">
|
|
||||||
{selectedRowLength} of {table.getFilteredRowModel().rows.length}{' '}
|
|
||||||
row(s) selected.
|
|
||||||
</div>
|
|
||||||
<div className="space-x-2">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => table.previousPage()}
|
|
||||||
disabled={!table.getCanPreviousPage()}
|
|
||||||
>
|
|
||||||
{t('common.previousPage')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => table.nextPage()}
|
|
||||||
disabled={!table.getCanNextPage()}
|
|
||||||
>
|
|
||||||
{t('common.nextPage')}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{tagRenameVisible && (
|
|
||||||
<RenameDialog
|
|
||||||
hideModal={hideTagRenameModal}
|
|
||||||
initialName={initialName}
|
|
||||||
></RenameDialog>
|
|
||||||
)}
|
|
||||||
</TooltipProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
} from '@/components/ui/dialog';
|
|
||||||
import { LoadingButton } from '@/components/ui/loading-button';
|
|
||||||
import { useTagIsRenaming } from '@/hooks/knowledge-hooks';
|
|
||||||
import { IModalProps } from '@/interfaces/common';
|
|
||||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { RenameForm } from './rename-form';
|
|
||||||
|
|
||||||
export function RenameDialog({
|
|
||||||
hideModal,
|
|
||||||
initialName,
|
|
||||||
}: IModalProps<any> & { initialName: string }) {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const loading = useTagIsRenaming();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open onOpenChange={hideModal}>
|
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>{t('common.rename')}</DialogTitle>
|
|
||||||
</DialogHeader>
|
|
||||||
<RenameForm
|
|
||||||
initialName={initialName}
|
|
||||||
hideModal={hideModal}
|
|
||||||
></RenameForm>
|
|
||||||
<DialogFooter>
|
|
||||||
<LoadingButton type="submit" form={TagRenameId} loading={loading}>
|
|
||||||
{t('common.save')}
|
|
||||||
</LoadingButton>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import {
|
|
||||||
Form,
|
|
||||||
FormControl,
|
|
||||||
FormField,
|
|
||||||
FormItem,
|
|
||||||
FormLabel,
|
|
||||||
FormMessage,
|
|
||||||
} from '@/components/ui/form';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { useRenameTag } from '@/hooks/knowledge-hooks';
|
|
||||||
import { IModalProps } from '@/interfaces/common';
|
|
||||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
export function RenameForm({
|
|
||||||
initialName,
|
|
||||||
hideModal,
|
|
||||||
}: IModalProps<any> & { initialName: string }) {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const FormSchema = z.object({
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, {
|
|
||||||
message: t('common.namePlaceholder'),
|
|
||||||
})
|
|
||||||
.trim(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof FormSchema>>({
|
|
||||||
resolver: zodResolver(FormSchema),
|
|
||||||
defaultValues: {
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const { renameTag } = useRenameTag();
|
|
||||||
|
|
||||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
|
||||||
const ret = await renameTag({ fromTag: initialName, toTag: data.name });
|
|
||||||
if (ret) {
|
|
||||||
hideModal?.();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
form.setValue('name', initialName);
|
|
||||||
}, [form, initialName]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={form.handleSubmit(onSubmit)}
|
|
||||||
className="space-y-6"
|
|
||||||
id={TagRenameId}
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t('common.name')}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input
|
|
||||||
placeholder={t('common.namePlaceholder')}
|
|
||||||
{...field}
|
|
||||||
autoComplete="off"
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
import { Segmented } from 'antd';
|
|
||||||
import { SegmentedLabeledOption } from 'antd/es/segmented';
|
|
||||||
import { upperFirst } from 'lodash';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { TagTable } from './tag-table';
|
|
||||||
import { TagWordCloud } from './tag-word-cloud';
|
|
||||||
|
|
||||||
enum TagType {
|
|
||||||
Cloud = 'cloud',
|
|
||||||
Table = 'table',
|
|
||||||
}
|
|
||||||
|
|
||||||
const TagContentMap = {
|
|
||||||
[TagType.Cloud]: <TagWordCloud></TagWordCloud>,
|
|
||||||
[TagType.Table]: <TagTable></TagTable>,
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TagTabs() {
|
|
||||||
const [value, setValue] = useState<TagType>(TagType.Cloud);
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const options: SegmentedLabeledOption[] = [TagType.Cloud, TagType.Table].map(
|
|
||||||
(x) => ({
|
|
||||||
label: t(`knowledgeConfiguration.tag${upperFirst(x)}`),
|
|
||||||
value: x,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="mt-4">
|
|
||||||
<Segmented
|
|
||||||
value={value}
|
|
||||||
options={options}
|
|
||||||
onChange={(val) => setValue(val as TagType)}
|
|
||||||
/>
|
|
||||||
{TagContentMap[value]}
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
import { useFetchTagList } from '@/hooks/knowledge-hooks';
|
|
||||||
import { Chart } from '@antv/g2';
|
|
||||||
import { sumBy } from 'lodash';
|
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
||||||
|
|
||||||
export function TagWordCloud() {
|
|
||||||
const domRef = useRef<HTMLDivElement>(null);
|
|
||||||
let chartRef = useRef<Chart>();
|
|
||||||
const { list } = useFetchTagList();
|
|
||||||
|
|
||||||
const { list: tagList } = useMemo(() => {
|
|
||||||
const nextList = list.sort((a, b) => b[1] - a[1]).slice(0, 256);
|
|
||||||
|
|
||||||
return {
|
|
||||||
list: nextList.map((x) => ({ text: x[0], value: x[1], name: x[0] })),
|
|
||||||
sumValue: sumBy(nextList, (x: [string, number]) => x[1]),
|
|
||||||
length: nextList.length,
|
|
||||||
};
|
|
||||||
}, [list]);
|
|
||||||
|
|
||||||
const renderWordCloud = useCallback(() => {
|
|
||||||
if (domRef.current) {
|
|
||||||
chartRef.current = new Chart({ container: domRef.current });
|
|
||||||
|
|
||||||
chartRef.current.options({
|
|
||||||
type: 'wordCloud',
|
|
||||||
autoFit: true,
|
|
||||||
layout: {
|
|
||||||
fontSize: [10, 50],
|
|
||||||
// fontSize: (d: any) => {
|
|
||||||
// if (d.value) {
|
|
||||||
// return (d.value / sumValue) * 100 * (length / 10);
|
|
||||||
// }
|
|
||||||
// return 0;
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: 'inline',
|
|
||||||
value: tagList,
|
|
||||||
},
|
|
||||||
encode: { color: 'text' },
|
|
||||||
legend: false,
|
|
||||||
tooltip: {
|
|
||||||
title: 'name', // title
|
|
||||||
items: ['value'], // data item
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
chartRef.current.render();
|
|
||||||
}
|
|
||||||
}, [tagList]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
renderWordCloud();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
chartRef.current?.destroy();
|
|
||||||
};
|
|
||||||
}, [renderWordCloud]);
|
|
||||||
|
|
||||||
return <div ref={domRef} className="w-full h-[38vh]"></div>;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
const getImageName = (prefix: string, length: number) =>
|
|
||||||
new Array(length)
|
|
||||||
.fill(0)
|
|
||||||
.map((x, idx) => `chunk-method/${prefix}-0${idx + 1}`);
|
|
||||||
|
|
||||||
export const ImageMap = {
|
|
||||||
book: getImageName('book', 4),
|
|
||||||
laws: getImageName('law', 2),
|
|
||||||
manual: getImageName('manual', 4),
|
|
||||||
picture: getImageName('media', 2),
|
|
||||||
naive: getImageName('naive', 2),
|
|
||||||
paper: getImageName('paper', 2),
|
|
||||||
presentation: getImageName('presentation', 2),
|
|
||||||
qa: getImageName('qa', 2),
|
|
||||||
resume: getImageName('resume', 2),
|
|
||||||
table: getImageName('table', 2),
|
|
||||||
one: getImageName('one', 2),
|
|
||||||
knowledge_graph: getImageName('knowledge-graph', 2),
|
|
||||||
tag: getImageName('tag', 2),
|
|
||||||
};
|
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { IconFontFill } from '@/components/icon-font';
|
||||||
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
import { RAGFlowAvatar } from '@/components/ragflow-avatar';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { useSecondPathName } from '@/hooks/route-hook';
|
import { useSecondPathName } from '@/hooks/route-hook';
|
||||||
|
|||||||
@ -30,7 +30,6 @@ export enum Routes {
|
|||||||
ProfilePrompt = `${ProfileSetting}${Prompt}`,
|
ProfilePrompt = `${ProfileSetting}${Prompt}`,
|
||||||
ProfileProfile = `${ProfileSetting}${Profile}`,
|
ProfileProfile = `${ProfileSetting}${Profile}`,
|
||||||
DatasetTesting = '/testing',
|
DatasetTesting = '/testing',
|
||||||
DatasetSetting = '/setting',
|
|
||||||
Chunk = '/chunk',
|
Chunk = '/chunk',
|
||||||
ChunkResult = `${Chunk}${Chunk}`,
|
ChunkResult = `${Chunk}${Chunk}`,
|
||||||
Parsed = '/parsed',
|
Parsed = '/parsed',
|
||||||
@ -262,10 +261,6 @@ const routes = [
|
|||||||
path: `${Routes.Dataset}/:id`,
|
path: `${Routes.Dataset}/:id`,
|
||||||
component: `@/pages${Routes.Dataset}`,
|
component: `@/pages${Routes.Dataset}`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: `${Routes.DatasetBase}${Routes.DatasetSetting}/:id`,
|
|
||||||
component: `@/pages${Routes.DatasetBase}${Routes.DatasetSetting}`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: `${Routes.DatasetBase}${Routes.DatasetTesting}/:id`,
|
path: `${Routes.DatasetBase}${Routes.DatasetTesting}/:id`,
|
||||||
component: `@/pages${Routes.DatasetBase}${Routes.DatasetTesting}`,
|
component: `@/pages${Routes.DatasetBase}${Routes.DatasetTesting}`,
|
||||||
|
|||||||
@ -119,7 +119,7 @@
|
|||||||
/* --state-success: #3ba05c; */
|
/* --state-success: #3ba05c; */
|
||||||
--state-success: 59 160 92;
|
--state-success: 59 160 92;
|
||||||
/* --state-warning: #767573; */
|
/* --state-warning: #767573; */
|
||||||
--state-warning: 118 117 115;
|
--state-warning: 250 173 20;
|
||||||
--state-error: 216 73 75;
|
--state-error: 216 73 75;
|
||||||
|
|
||||||
--team-group: #5ab77e;
|
--team-group: #5ab77e;
|
||||||
|
|||||||
Reference in New Issue
Block a user