From 435479adb3a3564d7f3cf7a43fa2cb81563ae1ec Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Wed, 12 Nov 2025 09:36:48 +0800 Subject: [PATCH] Fixes: Fixed some bugs #10703 (#11180) ### What problem does this PR solve? Fixes: Fixed some bugs #10703 - Removed S3 upload from the file upload component - Updated the dropdown menu style on the model provider page - Updated some model provider icons - Fixed other style issues ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- web/public/iconfont.js | 1 + .../assets/svg/data-source/google-drive.svg | 30 ++- web/src/assets/svg/llm/chat-minimax.svg | 1 - web/src/assets/svg/llm/gemini.svg | 115 +---------- web/src/assets/svg/llm/local-ai.svg | 32 ++- web/src/assets/svg/llm/stepfun.svg | 38 +--- web/src/components/back-button/index.tsx | 3 +- .../components/file-upload-dialog/index.tsx | 9 +- web/src/components/svg-icon.tsx | 14 +- web/src/components/ui/command.tsx | 2 +- web/src/components/ui/modal/modal.tsx | 4 +- web/src/constants/llm.ts | 4 +- web/src/hooks/llm-hooks.tsx | 1 + web/src/locales/en.ts | 2 + web/src/locales/zh.ts | 9 +- web/src/pages/login-next/index.tsx | 2 +- .../data-source/add-datasource-modal.tsx | 2 +- .../component/google-drive-token-field.tsx | 2 +- .../user-setting/data-source/contant.tsx | 190 +++++++++--------- .../setting-model/components/modal-card.tsx | 4 +- .../components/system-setting.tsx | 4 +- .../setting-model/components/un-add-model.tsx | 2 +- .../setting-model/components/used-model.tsx | 2 +- .../pages/user-setting/setting-model/hooks.ts | 6 +- .../user-setting/setting-model/index.tsx | 4 +- .../modal/api-key-modal/index.tsx | 9 +- 26 files changed, 190 insertions(+), 302 deletions(-) delete mode 100644 web/src/assets/svg/llm/chat-minimax.svg diff --git a/web/public/iconfont.js b/web/public/iconfont.js index 178288a11e..b7b426074c 100644 --- a/web/public/iconfont.js +++ b/web/public/iconfont.js @@ -1,6 +1,7 @@ (window._iconfont_svg_string_4909832 = '' + ` + diff --git a/web/src/assets/svg/data-source/google-drive.svg b/web/src/assets/svg/data-source/google-drive.svg index a8cefd5b28..74cf7493ea 100644 --- a/web/src/assets/svg/data-source/google-drive.svg +++ b/web/src/assets/svg/data-source/google-drive.svg @@ -1,8 +1,22 @@ - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/assets/svg/llm/chat-minimax.svg b/web/src/assets/svg/llm/chat-minimax.svg deleted file mode 100644 index 3ba8f7ff61..0000000000 --- a/web/src/assets/svg/llm/chat-minimax.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/web/src/assets/svg/llm/gemini.svg b/web/src/assets/svg/llm/gemini.svg index 91b0bf4cfc..f1cf357573 100644 --- a/web/src/assets/svg/llm/gemini.svg +++ b/web/src/assets/svg/llm/gemini.svg @@ -1,114 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Gemini \ No newline at end of file diff --git a/web/src/assets/svg/llm/local-ai.svg b/web/src/assets/svg/llm/local-ai.svg index 3be050a378..9dc6e6276e 100644 --- a/web/src/assets/svg/llm/local-ai.svg +++ b/web/src/assets/svg/llm/local-ai.svg @@ -1,17 +1,15 @@ - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + diff --git a/web/src/assets/svg/llm/stepfun.svg b/web/src/assets/svg/llm/stepfun.svg index 919ab7f0c3..70989521a5 100644 --- a/web/src/assets/svg/llm/stepfun.svg +++ b/web/src/assets/svg/llm/stepfun.svg @@ -1,37 +1 @@ - - - - +Stepfun \ No newline at end of file diff --git a/web/src/components/back-button/index.tsx b/web/src/components/back-button/index.tsx index 81c08532e4..c790d68828 100644 --- a/web/src/components/back-button/index.tsx +++ b/web/src/components/back-button/index.tsx @@ -1,4 +1,5 @@ import { cn } from '@/lib/utils'; +import { t } from 'i18next'; import { ArrowBigLeft } from 'lucide-react'; import React from 'react'; import { useNavigate } from 'umi'; @@ -33,7 +34,7 @@ const BackButton: React.FC = ({ {...props} > - {children || 'Back'} + {children || t('common.back')} ); }; diff --git a/web/src/components/file-upload-dialog/index.tsx b/web/src/components/file-upload-dialog/index.tsx index aea32b472c..5b3c514638 100644 --- a/web/src/components/file-upload-dialog/index.tsx +++ b/web/src/components/file-upload-dialog/index.tsx @@ -6,7 +6,6 @@ import { DialogHeader, DialogTitle, } from '@/components/ui/dialog'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { IModalProps } from '@/interfaces/common'; import { zodResolver } from '@hookform/resolvers/zod'; import { TFunction } from 'i18next'; @@ -102,7 +101,7 @@ export function FileUploadDialog({ {t('fileManager.uploadFile')} - + {/* {t('fileManager.local')} {t('fileManager.s3')} @@ -114,7 +113,11 @@ export function FileUploadDialog({ > {t('common.comingSoon')} - + */} + {t('common.save')} diff --git a/web/src/components/svg-icon.tsx b/web/src/components/svg-icon.tsx index 7aa79aa04c..d21e55aceb 100644 --- a/web/src/components/svg-icon.tsx +++ b/web/src/components/svg-icon.tsx @@ -68,6 +68,7 @@ export const LlmIcon = ({ LLMFactory.FishAudio, LLMFactory.TogetherAI, LLMFactory.Meituan, + LLMFactory.Longcat, ]; let icon = useMemo(() => { const icontemp = IconMap[name as keyof typeof IconMap]; @@ -84,7 +85,7 @@ export const LlmIcon = ({ const svgIcons = [ LLMFactory.LocalAI, // LLMFactory.VolcEngine, - LLMFactory.MiniMax, + // LLMFactory.MiniMax, LLMFactory.Gemini, LLMFactory.StepFun, // LLMFactory.DeerAPI, @@ -101,9 +102,16 @@ export const LlmIcon = ({ } return icon ? ( - + ) : ( - } /> + + // } /> ); }; diff --git a/web/src/components/ui/command.tsx b/web/src/components/ui/command.tsx index 698260b412..10caef77d4 100644 --- a/web/src/components/ui/command.tsx +++ b/web/src/components/ui/command.tsx @@ -15,7 +15,7 @@ const Command = React.forwardRef< handleCancel()} - className="px-2 py-1 border border-input rounded-md hover:bg-muted" + className="px-2 py-1 border border-border-button rounded-md hover:bg-bg-card hover:text-text-primary " > {cancelText ?? t('modal.cancelText')} @@ -132,7 +132,7 @@ const Modal: ModalType = ({ return (
diff --git a/web/src/constants/llm.ts b/web/src/constants/llm.ts index 6282dd1ef3..0f85140d5b 100644 --- a/web/src/constants/llm.ts +++ b/web/src/constants/llm.ts @@ -55,6 +55,7 @@ export enum LLMFactory { XAI = 'xAI', TokenPony = 'TokenPony', Meituan = 'Meituan', + Longcat = 'LongCat', CometAPI = 'CometAPI', DeerAPI = 'DeerAPI', Builtin = 'Builtin', @@ -74,7 +75,7 @@ export const IconMap = { [LLMFactory.VolcEngine]: 'volcengine', [LLMFactory.BaiChuan]: 'baichuan', [LLMFactory.Jina]: 'jina', - [LLMFactory.MiniMax]: 'chat-minimax', + [LLMFactory.MiniMax]: 'MiniMax', [LLMFactory.Mistral]: 'mistral', [LLMFactory.AzureOpenAI]: 'azure', [LLMFactory.Bedrock]: 'bedrock', @@ -118,6 +119,7 @@ export const IconMap = { [LLMFactory.XAI]: 'xai', [LLMFactory.TokenPony]: 'tokenpony', [LLMFactory.Meituan]: 'longcat', + [LLMFactory.Longcat]: 'longcat', [LLMFactory.CometAPI]: 'cometapi', [LLMFactory.DeerAPI]: 'deerapi', [LLMFactory.Builtin]: 'builtin', diff --git a/web/src/hooks/llm-hooks.tsx b/web/src/hooks/llm-hooks.tsx index 0da63f7b56..274f31ae06 100644 --- a/web/src/hooks/llm-hooks.tsx +++ b/web/src/hooks/llm-hooks.tsx @@ -402,6 +402,7 @@ export const useDeleteFactory = () => { queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); queryClient.invalidateQueries({ queryKey: ['myLlmListDetailed'] }); queryClient.invalidateQueries({ queryKey: ['factoryList'] }); + queryClient.invalidateQueries({ queryKey: ['llmList'] }); message.success(t('message.deleted')); } return data.code; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index e405efcd42..4a36f3a6f5 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1,6 +1,7 @@ export default { translation: { common: { + back: 'Back', noResults: 'No results.', selectPlaceholder: 'select value', selectAll: 'Select all', @@ -693,6 +694,7 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s tocEnhanceTip: ` During the parsing of the document, table of contents information was generated (see the 'Enable Table of Contents Extraction' option in the General method). This allows the large model to return table of contents items relevant to the user's query, thereby using these items to retrieve related chunks and apply weighting to these chunks during the sorting process. This approach is derived from mimicking the behavioral logic of how humans search for knowledge in books.`, }, setting: { + configureModelTitle: 'Configure model', confluenceIsCloudTip: 'Check if this is a Confluence Cloud instance, uncheck for Confluence Server/Data Center', confluenceWikiBaseUrlTip: diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 47e2dadd39..9c90d734bd 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -1,6 +1,7 @@ export default { translation: { common: { + back: '返回', noResults: '无结果。', selectPlaceholder: '请选择', selectAll: '全选', @@ -679,9 +680,11 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 chatSetting: '聊天设置', avatarHidden: '隐藏头像', locale: '地区', + tocEnhance: '目录增强', tocEnhanceTip: `解析文档时生成了目录信息(见General方法的‘启用目录抽取’),让大模型返回和用户问题相关的目录项,从而利用目录项拿到相关chunk,对这些chunk在排序中进行加权。这种方法来源于模仿人类查询书本中知识的行为逻辑`, }, setting: { + configureModelTitle: '配置模型', confluenceIsCloudTip: '检查这是否是 Confluence Cloud 实例,如果是 Confluence 服务/数据中心,则取消选中。', confluenceWikiBaseUrlTip: @@ -759,7 +762,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 confirmPasswordMessage: '请确认新密码', confirmPasswordNonMatchMessage: '您输入的新密码不匹配!', cancel: '取消', - addedModels: '已添加的模型', + addedModels: '添加了的模型', modelsToBeAdded: '待添加的模型', addTheModel: '添加', apiKey: 'API-Key', @@ -1011,10 +1014,10 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 exceptionMethod: '异常处理方法', maxRounds: '最大反思轮数', delayEfterError: '错误后延迟', - maxRetries: '最大重试轮数', + maxRetries: '最大反思轮数', advancedSettings: '高级设置', addTools: '添加工具', - sysPromptDefaultValue: ` + sysPromptDefultValue: ` 你是一名乐于助人的助手,一名专注于为用户解决问题的 AI 助手。 如果用户指定了特定领域,你需要在该领域展现专业性;如果没有,则以通用助手的方式工作。 diff --git a/web/src/pages/login-next/index.tsx b/web/src/pages/login-next/index.tsx index 1aa9b2aa52..c9354225f8 100644 --- a/web/src/pages/login-next/index.tsx +++ b/web/src/pages/login-next/index.tsx @@ -157,7 +157,7 @@ const Login = () => { {/* */}
-
+
logo -
+
{ hideModal?.(); diff --git a/web/src/pages/user-setting/data-source/component/google-drive-token-field.tsx b/web/src/pages/user-setting/data-source/component/google-drive-token-field.tsx index 1f0d91617f..50a055f52f 100644 --- a/web/src/pages/user-setting/data-source/component/google-drive-token-field.tsx +++ b/web/src/pages/user-setting/data-source/component/google-drive-token-field.tsx @@ -302,7 +302,7 @@ const GoogleDriveTokenField = ({
)} ( - - ), - tooltip: t('setting.google_driveTokenTip'), - }, - { - label: 'My Drive Emails', - name: 'config.my_drive_emails', - type: FormFieldType.Text, - required: true, - placeholder: 'user1@example.com,user2@example.com', - tooltip: t('setting.google_driveMyDriveEmailsTip'), - }, - { - label: 'Shared Folder URLs', - name: 'config.shared_folder_urls', - type: FormFieldType.Textarea, - required: true, - placeholder: - 'https://drive.google.com/drive/folders/XXXXX,https://drive.google.com/drive/folders/YYYYY', - tooltip: t('setting.google_driveSharedFoldersTip'), - }, - // The fields below are intentionally disabled for now. Uncomment them when we - // reintroduce shared drive controls or advanced impersonation options. - // { - // label: 'Shared Drive URLs', - // name: 'config.shared_drive_urls', - // type: FormFieldType.Text, - // required: false, - // placeholder: - // 'Optional: comma-separated shared drive links if you want to include them.', - // }, - // { - // label: 'Specific User Emails', - // name: 'config.specific_user_emails', - // type: FormFieldType.Text, - // required: false, - // placeholder: - // 'Optional: comma-separated list of users to impersonate (overrides defaults).', - // }, - // { - // label: 'Include My Drive', - // name: 'config.include_my_drives', - // type: FormFieldType.Checkbox, - // required: false, - // defaultValue: true, - // }, - // { - // label: 'Include Shared Drives', - // name: 'config.include_shared_drives', - // type: FormFieldType.Checkbox, - // required: false, - // defaultValue: false, - // }, - // { - // label: 'Include “Shared with me”', - // name: 'config.include_files_shared_with_me', - // type: FormFieldType.Checkbox, - // required: false, - // defaultValue: false, - // }, - // { - // label: 'Allow Images', - // name: 'config.allow_images', - // type: FormFieldType.Checkbox, - // required: false, - // defaultValue: false, - // }, - { - label: '', - name: 'config.credentials.authentication_method', - type: FormFieldType.Text, - required: false, - hidden: true, - defaultValue: 'uploaded', - }, - ], + // [DataSourceKey.GOOGLE_DRIVE]: [ + // { + // label: 'Primary Admin Email', + // name: 'config.credentials.google_primary_admin', + // type: FormFieldType.Text, + // required: true, + // placeholder: 'admin@example.com', + // tooltip: t('setting.google_drivePrimaryAdminTip'), + // }, + // { + // label: 'OAuth Token JSON', + // name: 'config.credentials.google_tokens', + // type: FormFieldType.Textarea, + // required: true, + // render: (fieldProps) => ( + // + // ), + // tooltip: t('setting.google_driveTokenTip'), + // }, + // { + // label: 'My Drive Emails', + // name: 'config.my_drive_emails', + // type: FormFieldType.Text, + // required: true, + // placeholder: 'user1@example.com,user2@example.com', + // tooltip: t('setting.google_driveMyDriveEmailsTip'), + // }, + // { + // label: 'Shared Folder URLs', + // name: 'config.shared_folder_urls', + // type: FormFieldType.Textarea, + // required: true, + // placeholder: + // 'https://drive.google.com/drive/folders/XXXXX,https://drive.google.com/drive/folders/YYYYY', + // tooltip: t('setting.google_driveSharedFoldersTip'), + // }, + // // The fields below are intentionally disabled for now. Uncomment them when we + // // reintroduce shared drive controls or advanced impersonation options. + // // { + // // label: 'Shared Drive URLs', + // // name: 'config.shared_drive_urls', + // // type: FormFieldType.Text, + // // required: false, + // // placeholder: + // // 'Optional: comma-separated shared drive links if you want to include them.', + // // }, + // // { + // // label: 'Specific User Emails', + // // name: 'config.specific_user_emails', + // // type: FormFieldType.Text, + // // required: false, + // // placeholder: + // // 'Optional: comma-separated list of users to impersonate (overrides defaults).', + // // }, + // // { + // // label: 'Include My Drive', + // // name: 'config.include_my_drives', + // // type: FormFieldType.Checkbox, + // // required: false, + // // defaultValue: true, + // // }, + // // { + // // label: 'Include Shared Drives', + // // name: 'config.include_shared_drives', + // // type: FormFieldType.Checkbox, + // // required: false, + // // defaultValue: false, + // // }, + // // { + // // label: 'Include “Shared with me”', + // // name: 'config.include_files_shared_with_me', + // // type: FormFieldType.Checkbox, + // // required: false, + // // defaultValue: false, + // // }, + // // { + // // label: 'Allow Images', + // // name: 'config.allow_images', + // // type: FormFieldType.Checkbox, + // // required: false, + // // defaultValue: false, + // // }, + // { + // label: '', + // name: 'config.credentials.authentication_method', + // type: FormFieldType.Text, + // required: false, + // hidden: true, + // defaultValue: 'uploaded', + // }, + // ], }; export const DataSourceFormDefaultValues = { diff --git a/web/src/pages/user-setting/setting-model/components/modal-card.tsx b/web/src/pages/user-setting/setting-model/components/modal-card.tsx index 270f9b4b54..9bf2875f5c 100644 --- a/web/src/pages/user-setting/setting-model/components/modal-card.tsx +++ b/web/src/pages/user-setting/setting-model/components/modal-card.tsx @@ -65,7 +65,7 @@ export const ModelProviderCard: FC = ({ }; return ( -
+
{/* Header */}
@@ -131,7 +131,7 @@ export const ModelProviderCard: FC = ({ {item.llm.map((model) => (
diff --git a/web/src/pages/user-setting/setting-model/components/system-setting.tsx b/web/src/pages/user-setting/setting-model/components/system-setting.tsx index f668132812..2c87ab3b45 100644 --- a/web/src/pages/user-setting/setting-model/components/system-setting.tsx +++ b/web/src/pages/user-setting/setting-model/components/system-setting.tsx @@ -156,7 +156,7 @@ const SystemSetting = ({ onOk, loading }: IProps) => { )} { {t('systemModelDescription')}
-
+
{llmList.map((item) => ( ))} diff --git a/web/src/pages/user-setting/setting-model/components/un-add-model.tsx b/web/src/pages/user-setting/setting-model/components/un-add-model.tsx index 5d5c99d8c6..3d8b1d5e27 100644 --- a/web/src/pages/user-setting/setting-model/components/un-add-model.tsx +++ b/web/src/pages/user-setting/setting-model/components/un-add-model.tsx @@ -122,7 +122,7 @@ export const AvailableModels: FC<{ {filteredModels.map((model) => (
diff --git a/web/src/pages/user-setting/setting-model/components/used-model.tsx b/web/src/pages/user-setting/setting-model/components/used-model.tsx index dae2675791..6555caafc2 100644 --- a/web/src/pages/user-setting/setting-model/components/used-model.tsx +++ b/web/src/pages/user-setting/setting-model/components/used-model.tsx @@ -11,7 +11,7 @@ export const UsedModel = ({ }) => { const { factoryList, myLlmList: llmList, loading } = useSelectLlmList(); return ( -
+
{t('setting.addedModels')}
diff --git a/web/src/pages/user-setting/setting-model/hooks.ts b/web/src/pages/user-setting/setting-model/hooks.ts index 1efb79fdce..b509ed863f 100644 --- a/web/src/pages/user-setting/setting-model/hooks.ts +++ b/web/src/pages/user-setting/setting-model/hooks.ts @@ -13,6 +13,7 @@ import { import { useFetchTenantInfo } from '@/hooks/user-setting-hooks'; import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { getRealModelName } from '@/utils/llm-util'; +import { useQueryClient } from '@tanstack/react-query'; import { useCallback, useState } from 'react'; import { ApiKeyPostBody } from '../interface'; @@ -29,7 +30,7 @@ export const useSubmitApiKey = () => { hideModal: hideApiKeyModal, showModal: showApiKeyModal, } = useSetModalState(); - + const queryClient = useQueryClient(); const onApiKeySavingOk = useCallback( async (postBody: ApiKeyPostBody) => { const ret = await saveApiKey({ @@ -38,11 +39,12 @@ export const useSubmitApiKey = () => { }); if (ret === 0) { + queryClient.invalidateQueries({ queryKey: ['llmList'] }); hideApiKeyModal(); setEditMode(false); } }, - [hideApiKeyModal, saveApiKey, savingParams], + [hideApiKeyModal, saveApiKey, savingParams, queryClient], ); const onShowApiKeyModal = useCallback( diff --git a/web/src/pages/user-setting/setting-model/index.tsx b/web/src/pages/user-setting/setting-model/index.tsx index 307a2dce1a..af398e33c5 100644 --- a/web/src/pages/user-setting/setting-model/index.tsx +++ b/web/src/pages/user-setting/setting-model/index.tsx @@ -193,9 +193,9 @@ const ModelProviders = () => { [showApiKeyModal, showLlmAddingModal, ModalMap, detailedLlmList], ); return ( -
+
-
+
!open && hideModal()} onOk={handleOk} @@ -77,6 +77,7 @@ const ApiKeyModal = ({ confirmLoading={loading} okText={t('save')} cancelText={t('cancel')} + className="!w-[600px]" >
@@ -85,9 +86,11 @@ const ApiKeyModal = ({ rules={{ required: t('apiKeyMessage') }} render={({ field }) => ( - + {t('apiKey')} - *