diff --git a/web/src/components/data-pipeline-select/index.tsx b/web/src/components/data-pipeline-select/index.tsx new file mode 100644 index 000000000..523dbdef4 --- /dev/null +++ b/web/src/components/data-pipeline-select/index.tsx @@ -0,0 +1,76 @@ +import { useTranslate } from '@/hooks/common-hooks'; +import { buildSelectOptions } from '@/utils/component-util'; +import { ArrowUpRight } from 'lucide-react'; +import { useFormContext } from 'react-hook-form'; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '../ui/form'; +import { RAGFlowSelect } from '../ui/select'; + +interface IProps { + toDataPipeline?: () => void; + formFieldName: string; +} + +const data = [ + { id: '1', name: 'data-pipeline-1' }, + { id: '2', name: 'data-pipeline-2' }, + { id: '3', name: 'data-pipeline-3' }, + { id: '4', name: 'data-pipeline-4' }, +]; +export function DataFlowItem(props: IProps) { + const { toDataPipeline, formFieldName } = props; + const { t } = useTranslate('knowledgeConfiguration'); + const form = useFormContext(); + const toDataPipLine = () => { + // window.open('/data-pipeline'); + + toDataPipeline?.(); + }; + const options = buildSelectOptions(data, 'id', 'name'); + return ( + ( + +
+
+ + {t('dataFlow')} + +
+ {t('buildItFromScratch')} + +
+
+ +
+ + + +
+
+
+
+ +
+
+ )} + /> + ); +} diff --git a/web/src/components/ragflow-form.tsx b/web/src/components/ragflow-form.tsx index 4151e6fef..384565755 100644 --- a/web/src/components/ragflow-form.tsx +++ b/web/src/components/ragflow-form.tsx @@ -16,6 +16,7 @@ type RAGFlowFormItemProps = { children: ReactNode | ((field: ControllerRenderProps) => ReactNode); horizontal?: boolean; required?: boolean; + labelClassName?: string; }; export function RAGFlowFormItem({ @@ -25,6 +26,7 @@ export function RAGFlowFormItem({ children, horizontal = false, required = false, + labelClassName, }: RAGFlowFormItemProps) { const form = useFormContext(); return ( @@ -40,7 +42,7 @@ export function RAGFlowFormItem({ {label} diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 8d9a9c3f1..4ce559334 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -261,12 +261,13 @@ export default { reRankModelWaring: 'Re-rank model is very time consuming.', }, knowledgeConfiguration: { + default: 'Default', + dataPipeline: 'Data Pipeline', + linkDataPipeline: 'Link Data Pipeline', enableAutoGenerate: 'Enable Auto Generate', teamPlaceholder: 'Please select a team.', dataFlowPlaceholder: 'Please select a data flow.', buildItFromScratch: 'Build it from scratch', - useRAPTORToEnhanceRetrieval: 'Use RAPTOR to Enhance Retrieval', - extractKnowledgeGraph: 'Extract Knowledge Graph', dataFlow: 'Data Flow', parseType: 'Parse Type', manualSetup: 'Manual Setup', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 7e9895756..693d6acc3 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -246,12 +246,13 @@ export default { theDocumentBeingParsedCannotBeDeleted: '正在解析的文档不能被删除', }, knowledgeConfiguration: { + default: '默认', + dataPipeline: '数据流', + linkDataPipeline: '关联数据流', enableAutoGenerate: '是否启用自动生成', teamPlaceholder: '请选择团队', dataFlowPlaceholder: '请选择数据流', buildItFromScratch: '去Scratch构建', - useRAPTORToEnhanceRetrieval: '使用 RAPTOR 提升检索效果', - extractKnowledgeGraph: '知识图谱提取', dataFlow: '数据流', parseType: '切片方法', manualSetup: '手动设置', diff --git a/web/src/pages/dataset/dataset-overview/overview-table.tsx b/web/src/pages/dataset/dataset-overview/overview-table.tsx index d02eae615..0efd87cb8 100644 --- a/web/src/pages/dataset/dataset-overview/overview-table.tsx +++ b/web/src/pages/dataset/dataset-overview/overview-table.tsx @@ -317,7 +317,8 @@ const FileLogsTable: FC = ({ state: 'Running', startTime: '14/03/2025 14:53:39', duration: '800', - details: 'PRD for DealBees 1.2 (1).text', + details: + '\n17:43:21 Task has been received.\n17:43:25 Page(1~100000001): Start to parse.\n17:43:25 Page(1~100000001): Start to tag for every chunk ...\n17:43:45 Page(1~100000001): Tagging 2 chunks completed in 18.99s\n17:43:45 Page(1~100000001): Generate 2 chunks\n17:43:55 Page(1~100000001): Embedding chunks (10.60s)\n17:43:55 Page(1~100000001): Indexing done (0.07s). Task done (33.97s)\n17:43:58 created task raptor\n17:43:58 Task has been received.\n17:44:36 Cluster one layer: 2 -> 1\n17:44:36 Indexing done (0.05s). Task done (37.88s)\n17:44:40 created task graphrag\n17:44:41 Task has been received.\n17:50:57 Entities extraction of chunk 0 1/3 done, 25 nodes, 26 edges, 14893 tokens.\n17:56:01 [ERROR][Exception]: Operation timed out after 7200 seconds and 1 attempts.', }; return (
diff --git a/web/src/pages/dataset/dataset-setting/chunk-method-form.tsx b/web/src/pages/dataset/dataset-setting/chunk-method-form.tsx deleted file mode 100644 index 62462a29d..000000000 --- a/web/src/pages/dataset/dataset-setting/chunk-method-form.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Button } from '@/components/ui/button'; -import { useFormContext } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; - -import { NaiveConfiguration } from './naive'; -import { SavingButton } from './saving-button'; - -export function ChunkMethodForm() { - const form = useFormContext(); - const { t } = useTranslation(); - - return ( -
-
- -
-
- - -
-
- ); -} diff --git a/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx b/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx new file mode 100644 index 000000000..07a36e1e7 --- /dev/null +++ b/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx @@ -0,0 +1,79 @@ +import { RAGFlowAvatar } from '@/components/ragflow-avatar'; +import { Button } from '@/components/ui/button'; +import { Link, Route, Settings2, Unlink } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; + +interface DataPipelineItemProps { + name: string; + avatar?: string; + isDefault?: boolean; + linked?: boolean; +} +const DataPipelineItem = (props: DataPipelineItemProps) => { + const { t } = useTranslation(); + const { name, avatar, isDefault, linked } = props; + return ( +
+
+ +
{name}
+ {isDefault && ( +
+ {t('knowledgeConfiguration.default')} +
+ )} +
+
+ + +
+
+ ); +}; +const LinkDataPipeline = () => { + const { t } = useTranslation(); + const testNode = [ + { + name: 'Data Pipeline 1', + avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4', + isDefault: true, + linked: true, + }, + { + name: 'Data Pipeline 2', + avatar: 'https://avatars.githubusercontent.com/u/10656201?v=4', + linked: false, + }, + ]; + return ( +
+
+
+ + {t('knowledgeConfiguration.dataPipeline')} +
+
+
+ Manage data pipeline linkage with this dataset +
+ +
+
+
+ {testNode.map((item) => ( + + ))} +
+
+ ); +}; +export default LinkDataPipeline; diff --git a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx index 8b2e3c589..6c36f1801 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx @@ -10,7 +10,6 @@ import { RAGFlowSelect } from '@/components/ui/select'; import { Switch } from '@/components/ui/switch'; import { useTranslate } from '@/hooks/common-hooks'; import { cn } from '@/lib/utils'; -import { ArrowUpRight } from 'lucide-react'; import { useFormContext } from 'react-hook-form'; import { useHasParsedDocument, @@ -70,8 +69,13 @@ export function EmbeddingModelItem({ line = 1 }: { line?: 1 | 2 }) { control={form.control} name={'embd_id'} render={({ field }) => ( - -
+ +
( - -
-
- - {t('dataFlow')} - -
- {t('buildItFromScratch')} - -
-
- -
- - - -
-
-
-
- -
-
- )} - /> - ); -} - -export function DataExtractKnowledgeItem() { - const { t } = useTranslate('knowledgeConfiguration'); - const form = useFormContext(); - - return ( - <> - {' '} - ( - -
- - {t('extractKnowledgeGraph')} - -
- - - -
-
-
-
- -
-
- )} - />{' '} - ( - -
- - {t('useRAPTORToEnhanceRetrieval')} - -
- - - -
-
-
-
- -
-
- )} - /> - - ); -} - -export function TeamItem() { - const { t } = useTranslate('knowledgeConfiguration'); - const form = useFormContext(); - - return ( - ( - -
- - * - {t('team')} - -
- - - -
-
-
-
- -
-
- )} - /> - ); -} - export function EnableAutoGenerateItem() { const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); diff --git a/web/src/pages/dataset/dataset-setting/general-form.tsx b/web/src/pages/dataset/dataset-setting/general-form.tsx index f7dc59e8b..10aa31d82 100644 --- a/web/src/pages/dataset/dataset-setting/general-form.tsx +++ b/web/src/pages/dataset/dataset-setting/general-form.tsx @@ -17,7 +17,7 @@ export function GeneralForm() { const { t } = useTranslation(); return ( -
+ <> -
+ ); } diff --git a/web/src/pages/dataset/dataset-setting/index.tsx b/web/src/pages/dataset/dataset-setting/index.tsx index 33fd081ac..0d24a79d5 100644 --- a/web/src/pages/dataset/dataset-setting/index.tsx +++ b/web/src/pages/dataset/dataset-setting/index.tsx @@ -1,3 +1,6 @@ +import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields'; +import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields'; +import { Button } from '@/components/ui/button'; import Divider from '@/components/ui/divider'; import { Form } from '@/components/ui/form'; import { DocumentParserType } from '@/constants/knowledge'; @@ -7,11 +10,12 @@ import { useForm } 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 LinkDataPipeline from './components/link-data-pipeline'; +import { MainContainer } from './configuration-form-container'; import { formSchema } from './form-schema'; import { GeneralForm } from './general-form'; import { useFetchKnowledgeConfigurationOnMount } from './hooks'; - +import { SavingButton } from './saving-button'; const enum DocumentType { DeepDOC = 'DeepDOC', PlainText = 'Plain Text', @@ -77,10 +81,29 @@ export default function DatasetSettings() { onSubmit={form.handleSubmit(onSubmit)} className="space-y-6 flex-1" > -
- - - +
+ + + + + + + + + + +
+
+ +
diff --git a/web/src/pages/dataset/dataset-setting/naive.tsx b/web/src/pages/dataset/dataset-setting/naive.tsx deleted file mode 100644 index 1f15a9f6a..000000000 --- a/web/src/pages/dataset/dataset-setting/naive.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import GraphRagItems from '@/components/parse-configuration/graph-rag-form-fields'; -import RaptorFormFields from '@/components/parse-configuration/raptor-form-fields'; -import Divider from '@/components/ui/divider'; -import { - ConfigurationFormContainer, - MainContainer, -} from './configuration-form-container'; - -export function NaiveConfiguration() { - return ( - - - - - - - - - ); -} diff --git a/web/src/pages/datasets/dataset-creating-dialog.tsx b/web/src/pages/datasets/dataset-creating-dialog.tsx index 5bf28758b..d320a924e 100644 --- a/web/src/pages/datasets/dataset-creating-dialog.tsx +++ b/web/src/pages/datasets/dataset-creating-dialog.tsx @@ -1,3 +1,4 @@ +import { DataFlowItem } from '@/components/data-pipeline-select'; import { ButtonLoading } from '@/components/ui/button'; import { Dialog, @@ -15,17 +16,15 @@ import { FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; +import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { IModalProps } from '@/interfaces/common'; import { zodResolver } from '@hookform/resolvers/zod'; import { useForm, useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; import { - DataExtractKnowledgeItem, - DataFlowItem, EmbeddingModelItem, ParseTypeItem, - TeamItem, } from '../dataset/dataset-setting/configuration/common-item'; const FormId = 'dataset-creating-form'; @@ -58,6 +57,7 @@ export function InputForm({ onOk }: IModalProps) { control: form.control, name: 'parseType', }); + const { navigateToAgents } = useNavigatePage(); return (
) { {parseType === 2 && ( <> - - - + )} diff --git a/web/src/pages/datasets/process-log-modal.tsx b/web/src/pages/datasets/process-log-modal.tsx index 3b2c74b18..4d7315cd5 100644 --- a/web/src/pages/datasets/process-log-modal.tsx +++ b/web/src/pages/datasets/process-log-modal.tsx @@ -1,7 +1,9 @@ +import FileStatusBadge from '@/components/file-status-badge'; import { Button } from '@/components/ui/button'; import { Modal } from '@/components/ui/modal/modal'; import { useTranslate } from '@/hooks/common-hooks'; import React from 'react'; +import reactStringReplace from 'react-string-replace'; interface ProcessLogModalProps { visible: boolean; @@ -12,7 +14,7 @@ interface ProcessLogModalProps { fileSize: string; source: string; task: string; - state: 'Running' | 'Completed' | 'Failed' | 'Pending'; + state: 'Running' | 'Success' | 'Failed' | 'Pending'; startTime: string; endTime?: string; duration?: string; @@ -20,32 +22,6 @@ interface ProcessLogModalProps { }; } -const StatusTag: React.FC<{ state: string }> = ({ state }) => { - const getTagStyle = () => { - switch (state) { - case 'Running': - return 'bg-green-500 text-green-100'; - case 'Completed': - return 'bg-blue-500 text-blue-100'; - case 'Failed': - return 'bg-red-500 text-red-100'; - case 'Pending': - return 'bg-yellow-500 text-yellow-100'; - default: - return 'bg-gray-500 text-gray-100'; - } - }; - - return ( - - - {state} - - ); -}; - const InfoItem: React.FC<{ label: string; value: string | React.ReactNode; @@ -65,6 +41,24 @@ const ProcessLogModal: React.FC = ({ taskInfo, }) => { const { t } = useTranslate('knowledgeDetails'); + const replaceText = (text: string) => { + // Remove duplicate \n + const nextText = text.replace(/(\n)\1+/g, '$1'); + + const replacedText = reactStringReplace( + nextText, + /(\[ERROR\].+\s)/g, + (match, i) => { + return ( + + {match} + + ); + }, + ); + + return replacedText; + }; return ( = ({ -
{/* Right Column */}
- States + Status
- +
@@ -108,6 +101,17 @@ const ProcessLogModal: React.FC = ({ />
+ {/* */} +
+
Details
+
+
    +
    + {replaceText(taskInfo.details)} +
    +
+
+
); diff --git a/web/src/utils/component-util.ts b/web/src/utils/component-util.ts index 724be1caa..954b721a3 100644 --- a/web/src/utils/component-util.ts +++ b/web/src/utils/component-util.ts @@ -1,3 +1,10 @@ -export function buildSelectOptions(list: Array) { +export function buildSelectOptions( + list: Array, + keyName?: string, + valueName?: string, +) { + if (keyName && valueName) { + return list.map((x) => ({ label: x[valueName], value: x[keyName] })); + } return list.map((x) => ({ label: x, value: x })); } diff --git a/web/tailwind.css b/web/tailwind.css index 67a188cfd..b1ccf1fa7 100644 --- a/web/tailwind.css +++ b/web/tailwind.css @@ -291,8 +291,8 @@ @layer utilities { .scrollbar-auto { /* hide scrollbar */ - scrollbar-width: none; - scrollbar-color: transparent transparent; + scrollbar-width: thin; + scrollbar-color: var(--border-default) var(--bg-card); } .scrollbar-auto::-webkit-scrollbar {