From 4775a3a77dad8be2effa009a50c77c6f870c4816 Mon Sep 17 00:00:00 2001 From: suyao Date: Sun, 23 Mar 2025 19:00:38 +0800 Subject: [PATCH] refactor(Settings): Refactored knowledge settings to utilize the new OCR provider management. --- src/renderer/src/components/Icons/OcrIcon.tsx | 20 ++++++ .../src/components/Icons/ToolIcon.tsx | 16 +++++ src/renderer/src/hooks/useKnowledge.ts | 34 +-------- src/renderer/src/hooks/useOcr.ts | 45 ++++++++++++ src/renderer/src/i18n/locales/en-us.json | 65 ++++++++++------- src/renderer/src/i18n/locales/ja-jp.json | 66 ++++++++++------- src/renderer/src/i18n/locales/ru-ru.json | 64 ++++++++++------- src/renderer/src/i18n/locales/zh-cn.json | 72 +++++++++---------- src/renderer/src/i18n/locales/zh-tw.json | 67 ++++++++++------- .../src/pages/knowledge/KnowledgeContent.tsx | 3 +- .../src/pages/knowledge/KnowledgePage.tsx | 6 +- .../components/KnowledgeSettings.tsx | 16 +++-- .../components/KnowledgeSettingsPopup.tsx | 2 +- .../src/pages/settings/SettingsPage.tsx | 24 ++----- .../OcrSettings}/OcrProviderSettings.tsx | 8 +-- .../OcrSettings}/index.tsx | 36 ++++++---- .../WebSearchSettings/BasicSettings.tsx | 53 ++++++++++++++ .../WebSearchSettings/BlacklistSettings.tsx | 10 +-- .../WebSearchProviderSetting.tsx | 34 ++++++--- .../WebSearchSettings/index.tsx | 16 +++-- .../src/pages/settings/ToolSettings/index.tsx | 59 +++++++++++++++ .../WebSearchSettings/BasicSettings.tsx | 55 -------------- src/renderer/src/store/index.ts | 6 +- src/renderer/src/store/knowledge.ts | 21 +----- src/renderer/src/store/migrate.ts | 22 +++--- src/renderer/src/store/ocr.ts | 44 ++++++++++++ 26 files changed, 537 insertions(+), 327 deletions(-) create mode 100644 src/renderer/src/components/Icons/OcrIcon.tsx create mode 100644 src/renderer/src/components/Icons/ToolIcon.tsx create mode 100644 src/renderer/src/hooks/useOcr.ts rename src/renderer/src/pages/settings/{KnowledgeSettings => ToolSettings/OcrSettings}/OcrProviderSettings.tsx (94%) rename src/renderer/src/pages/settings/{KnowledgeSettings => ToolSettings/OcrSettings}/index.tsx (53%) create mode 100644 src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BasicSettings.tsx rename src/renderer/src/pages/settings/{ => ToolSettings}/WebSearchSettings/BlacklistSettings.tsx (83%) rename src/renderer/src/pages/settings/{ => ToolSettings}/WebSearchSettings/WebSearchProviderSetting.tsx (85%) rename src/renderer/src/pages/settings/{ => ToolSettings}/WebSearchSettings/index.tsx (79%) create mode 100644 src/renderer/src/pages/settings/ToolSettings/index.tsx delete mode 100644 src/renderer/src/pages/settings/WebSearchSettings/BasicSettings.tsx create mode 100644 src/renderer/src/store/ocr.ts diff --git a/src/renderer/src/components/Icons/OcrIcon.tsx b/src/renderer/src/components/Icons/OcrIcon.tsx new file mode 100644 index 000000000..ae25e2adb --- /dev/null +++ b/src/renderer/src/components/Icons/OcrIcon.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react' + +const OcrIcon: FC> = (props) => ( + + + +) + +export default OcrIcon diff --git a/src/renderer/src/components/Icons/ToolIcon.tsx b/src/renderer/src/components/Icons/ToolIcon.tsx new file mode 100644 index 000000000..b49246516 --- /dev/null +++ b/src/renderer/src/components/Icons/ToolIcon.tsx @@ -0,0 +1,16 @@ +import { FC } from 'react' + +const ToolIcon: FC> = (props) => ( + + + +) + +export default ToolIcon diff --git a/src/renderer/src/hooks/useKnowledge.ts b/src/renderer/src/hooks/useKnowledge.ts index 51f145b91..509a5415c 100644 --- a/src/renderer/src/hooks/useKnowledge.ts +++ b/src/renderer/src/hooks/useKnowledge.ts @@ -17,11 +17,9 @@ import { updateBases, updateItem as updateItemAction, updateItemProcessingStatus, - updateNotes, - updateOcrProvider as _updateOcrProvider, - updateOcrProviders as _updateOcrProviders + updateNotes } from '@renderer/store/knowledge' -import { FileType, KnowledgeBase, KnowledgeItem, OcrProvider, ProcessingStatus } from '@renderer/types' +import { FileType, KnowledgeBase, KnowledgeItem, ProcessingStatus } from '@renderer/types' import { runAsyncFunction } from '@renderer/utils' import { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' @@ -394,31 +392,3 @@ export const useKnowledgeBases = () => { updateKnowledgeBases } } - -export const useOcrProviders = () => { - const dispatch = useDispatch() - const ocrProviders = useSelector((state: RootState) => state.knowledge.ocrProviders) - const updateOcrProviders = (ocrProviders: OcrProvider[]) => { - dispatch(_updateOcrProviders(ocrProviders)) - } - return { - ocrProviders, - updateOcrProviders - } -} -export const useOcrProvider = (id: string) => { - const dispatch = useDispatch() - const ocrProviders = useSelector((state: RootState) => state.knowledge.ocrProviders) - const ocrProvider = ocrProviders.find((provider) => provider.id === id) - if (!ocrProvider) { - throw new Error(`ocr provider with id ${id} not found`) - } - - const updateOcrProvider = (ocrProvider: OcrProvider) => { - dispatch(_updateOcrProvider(ocrProvider)) - } - return { - ocrProvider, - updateOcrProvider - } -} diff --git a/src/renderer/src/hooks/useOcr.ts b/src/renderer/src/hooks/useOcr.ts new file mode 100644 index 000000000..69a8f96ea --- /dev/null +++ b/src/renderer/src/hooks/useOcr.ts @@ -0,0 +1,45 @@ +import { RootState } from '@renderer/store' +import { + setDefaultOcrProvider as _setDefaultOcrProvider, + updateOcrProvider as _updateOcrProvider, + updateOcrProviders as _updateOcrProviders +} from '@renderer/store/ocr' +import { OcrProvider } from '@renderer/types' +import { useDispatch, useSelector } from 'react-redux' + +export const useOcrProvider = (id: string) => { + const dispatch = useDispatch() + const ocrProviders = useSelector((state: RootState) => state.ocr.providers) + const provider = ocrProviders.find((provider) => provider.id === id) + if (!provider) { + throw new Error(`ocr provider with id ${id} not found`) + } + const updateOcrProvider = (ocrProvider: OcrProvider) => { + dispatch(_updateOcrProvider(ocrProvider)) + } + return { provider, updateOcrProvider } +} + +export const useOcrProviders = () => { + const dispatch = useDispatch() + const ocrProviders = useSelector((state: RootState) => state.ocr.providers) + return { + ocrProviders, + updateOcrProviders: (ocrProviders: OcrProvider[]) => dispatch(_updateOcrProviders(ocrProviders)) + } +} + +export const useDefaultOcrProvider = () => { + const defaultProviderId = useSelector((state: RootState) => state.ocr.defaultProvider) + const { ocrProviders } = useOcrProviders() + const dispatch = useDispatch() + const provider = defaultProviderId ? ocrProviders.find((provider) => provider.id === defaultProviderId) : undefined + + const setDefaultOcrProvider = (ocrProvider: OcrProvider) => { + dispatch(_setDefaultOcrProvider(ocrProvider.id)) + } + const updateDefaultOcrProvider = (ocrProvider: OcrProvider) => { + dispatch(_updateOcrProvider(ocrProvider)) + } + return { provider, setDefaultOcrProvider, updateDefaultOcrProvider } +} diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index e35c2a3e5..70ceda8f7 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -369,7 +369,11 @@ "rename": "Rename", "search": "Search knowledge base", "search_placeholder": "Enter text to search", - "settings": "Knowledge Base Settings", + "settings": { + "title": "Knowledge Base Settings", + "preprocessing": "Preprocessing", + "preprocessing_tooltip": "Preprocess uploaded files with OCR" + }, "sitemap_placeholder": "Enter Website Map URL", "sitemaps": "Websites", "source": "Source", @@ -1101,37 +1105,46 @@ "theme.window.style.title": "Window Style", "theme.window.style.transparent": "Transparent Window", "title": "Settings", + "tool": { + "websearch": { + "blacklist": "Blacklist", + "blacklist_description": "Results from the following websites will not appear in search results", + "blacklist_tooltip": "Please use the following format (separated by line breaks)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", + "check": "Check", + "check_failed": "Verification failed", + "check_success": "Verification successful", + "enhance_mode": "Search enhance mode", + "enhance_mode_tooltip": "Use the default model to extract search keywords from the problem and search", + "get_api_key": "Get API Key", + "no_provider_selected": "Please select a search service provider before checking.", + "search_max_result": "Number of search results", + "search_provider": "Search service provider", + "search_provider_placeholder": "Choose a search service provider.", + "search_result_default": "Default", + "search_with_time": "Search with dates included", + "tavily": { + "api_key": "Tavily API Key", + "api_key.placeholder": "Enter Tavily API Key", + "description": "Tavily is a search engine tailored for AI agents, delivering real-time, accurate results, intelligent query suggestions, and in-depth research capabilities.", + "title": "Tavily" + }, + "title": "Web Search" + }, + "ocr": { + "title": "OCR", + "provider": "OCR Provider", + "ocr": "OCR Settings", + "provider_placeholder": "Choose a OCR provider" + }, + "title": "Tool Settings" + }, "topic.position": "Topic position", "topic.position.left": "Left", "topic.position.right": "Right", "topic.show.time": "Show topic time", "tray.onclose": "Minimize to Tray on Close", "tray.show": "Show Tray Icon", - "tray.title": "Tray", - "websearch": { - "blacklist": "Blacklist", - "blacklist_description": "Results from the following websites will not appear in search results", - "blacklist_tooltip": "Please use the following format (separated by line breaks)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", - "check": "Check", - "check_failed": "Verification failed", - "check_success": "Verification successful", - "enhance_mode": "Search enhance mode", - "enhance_mode_tooltip": "Use the default model to extract search keywords from the problem and search", - "get_api_key": "Get API Key", - "no_provider_selected": "Please select a search service provider before checking.", - "search_max_result": "Number of search results", - "search_provider": "Search service provider", - "search_provider_placeholder": "Choose a search service provider.", - "search_result_default": "Default", - "search_with_time": "Search with dates included", - "tavily": { - "api_key": "Tavily API Key", - "api_key.placeholder": "Enter Tavily API Key", - "description": "Tavily is a search engine tailored for AI agents, delivering real-time, accurate results, intelligent query suggestions, and in-depth research capabilities.", - "title": "Tavily" - }, - "title": "Web Search" - } + "tray.title": "Tray" }, "translate": { "any.language": "Any language", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 3d6bab82e..e7e811cbd 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -369,7 +369,11 @@ "rename": "名前を変更", "search": "ナレッジベースを検索", "search_placeholder": "検索するテキストを入力", - "settings": "ナレッジベース設定", + "settings": { + "title": "ナレッジベース設定", + "preprocessing": "預処理", + "preprocessing_tooltip": "アップロードされたファイルのOCR預処理" + }, "sitemap_placeholder": "サイトマップURLを入力", "sitemaps": "サイトマップ", "source": "ソース", @@ -1101,37 +1105,47 @@ "theme.window.style.title": "ウィンドウスタイル", "theme.window.style.transparent": "透明ウィンドウ", "title": "設定", + "tool": { + "title": "ツール設定", + "ocr": { + "title": "ナレッジベース設定", + "preprocessing": "預処理", + "preprocessing_tooltip": "アップロードされたファイルのOCR預処理", + "provider": "OCRプロバイダー", + "provider_placeholder": "OCRプロバイダーを選択する" + }, + "websearch": { + "blacklist": "ブラックリスト", + "blacklist_description": "以下のウェブサイトの結果は検索結果に表示されません", + "blacklist_tooltip": "以下の形式を使用してください(改行区切り)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", + "check": "チェック", + "check_failed": "検証に失敗しました", + "check_success": "検証に成功しました", + "enhance_mode": "検索強化モード", + "enhance_mode_tooltip": "デフォルトモデルを使用して問題から検索キーワードを抽出し、検索を実行します", + "get_api_key": "APIキーを取得", + "no_provider_selected": "検索サービスプロバイダーを選択してから再確認してください。", + "search_max_result": "検索結果の数", + "search_provider": "検索サービスプロバイダー", + "search_provider_placeholder": "検索サービスプロバイダーを選択する", + "search_result_default": "デフォルト", + "search_with_time": "日付を含む検索", + "tavily": { + "api_key": "Tavily API キー", + "api_key.placeholder": "Tavily API キーを入力してください", + "description": "Tavily は、AI エージェントのために特別に開発された検索エンジンで、最新の結果、インテリジェントな検索提案、そして深い研究能力を提供します", + "title": "Tavily" + }, + "title": "ウェブ検索" + } + }, "topic.position": "トピックの位置", "topic.position.left": "左", "topic.position.right": "右", "topic.show.time": "トピックの時間を表示", "tray.onclose": "閉じるときにトレイに最小化", "tray.show": "トレイアイコンを表示", - "tray.title": "トレイ", - "websearch": { - "blacklist": "ブラックリスト", - "blacklist_description": "以下のウェブサイトの結果は検索結果に表示されません", - "blacklist_tooltip": "以下の形式を使用してください(改行区切り)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", - "check": "チェック", - "check_failed": "検証に失敗しました", - "check_success": "検証に成功しました", - "enhance_mode": "検索強化モード", - "enhance_mode_tooltip": "デフォルトモデルを使用して問題から検索キーワードを抽出し、検索を実行します", - "get_api_key": "APIキーを取得", - "no_provider_selected": "検索サービスプロバイダーを選択してから再確認してください。", - "search_max_result": "検索結果の数", - "search_provider": "検索サービスプロバイダー", - "search_provider_placeholder": "検索サービスプロバイダーを選択する", - "search_result_default": "デフォルト", - "search_with_time": "日付を含む検索", - "tavily": { - "api_key": "Tavily API キー", - "api_key.placeholder": "Tavily API キーを入力してください", - "description": "Tavily は、AI エージェントのために特別に開発された検索エンジンで、最新の結果、インテリジェントな検索提案、そして深い研究能力を提供します", - "title": "Tavily" - }, - "title": "ウェブ検索" - } + "tray.title": "トレイ" }, "translate": { "any.language": "任意の言語", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index d3c854c4e..dbd0cf7ab 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -369,7 +369,11 @@ "rename": "Переименовать", "search": "Поиск в базе знаний", "search_placeholder": "Введите текст для поиска", - "settings": "Настройки базы знаний", + "settings": { + "title": "Настройки базы знаний", + "preprocessing": "Предварительная обработка", + "preprocessing_tooltip": "Предварительная обработка изображений с помощью OCR" + }, "sitemap_placeholder": "Введите URL карты сайта", "sitemaps": "Сайты", "source": "Источник", @@ -1101,37 +1105,45 @@ "theme.window.style.title": "Стиль окна", "theme.window.style.transparent": "Прозрачное окно", "title": "Настройки", + "tool": { + "title": "Настройки инструментов", + "ocr": { + "title": "Настройки OCR", + "provider": "Поставщик OCR", + "provider_placeholder": "Выберите поставщика OCR" + }, + "websearch": { + "blacklist": "Черный список", + "blacklist_description": "Результаты из следующих веб-сайтов не будут отображаться в результатах поиска", + "blacklist_tooltip": "Пожалуйста, используйте следующий формат (разделенный переносами строк)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", + "check": "проверка", + "check_failed": "Проверка не прошла", + "check_success": "Проверка успешна", + "enhance_mode": "Режим улучшения поиска", + "enhance_mode_tooltip": "Используйте модель по умолчанию для извлечения ключевых слов из проблемы и поиска", + "get_api_key": "Получить ключ API", + "no_provider_selected": "Пожалуйста, выберите поставщика поисковых услуг, затем проверьте.", + "search_max_result": "Количество результатов поиска", + "search_provider": "поиск сервисного провайдера", + "search_provider_placeholder": "Выберите поставщика поисковых услуг", + "search_result_default": "По умолчанию", + "search_with_time": "Поиск, содержащий дату", + "tavily": { + "api_key": "Ключ API Tavily", + "api_key.placeholder": "Введите ключ API Tavily", + "description": "Tavily — это поисковая система, специально разработанная для ИИ-агентов, предоставляющая актуальные результаты, умные предложения по запросам и глубокие исследовательские возможности", + "title": "Tavily" + }, + "title": "Поиск в Интернете" + } + }, "topic.position": "Позиция топиков", "topic.position.left": "Слева", "topic.position.right": "Справа", "topic.show.time": "Показывать время топика", "tray.onclose": "Свернуть в трей при закрытии", "tray.show": "Показать значок в трее", - "tray.title": "Трей", - "websearch": { - "blacklist": "Черный список", - "blacklist_description": "Результаты из следующих веб-сайтов не будут отображаться в результатах поиска", - "blacklist_tooltip": "Пожалуйста, используйте следующий формат (разделенный переносами строк)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", - "check": "проверка", - "check_failed": "Проверка не прошла", - "check_success": "Проверка успешна", - "enhance_mode": "Режим улучшения поиска", - "enhance_mode_tooltip": "Используйте модель по умолчанию для извлечения ключевых слов из проблемы и поиска", - "get_api_key": "Получить ключ API", - "no_provider_selected": "Пожалуйста, выберите поставщика поисковых услуг, затем проверьте.", - "search_max_result": "Количество результатов поиска", - "search_provider": "поиск сервисного провайдера", - "search_provider_placeholder": "Выберите поставщика поисковых услуг", - "search_result_default": "По умолчанию", - "search_with_time": "Поиск, содержащий дату", - "tavily": { - "api_key": "Ключ API Tavily", - "api_key.placeholder": "Введите ключ API Tavily", - "description": "Tavily — это поисковая система, специально разработанная для ИИ-агентов, предоставляющая актуальные результаты, умные предложения по запросам и глубокие исследовательские возможности", - "title": "Tavily" - }, - "title": "Поиск в Интернете" - } + "tray.title": "Трей" }, "translate": { "any.language": "Любой язык", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 81b455447..c2f1f2a61 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -369,6 +369,7 @@ "rename": "重命名", "search": "搜索知识库", "search_placeholder": "输入查询内容", + "settings": "知识库设置", "sitemap_placeholder": "请输入站点地图 URL", "sitemaps": "网站", "source": "来源", @@ -389,18 +390,7 @@ "topN_tooltip": "返回的匹配结果数量,数值越大,匹配结果越多,但消耗的 Token 也越多", "url_added": "网址已添加", "url_placeholder": "请输入网址, 多个网址用回车分隔", - "urls": "网址", - "settings": { - "title": "知识库设置", - "preprocessing": "预处理", - "preprocessing_tooltip": "对上传的文件进行ocr预处理", - "general": "常规设置", - "ocr": "OCR 设置", - "advanced": "高级设置", - "doc2x_api_key": "Doc2X API Key", - "doc2x_api_key_placeholder": "请输入 Doc2X API Key", - "doc2x_api_key_tooltip": "使用doc2x进行文档预处理" - } + "urls": "网址" }, "languages": { "arabic": "阿拉伯文", @@ -1118,37 +1108,45 @@ "theme.window.style.title": "窗口样式", "theme.window.style.transparent": "透明窗口", "title": "设置", + "tool": { + "title": "工具设置", + "ocr": { + "title": "知识库设置", + "provider": "OCR服务商", + "provider_placeholder": "选择一个OCR服务商" + }, + "websearch": { + "blacklist": "黑名单", + "blacklist_description": "在搜索结果中不会出现以下网站的结果", + "blacklist_tooltip": "请使用以下格式(换行分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", + "check": "检查", + "check_failed": "验证失败", + "check_success": "验证成功", + "enhance_mode": "搜索增强模式", + "enhance_mode_tooltip": "使用默认模型提取关键词后搜索", + "get_api_key": "点击这里获取密钥", + "no_provider_selected": "请选择搜索服务商后再检查", + "search_max_result": "搜索结果个数", + "search_provider": "搜索服务商", + "search_provider_placeholder": "选择一个搜索服务商", + "search_result_default": "默认", + "search_with_time": "搜索包含日期", + "tavily": { + "api_key": "Tavily API 密钥", + "api_key.placeholder": "请输入 Tavily API 密钥", + "description": "Tavily 是一个为 AI 代理量身定制的搜索引擎,提供实时、准确的结果、智能查询建议和深入的研究能力", + "title": "Tavily" + }, + "title": "网络搜索" + } + }, "topic.position": "话题位置", "topic.position.left": "左侧", "topic.position.right": "右侧", "topic.show.time": "显示话题时间", "tray.onclose": "关闭时最小化到托盘", "tray.show": "显示托盘图标", - "tray.title": "托盘", - "websearch": { - "blacklist": "黑名单", - "blacklist_description": "在搜索结果中不会出现以下网站的结果", - "blacklist_tooltip": "请使用以下格式(换行分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", - "check": "检查", - "check_failed": "验证失败", - "check_success": "验证成功", - "enhance_mode": "搜索增强模式", - "enhance_mode_tooltip": "使用默认模型提取关键词后搜索", - "get_api_key": "点击这里获取密钥", - "no_provider_selected": "请选择搜索服务商后再检查", - "search_max_result": "搜索结果个数", - "search_provider": "搜索服务商", - "search_provider_placeholder": "选择一个搜索服务商", - "search_result_default": "默认", - "search_with_time": "搜索包含日期", - "tavily": { - "api_key": "Tavily API 密钥", - "api_key.placeholder": "请输入 Tavily API 密钥", - "description": "Tavily 是一个为 AI 代理量身定制的搜索引擎,提供实时、准确的结果、智能查询建议和深入的研究能力", - "title": "Tavily" - }, - "title": "网络搜索" - } + "tray.title": "托盘" }, "translate": { "any.language": "任意语言", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 3c13cc698..24f8fcb4f 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -369,7 +369,11 @@ "rename": "重新命名", "search": "搜尋知識庫", "search_placeholder": "輸入查詢內容", - "settings": "知識庫設定", + "settings": { + "title": "知識庫設定", + "preprocessing": "預處理", + "preprocessing_tooltip": "預處理上傳的文件" + }, "sitemap_placeholder": "請輸入網站地圖 URL", "sitemaps": "網站", "source": "來源", @@ -1101,37 +1105,46 @@ "theme.window.style.title": "視窗樣式", "theme.window.style.transparent": "透明視窗", "title": "設定", + "tool": { + "title": "工具", + "ocr": { + "title": "OCR", + "description": "OCR 設定", + "provider": "OCR 提供者", + "provider_placeholder": "選擇一個 OCR 提供者" + }, + "websearch": { + "blacklist": "黑名單", + "blacklist_description": "以下網站不會出現在搜尋結果中", + "blacklist_tooltip": "請使用以下格式 (換行符號分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", + "check": "檢查", + "check_failed": "驗證失敗", + "check_success": "驗證成功", + "enhance_mode": "搜索增強模式", + "enhance_mode_tooltip": "使用預設模型提取關鍵詞後搜索", + "get_api_key": "點選這裡取得金鑰", + "no_provider_selected": "請選擇搜尋服務商後再檢查", + "search_max_result": "搜尋結果個數", + "search_provider": "搜尋服務商", + "search_provider_placeholder": "選擇一個搜尋服務商", + "search_result_default": "預設", + "search_with_time": "搜尋包含日期", + "tavily": { + "api_key": "Tavily API 金鑰", + "api_key.placeholder": "請輸入 Tavily API 金鑰", + "description": "Tavily 是一個為 AI 代理量身訂製的搜尋引擎,提供即時、準確的結果、智慧查詢建議和深入的研究能力", + "title": "Tavily" + }, + "title": "網路搜尋" + } + }, "topic.position": "話題位置", "topic.position.left": "左側", "topic.position.right": "右側", "topic.show.time": "顯示話題時間", "tray.onclose": "關閉時最小化到系统匣", "tray.show": "顯示系统匣圖示", - "tray.title": "系统匣", - "websearch": { - "blacklist": "黑名單", - "blacklist_description": "以下網站不會出現在搜尋結果中", - "blacklist_tooltip": "請使用以下格式 (換行符號分隔)\nexample.com\nhttps://www.example.com\nhttps://example.com\n*://*.example.com", - "check": "檢查", - "check_failed": "驗證失敗", - "check_success": "驗證成功", - "enhance_mode": "搜索增強模式", - "enhance_mode_tooltip": "使用預設模型提取關鍵詞後搜索", - "get_api_key": "點選這裡取得金鑰", - "no_provider_selected": "請選擇搜尋服務商後再檢查", - "search_max_result": "搜尋結果個數", - "search_provider": "搜尋服務商", - "search_provider_placeholder": "選擇一個搜尋服務商", - "search_result_default": "預設", - "search_with_time": "搜尋包含日期", - "tavily": { - "api_key": "Tavily API 金鑰", - "api_key.placeholder": "請輸入 Tavily API 金鑰", - "description": "Tavily 是一個為 AI 代理量身訂製的搜尋引擎,提供即時、準確的結果、智慧查詢建議和深入的研究能力", - "title": "Tavily" - }, - "title": "網路搜尋" - } + "tray.title": "系统匣" }, "translate": { "any.language": "任意語言", @@ -1170,4 +1183,4 @@ "visualization": "視覺化" } } -} \ No newline at end of file +} diff --git a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx index e7cbe9cf9..634730117 100644 --- a/src/renderer/src/pages/knowledge/KnowledgeContent.tsx +++ b/src/renderer/src/pages/knowledge/KnowledgeContent.tsx @@ -28,7 +28,6 @@ import styled from 'styled-components' import KnowledgeSearchPopup from './components/KnowledgeSearchPopup' import KnowledgeSettings from './components/KnowledgeSettings' import StatusIcon from './components/StatusIcon' -import KnowledgeSettingsPopup from './components/KnowledgeSettingsPopup' const { Dragger } = Upload const { Title } = Typography @@ -463,7 +462,7 @@ const KnowledgeContent: FC = ({ selectedBase }) => {
-
diff --git a/src/renderer/src/pages/knowledge/KnowledgePage.tsx b/src/renderer/src/pages/knowledge/KnowledgePage.tsx index 8129816ce..ecf5ab0cf 100644 --- a/src/renderer/src/pages/knowledge/KnowledgePage.tsx +++ b/src/renderer/src/pages/knowledge/KnowledgePage.tsx @@ -24,7 +24,7 @@ import { useTranslation } from 'react-i18next' import styled from 'styled-components' import AddKnowledgePopup from './components/AddKnowledgePopup' -import KnowledgeSettingsPopup from './components/KnowledgeSettingsPopup' +import KnowledgeSettings from './components/KnowledgeSettings' import KnowledgeContent from './KnowledgeContent' const KnowledgePage: FC = () => { @@ -64,10 +64,10 @@ const KnowledgePage: FC = () => { } }, { - label: t('knowledge.settings'), + label: t('knowledge.settings.title'), key: 'settings', icon: , - onClick: () => KnowledgeSettingsPopup.show({ base }) + onClick: () => KnowledgeSettings.show({ base }) }, { type: 'divider' }, { diff --git a/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx b/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx index 095816ac7..2f224eddc 100644 --- a/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx +++ b/src/renderer/src/pages/knowledge/components/KnowledgeSettings.tsx @@ -3,7 +3,8 @@ import { TopView } from '@renderer/components/TopView' import { DEFAULT_KNOWLEDGE_DOCUMENT_COUNT } from '@renderer/config/constant' import { getEmbeddingMaxContext } from '@renderer/config/embedings' import { isEmbeddingModel, isRerankModel } from '@renderer/config/models' -import { useKnowledge, useOcrProviders } from '@renderer/hooks/useKnowledge' +import { useKnowledge } from '@renderer/hooks/useKnowledge' +import { useOcrProviders } from '@renderer/hooks/useOcr' import { useProviders } from '@renderer/hooks/useProvider' import { SettingRowTitle } from '@renderer/pages/settings' import { getModelUniqId } from '@renderer/services/ModelService' @@ -87,7 +88,7 @@ const PopupContainer: React.FC = ({ base: _base, resolve }) => { const settingItems: TabsProps['items'] = [ { key: '1', - label: t('knowledge.settings.general'), + label: t('settings.general'), children: ( @@ -172,11 +173,11 @@ const PopupContainer: React.FC = ({ base: _base, resolve }) => { }, { key: '2', - label: t('knowledge.settings.ocr'), + label: t('settings.tool.ocr.title'), children: ( - {t('settings.knowledge.ocr.provider')} + {t('settings.tool.ocr.provider')}
{ - const provider = ocrProviders.find((p) => p.id === value) - if (!provider) return - setSelectedProvider(provider) - }} - placeholder={t('settings.websearch.search_provider_placeholder')} + onChange={(value: string) => updateSelectedOcrProvider(value)} + placeholder={t('settings.tool.ocr.provider_placeholder')} options={ocrProviders.map((p) => ({ value: p.id, label: p.name }))} />
- - {selectedProvider && } - + {selectedProvider && ( + + + + )} ) } diff --git a/src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BasicSettings.tsx b/src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BasicSettings.tsx new file mode 100644 index 000000000..1b8402833 --- /dev/null +++ b/src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BasicSettings.tsx @@ -0,0 +1,53 @@ +import { InfoCircleOutlined } from '@ant-design/icons' +import { useTheme } from '@renderer/context/ThemeProvider' +import { useAppDispatch, useAppSelector } from '@renderer/store' +import { setEnhanceMode, setMaxResult, setSearchWithTime } from '@renderer/store/websearch' +import { Slider, Switch, Tooltip } from 'antd' +import { t } from 'i18next' +import { FC } from 'react' + +import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '../..' + +const BasicSettings: FC = () => { + const { theme } = useTheme() + const searchWithTime = useAppSelector((state) => state.websearch.searchWithTime) + const enhanceMode = useAppSelector((state) => state.websearch.enhanceMode) + const maxResults = useAppSelector((state) => state.websearch.maxResults) + + const dispatch = useAppDispatch() + + return ( + + {t('settings.general.title')} + + + {t('settings.tool.websearch.search_with_time')} + dispatch(setSearchWithTime(checked))} /> + + + + + {t('settings.tool.websearch.enhance_mode')} + + + + + dispatch(setEnhanceMode(checked))} /> + + + + {t('settings.tool.websearch.search_max_result')} + dispatch(setMaxResult(value))} + /> + + + ) +} +export default BasicSettings diff --git a/src/renderer/src/pages/settings/WebSearchSettings/BlacklistSettings.tsx b/src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BlacklistSettings.tsx similarity index 83% rename from src/renderer/src/pages/settings/WebSearchSettings/BlacklistSettings.tsx rename to src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BlacklistSettings.tsx index 8441c0e33..6491c19eb 100644 --- a/src/renderer/src/pages/settings/WebSearchSettings/BlacklistSettings.tsx +++ b/src/renderer/src/pages/settings/ToolSettings/WebSearchSettings/BlacklistSettings.tsx @@ -7,7 +7,7 @@ import TextArea from 'antd/es/input/TextArea' import { t } from 'i18next' import { FC, useEffect, useState } from 'react' -import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..' +import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '../..' const BlacklistSettings: FC = () => { const [errFormat, setErrFormat] = useState(false) @@ -45,22 +45,22 @@ const BlacklistSettings: FC = () => { return ( <> - {t('settings.websearch.blacklist')} + {t('settings.tool.websearch.blacklist')} - {t('settings.websearch.blacklist_description')} + {t('settings.tool.websearch.blacklist_description')}