From fa3e90c72ec027737b5af87e8b58d45c29208679 Mon Sep 17 00:00:00 2001 From: BlueYu-0221 <13072185617@163.com> Date: Thu, 19 Jun 2025 16:40:30 +0800 Subject: [PATCH] Refactor: Datasets UI #3221 (#8349) ### What problem does this PR solve? Refactor Datasets UI #3221. ### Type of change - [X] New Feature (non-breaking change which adds functionality) --- web/src/components/cross-language-item-ui.tsx | 48 ++ web/src/components/delimiter-form-field.tsx | 38 +- web/src/components/edit-tag/index.less | 5 +- web/src/components/edit-tag/index.tsx | 30 +- .../components/entity-types-form-field.tsx | 21 +- .../components/excel-to-html-form-field.tsx | 43 +- .../layout-recognize-form-field.tsx | 42 +- web/src/components/originui/input.tsx | 25 + web/src/components/page-rank-form-field.tsx | 2 +- .../graph-rag-form-fields.tsx | 142 +++--- .../raptor-form-fields-old.tsx | 146 ++++++ .../raptor-form-fields.tsx | 106 +++-- web/src/components/password-input/index.tsx | 58 +++ .../components/slider-input-form-field.tsx | 74 +-- web/src/components/ui/tabs-underlined.tsx | 64 +++ web/src/hooks/use-knowledge-request.ts | 11 +- web/src/interfaces/database/user-setting.ts | 1 + web/src/locales/de.ts | 1 + web/src/locales/en.ts | 1 + web/src/locales/es.ts | 1 + web/src/locales/id.ts | 1 + web/src/locales/ja.ts | 1 + web/src/locales/pt-br.ts | 1 + web/src/locales/vi.ts | 1 + web/src/locales/zh-traditional.ts | 1 + web/src/locales/zh.ts | 4 +- web/src/pages/chunk/index-old.tsx | 68 +++ .../pages/chunk/parsed-result/index-old.tsx | 10 + .../components/chunk-card/index.less | 34 ++ .../components/chunk-card/index.tsx | 101 ++++ .../components/chunk-creating-modal/index.tsx | 140 ++++++ .../chunk-creating-modal/tag-feature-item.tsx | 107 +++++ .../components/chunk-toolbar/index.tsx | 221 +++++++++ .../components/document-preview/hooks.ts | 55 +++ .../components/document-preview/index.less | 12 + .../components/document-preview/preview.tsx | 121 +++++ .../parsed-result/knowledge-chunk/constant.ts | 4 + .../parsed-result/knowledge-chunk/hooks.ts | 129 ++++++ .../parsed-result/knowledge-chunk/index.less | 92 ++++ .../parsed-result/knowledge-chunk/index.tsx | 202 ++++++++ .../parsed-result/knowledge-chunk/utils.ts | 24 + web/src/pages/dataset/index.tsx | 1 + .../dataset/setting/chunk-method-form.tsx | 50 +- .../setting/chunk-method-learn-more.tsx | 45 ++ .../setting/configuration/common-item.tsx | 72 +-- web/src/pages/dataset/setting/form-schema.ts | 84 ++-- .../pages/dataset/setting/general-form.tsx | 310 +++++++++---- web/src/pages/dataset/setting/index.tsx | 76 ++- web/src/pages/dataset/setting/tag-item.tsx | 58 ++- web/src/pages/dataset/sidebar/index.tsx | 9 +- web/src/pages/dataset/testing/index.tsx | 8 +- .../pages/dataset/testing/testing-form.tsx | 33 +- .../pages/profile-setting/profile/index.tsx | 438 ++++++++++++++++-- .../pages/profile-setting/sidebar/index.tsx | 11 +- web/src/routes.ts | 2 + 55 files changed, 2960 insertions(+), 425 deletions(-) create mode 100644 web/src/components/cross-language-item-ui.tsx create mode 100644 web/src/components/originui/input.tsx create mode 100644 web/src/components/parse-configuration/raptor-form-fields-old.tsx create mode 100644 web/src/components/password-input/index.tsx create mode 100644 web/src/components/ui/tabs-underlined.tsx create mode 100644 web/src/pages/chunk/index-old.tsx create mode 100644 web/src/pages/chunk/parsed-result/index-old.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/chunk-card/index.less create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/chunk-card/index.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/chunk-creating-modal/index.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/chunk-creating-modal/tag-feature-item.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/chunk-toolbar/index.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/document-preview/hooks.ts create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/document-preview/index.less create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/components/document-preview/preview.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/constant.ts create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/hooks.ts create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/index.less create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/index.tsx create mode 100644 web/src/pages/chunk/parsed-result/knowledge-chunk/utils.ts create mode 100644 web/src/pages/dataset/setting/chunk-method-learn-more.tsx diff --git a/web/src/components/cross-language-item-ui.tsx b/web/src/components/cross-language-item-ui.tsx new file mode 100644 index 000000000..3fbf5430d --- /dev/null +++ b/web/src/components/cross-language-item-ui.tsx @@ -0,0 +1,48 @@ +import { FormLabel } from '@/components/ui/form'; +import { MultiSelect } from '@/components/ui/multi-select'; +import { useTranslation } from 'react-i18next'; + +const Languages = [ + 'English', + 'Chinese', + 'Spanish', + 'French', + 'German', + 'Japanese', + 'Korean', +]; + +const options = Languages.map((x) => ({ label: x, value: x })); + +type CrossLanguageItemProps = { + name?: string | Array; + onChange: (arg: string[]) => void; +}; + +export const CrossLanguageItem = ({ + name = ['prompt_config', 'cross_languages'], + onChange = () => {}, +}: CrossLanguageItemProps) => { + const { t } = useTranslation(); + + return ( +
+
+ + {t('chat.crossLanguage')} + +
+ { + onChange(val); + }} + // defaultValue={field.value} + placeholder={t('fileManager.pleaseSelect')} + maxCount={100} + // {...field} + modalPopover + /> +
+ ); +}; diff --git a/web/src/components/delimiter-form-field.tsx b/web/src/components/delimiter-form-field.tsx index 479aa917c..cc1affd56 100644 --- a/web/src/components/delimiter-form-field.tsx +++ b/web/src/components/delimiter-form-field.tsx @@ -43,17 +43,33 @@ export function DelimiterFormField() { ( - - - {t('knowledgeDetails.delimiter')} - - - - - - - )} + render={({ field }) => { + if (typeof field.value === 'undefined') { + // default value set + form.setValue('parser_config.delimiter', '\n'); + } + return ( + +
+ + {t('knowledgeDetails.delimiter')} + +
+ + + +
+
+
+
+ +
+
+ ); + }} /> ); } diff --git a/web/src/components/edit-tag/index.less b/web/src/components/edit-tag/index.less index ef67d1023..1c4314cfb 100644 --- a/web/src/components/edit-tag/index.less +++ b/web/src/components/edit-tag/index.less @@ -2,14 +2,15 @@ display: flex; gap: 8px; flex-wrap: wrap; - width: 100%; + // width: 100%; margin-bottom: 8px; } .tag { max-width: 100%; margin: 0; - padding: 2px 20px 2px 4px; + padding: 2px 20px 0px 4px; + height: 26px; font-size: 14px; .textEllipsis(); position: relative; diff --git a/web/src/components/edit-tag/index.tsx b/web/src/components/edit-tag/index.tsx index 676ba7ff9..6a82351b3 100644 --- a/web/src/components/edit-tag/index.tsx +++ b/web/src/components/edit-tag/index.tsx @@ -74,7 +74,7 @@ const EditTag = ({ value = [], onChange }: EditTagsProps) => { }; return ( -
+
{Array.isArray(tagChild) && tagChild.length > 0 && ( { )} {inputVisible ? ( - +
+ +
) : ( - - - +
+ + + +
)}
); diff --git a/web/src/components/entity-types-form-field.tsx b/web/src/components/entity-types-form-field.tsx index 6cf3e364b..3a5de8ce5 100644 --- a/web/src/components/entity-types-form-field.tsx +++ b/web/src/components/entity-types-form-field.tsx @@ -24,12 +24,21 @@ export function EntityTypesFormField({ control={form.control} name={name} render={({ field }) => ( - - {t('entityTypes')} - - - - + +
+ + * {t('entityTypes')} + +
+ + + +
+
+
+
+ +
)} /> diff --git a/web/src/components/excel-to-html-form-field.tsx b/web/src/components/excel-to-html-form-field.tsx index 2e4ba1139..90fa5de81 100644 --- a/web/src/components/excel-to-html-form-field.tsx +++ b/web/src/components/excel-to-html-form-field.tsx @@ -17,18 +17,37 @@ export function ExcelToHtmlFormField() { ( - - {t('html4excel')} - - - - - - )} + render={({ field }) => { + if (typeof field.value === 'undefined') { + // default value set + form.setValue('parser_config.html4excel', false); + } + + return ( + +
+ + {t('html4excel')} + +
+ + + +
+
+
+
+ +
+
+ ); + }} /> ); } diff --git a/web/src/components/layout-recognize-form-field.tsx b/web/src/components/layout-recognize-form-field.tsx index 0c95ef660..50eccbffb 100644 --- a/web/src/components/layout-recognize-form-field.tsx +++ b/web/src/components/layout-recognize-form-field.tsx @@ -54,17 +54,37 @@ export function LayoutRecognizeFormField() { ( - - - {t('layoutRecognize')} - - - - - - - )} + render={({ field }) => { + if (typeof field.value === 'undefined') { + // default value set + form.setValue( + 'parser_config.layout_recognize', + form.formState.defaultValues?.parser_config?.layout_recognize ?? + 'DeepDOC', + ); + } + return ( + +
+ + {t('layoutRecognize')} + +
+ + + +
+
+
+
+ +
+
+ ); + }} /> ); } diff --git a/web/src/components/originui/input.tsx b/web/src/components/originui/input.tsx new file mode 100644 index 000000000..d8c125f91 --- /dev/null +++ b/web/src/components/originui/input.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +function Input({ className, type, ...props }: React.ComponentProps<'input'>) { + return ( + + ); +} + +export { Input }; diff --git a/web/src/components/page-rank-form-field.tsx b/web/src/components/page-rank-form-field.tsx index 4ce23d6fc..dce708b72 100644 --- a/web/src/components/page-rank-form-field.tsx +++ b/web/src/components/page-rank-form-field.tsx @@ -11,7 +11,7 @@ export function PageRankFormField() { tooltip={t('pageRankTip')} defaultValue={0} max={100} - min={1} + min={0} > ); } diff --git a/web/src/components/parse-configuration/graph-rag-form-fields.tsx b/web/src/components/parse-configuration/graph-rag-form-fields.tsx index 7448ca372..fddc65cf6 100644 --- a/web/src/components/parse-configuration/graph-rag-form-fields.tsx +++ b/web/src/components/parse-configuration/graph-rag-form-fields.tsx @@ -58,17 +58,27 @@ export function UseGraphRagFormField() { control={form.control} name="parser_config.graphrag.use_graphrag" render={({ field }) => ( - - - {t('useGraphRag')} - - - - - + +
+ + {t('useGraphRag')} + +
+ + + +
+
+
+
+ +
)} /> @@ -112,25 +122,33 @@ const GraphRagItems = ({ control={form.control} name="parser_config.graphrag.method" render={({ field }) => ( - -
, - )} - > - {t('graphRagMethod')} - - - - - + +
+
, + )} + > + {t('graphRagMethod')} + +
+ + + +
+ +
+
+ +
)} /> @@ -139,17 +157,27 @@ const GraphRagItems = ({ control={form.control} name="parser_config.graphrag.resolution" render={({ field }) => ( - - - {t('resolution')} - - - - - + +
+ + {t('resolution')} + +
+ + + +
+
+
+
+ +
)} /> @@ -158,17 +186,27 @@ const GraphRagItems = ({ control={form.control} name="parser_config.graphrag.community" render={({ field }) => ( - - - {t('community')} - - - - - + +
+ + {t('community')} + +
+ + + +
+
+
+
+ +
)} /> diff --git a/web/src/components/parse-configuration/raptor-form-fields-old.tsx b/web/src/components/parse-configuration/raptor-form-fields-old.tsx new file mode 100644 index 000000000..28cd79ced --- /dev/null +++ b/web/src/components/parse-configuration/raptor-form-fields-old.tsx @@ -0,0 +1,146 @@ +import { DocumentParserType } from '@/constants/knowledge'; +import { useTranslate } from '@/hooks/common-hooks'; +import random from 'lodash/random'; +import { Plus } from 'lucide-react'; +import { useCallback } from 'react'; +import { useFormContext, useWatch } from 'react-hook-form'; +import { SliderInputFormField } from '../slider-input-form-field'; +import { Button } from '../ui/button'; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '../ui/form'; +import { Input } from '../ui/input'; +import { Switch } from '../ui/switch'; +import { Textarea } from '../ui/textarea'; + +export const excludedParseMethods = [ + DocumentParserType.Table, + DocumentParserType.Resume, + DocumentParserType.One, + DocumentParserType.Picture, + DocumentParserType.KnowledgeGraph, + DocumentParserType.Qa, + DocumentParserType.Tag, +]; + +export const showRaptorParseConfiguration = ( + parserId: DocumentParserType | undefined, +) => { + return !excludedParseMethods.some((x) => x === parserId); +}; + +export const excludedTagParseMethods = [ + DocumentParserType.Table, + DocumentParserType.KnowledgeGraph, + DocumentParserType.Tag, +]; + +export const showTagItems = (parserId: DocumentParserType) => { + return !excludedTagParseMethods.includes(parserId); +}; + +const UseRaptorField = 'parser_config.raptor.use_raptor'; +const RandomSeedField = 'parser_config.raptor.random_seed'; + +// The three types "table", "resume" and "one" do not display this configuration. + +const RaptorFormFields = () => { + const form = useFormContext(); + const { t } = useTranslate('knowledgeConfiguration'); + const useRaptor = useWatch({ name: UseRaptorField }); + + const handleGenerate = useCallback(() => { + form.setValue(RandomSeedField, random(10000)); + }, [form]); + + return ( + <> + ( + + {t('useRaptor')} + + + + + + )} + /> + {useRaptor && ( +
+ ( + + {t('prompt')} + +