From 2078d88c28230bca54f86dcaee7960122d6ba609 Mon Sep 17 00:00:00 2001 From: balibabu Date: Thu, 9 Oct 2025 13:55:36 +0800 Subject: [PATCH] Feat: Modify the translation file of the workflow #9869 (#10430) ### What problem does this PR solve? Feat: Modify the translation file of the workflow #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/hooks/use-knowledge-request.ts | 4 ++-- web/src/locales/en.ts | 24 +++++++++++++++---- web/src/locales/zh.ts | 3 ++- .../form/parser-form/common-form-fields.tsx | 9 ++++--- .../form/parser-form/image-form-fields.tsx | 7 ++++-- .../data-flow/form/parser-form/index.tsx | 14 +++++++---- web/src/pages/data-flow/index.tsx | 11 ++++++++- 7 files changed, 53 insertions(+), 19 deletions(-) diff --git a/web/src/hooks/use-knowledge-request.ts b/web/src/hooks/use-knowledge-request.ts index d99167338..5caaa6633 100644 --- a/web/src/hooks/use-knowledge-request.ts +++ b/web/src/hooks/use-knowledge-request.ts @@ -144,7 +144,7 @@ export const useFetchNextKnowledgeListByPage = () => { const onInputChange: React.ChangeEventHandler = useCallback( (e) => { - // setPagination({ page: 1 }); // TODO: 这里导致重复请求 + // setPagination({ page: 1 }); // TODO: This results in repeated requests handleInputChange(e); }, [handleInputChange], @@ -323,7 +323,7 @@ export const useRemoveKnowledgeGraph = () => { if (data.code === 0) { message.success(i18n.t(`message.deleted`)); queryClient.invalidateQueries({ - queryKey: ['fetchKnowledgeGraph'], + queryKey: [KnowledgeApiAction.FetchKnowledgeGraph], }); } return data?.code; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index ef9dc4095..e160af555 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1531,7 +1531,7 @@ This delimiter is used to split the input text into several text pieces echo of agentDescription: 'Builds agent components equipped with reasoning, tool usage, and multi-agent collaboration. ', maxRecords: 'Max records', - createAgent: 'Create Agent', + createAgent: 'Agent flow', stringTransform: 'Text Processing', userFillUp: 'Await Response', userFillUpDescription: `Pauses the workflow and waits for the user's message before continuing.`, @@ -1696,6 +1696,7 @@ This delimiter is used to split the input text into several text pieces echo of parserDescription: 'Extracts raw text and structure from files for downstream processing.', tokenizer: 'Tokenizer', + tokenizerRequired: 'Please add the Tokenizer node first', tokenizerDescription: 'Transforms text into the required data structure (e.g., vector embeddings for Embedding Search) depending on the chosen search method.', splitter: 'Token Splitter', @@ -1709,15 +1710,25 @@ This delimiter is used to split the input text into several text pieces echo of 'Use an LLM to extract structured insights from document chunks—such as summaries, classifications, etc.', outputFormat: 'Output format', lang: 'Language', - fileFormats: 'File formats', - fields: 'Fields', + fileFormats: 'File format', + fileFormatOptions: { + pdf: 'PDF', + spreadsheet: 'Spreadsheet', + image: 'Image', + email: 'Email', + 'text&markdown': 'Text & Markup', + word: 'Word', + slides: 'PPT', + audio: 'Audio', + }, + fields: 'Field', addParser: 'Add Parser', hierarchy: 'Hierarchy', regularExpressions: 'Regular Expressions', overlappedPercent: 'Overlapped percent', searchMethod: 'Search method', begin: 'File', - parserMethod: 'Parser method', + parserMethod: 'Parsing method', systemPrompt: 'System Prompt', systemPromptPlaceholder: 'Enter system prompt for image analysis, if empty the system default value will be used', @@ -1785,11 +1796,14 @@ Important structured information may include: names, dates, locations, events, k }, filenameEmbeddingWeight: 'Filename embedding weight', tokenizerFieldsOptions: { - text: 'Text', + text: 'Processed Text', keywords: 'Keywords', questions: 'Questions', summary: 'Augmented Context', }, + imageParseMethodOptions: { + ocr: 'OCR', + }, }, datasetOverview: { downloadTip: 'Files being downloaded from data sources. ', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 7d79476ae..a57283192 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1454,7 +1454,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 addAgent: '添加智能体', agentDescription: '构建具备推理、工具调用和多智能体协同的智能体组件。', maxRecords: '最大记录数', - createAgent: '创建智能体', + createAgent: '智能体流程', stringTransform: '文本处理', userFillUp: '等待输入', userFillUpDescription: `此组件会暂停当前的流程并等待用户发送消息,接收到消息之后再进行之后的流程。`, @@ -1611,6 +1611,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 parser: '解析器', parserDescription: '从文件中提取原始文本和结构以供下游处理。', tokenizer: '分词器', + tokenizerRequired: '请先添加Tokenizer节点', tokenizerDescription: '根据所选的搜索方法,将文本转换为所需的数据结构(例如,用于嵌入搜索的向量嵌入)。', splitter: '分词器拆分器', diff --git a/web/src/pages/data-flow/form/parser-form/common-form-fields.tsx b/web/src/pages/data-flow/form/parser-form/common-form-fields.tsx index 46809ad2c..dc7039781 100644 --- a/web/src/pages/data-flow/form/parser-form/common-form-fields.tsx +++ b/web/src/pages/data-flow/form/parser-form/common-form-fields.tsx @@ -6,9 +6,9 @@ import { SelectWithSearchFlagOptionType, } from '@/components/originui/select-with-search'; import { RAGFlowFormItem } from '@/components/ragflow-form'; -import { buildOptions } from '@/utils/form'; +import { upperFirst } from 'lodash'; import { useTranslation } from 'react-i18next'; -import { FileType, OutputFormatMap } from '../../constant'; +import { FileType, OutputFormatMap, PdfOutputFormat } from '../../constant'; import { CommonProps } from './interface'; import { buildFieldNameWithPrefix } from './utils'; @@ -16,7 +16,10 @@ function buildOutputOptionsFormatMap() { return Object.entries(OutputFormatMap).reduce< Record >((pre, [key, value]) => { - pre[key] = buildOptions(value); + pre[key] = Object.values(value).map((v) => ({ + label: v === PdfOutputFormat.Json ? 'JSON' : upperFirst(v), + value: v, + })); return pre; }, {}); } diff --git a/web/src/pages/data-flow/form/parser-form/image-form-fields.tsx b/web/src/pages/data-flow/form/parser-form/image-form-fields.tsx index 4cff99ea7..8dbde3a96 100644 --- a/web/src/pages/data-flow/form/parser-form/image-form-fields.tsx +++ b/web/src/pages/data-flow/form/parser-form/image-form-fields.tsx @@ -11,11 +11,14 @@ import { CommonProps } from './interface'; import { useSetInitialLanguage } from './use-set-initial-language'; import { buildFieldNameWithPrefix } from './utils'; -const options = buildOptions(ImageParseMethod); - export function ImageFormFields({ prefix }: CommonProps) { const { t } = useTranslation(); const form = useFormContext(); + const options = buildOptions( + ImageParseMethod, + t, + 'dataflow.imageParseMethodOptions', + ); const parseMethodName = buildFieldNameWithPrefix('parse_method', prefix); const parseMethod = useWatch({ diff --git a/web/src/pages/data-flow/form/parser-form/index.tsx b/web/src/pages/data-flow/form/parser-form/index.tsx index 2d5f540e2..836f5414e 100644 --- a/web/src/pages/data-flow/form/parser-form/index.tsx +++ b/web/src/pages/data-flow/form/parser-form/index.tsx @@ -36,10 +36,6 @@ import { VideoFormFields } from './video-form-fields'; const outputList = buildOutputList(initialParserValues.outputs); -const FileFormatOptions = buildOptions(FileType).filter( - (x) => x.value !== FileType.Video, // Temporarily hide the video option -); - const FileFormatWidgetMap = { [FileType.PDF]: PdfFormFields, [FileType.Video]: VideoFormFields, @@ -83,6 +79,14 @@ function ParserItem({ name, index, fieldLength, remove }: ParserItemProps) { const values = form.getValues(); const parserList = values.setups.slice(); // Adding, deleting, or modifying the parser array will not change the reference. + const FileFormatOptions = buildOptions( + FileType, + t, + 'dataflow.fileFormatOptions', + ).filter( + (x) => x.value !== FileType.Video, // Temporarily hide the video option + ); + const filteredFileFormatOptions = useMemo(() => { const otherFileFormatList = parserList .filter((_, idx) => idx !== index) @@ -91,7 +95,7 @@ function ParserItem({ name, index, fieldLength, remove }: ParserItemProps) { return FileFormatOptions.filter((x) => { return !otherFileFormatList.includes(x.value); }); - }, [index, parserList]); + }, [FileFormatOptions, index, parserList]); const Widget = typeof fileFormat === 'string' && fileFormat in FileFormatWidgetMap diff --git a/web/src/pages/data-flow/index.tsx b/web/src/pages/data-flow/index.tsx index cdca3ebae..f536f8580 100644 --- a/web/src/pages/data-flow/index.tsx +++ b/web/src/pages/data-flow/index.tsx @@ -15,6 +15,7 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; +import message from '@/components/ui/message'; import { useSetModalState } from '@/hooks/common-hooks'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { ReactFlowProvider } from '@xyflow/react'; @@ -30,6 +31,7 @@ import { ComponentPropsWithoutRef, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import DataFlowCanvas from './canvas'; import { DropdownProvider } from './canvas/context'; +import { Operator } from './constant'; import { LogContext } from './context'; import { useCancelCurrentDataflow } from './hooks/use-cancel-dataflow'; import { useHandleExportOrImportJsonFile } from './hooks/use-export-json'; @@ -42,6 +44,7 @@ import { } from './hooks/use-save-graph'; import { LogSheet } from './log-sheet'; import { SettingDialog } from './setting-dialog'; +import useGraphStore from './store'; import { useAgentHistoryManager } from './use-agent-history-manager'; import { VersionDialog } from './version-dialog'; @@ -101,8 +104,14 @@ export default function DataFlow() { const [uploadedFileData, setUploadedFileData] = useState>(); + const findNodeByName = useGraphStore((state) => state.findNodeByName); const handleRunAgent = useCallback(() => { + if (!findNodeByName(Operator.Tokenizer)) { + message.warning(t('dataflow.tokenizerRequired')); + return; + } + if (isParsing) { // show log sheet showLogSheet(); @@ -110,7 +119,7 @@ export default function DataFlow() { hideLogSheet(); handleRun(); } - }, [handleRun, hideLogSheet, isParsing, showLogSheet]); + }, [findNodeByName, handleRun, hideLogSheet, isParsing, showLogSheet, t]); const { handleCancel } = useCancelCurrentDataflow({ messageId,