refactor(settings): reorganize the menu layout in the settings page

- Introduced QuickPhraseSettings component for managing quick phrases with add, edit, and delete functionality.
- Added PreprocessSettings component to configure document preprocessing options, including provider selection.
- Updated SettingsPage to include links to the new Quick Phrase and Preprocess settings.
- Removed the deprecated ToolSettings component and its associated routes.
- Enhanced WebSearchSettings with new compression settings and improved UI for managing web search providers.
This commit is contained in:
kangfenmao 2025-08-13 10:40:50 +08:00
parent d579872078
commit 2dd2bee940
21 changed files with 73 additions and 135 deletions

View File

@ -9,10 +9,10 @@ import { CancellationToken, UpdateInfo } from 'builder-util-runtime'
import { app, BrowserWindow, dialog } from 'electron'
import { AppUpdater as _AppUpdater, autoUpdater, Logger, NsisUpdater, UpdateCheckResult } from 'electron-updater'
import path from 'path'
import { windowService } from './WindowService'
import icon from '../../../build/icon.png?asset'
import { configManager } from './ConfigManager'
import { windowService } from './WindowService'
const logger = loggerService.withContext('AppUpdater')

View File

@ -2889,7 +2889,7 @@
"tagsPlaceholder": "Enter tags",
"timeout": "Timeout",
"timeoutTooltip": "Timeout in seconds for requests to this server, default is 60 seconds",
"title": "MCP Settings",
"title": "MCP",
"tools": {
"autoApprove": {
"label": "Auto Approve",
@ -3432,10 +3432,10 @@
"title": "Settings",
"tool": {
"preprocess": {
"provider": "Pre Process Provider",
"provider_placeholder": "Choose a Pre Process provider",
"title": "Pre Process",
"tooltip": "In Settings -> Tools, set a document preprocessing service provider. Document preprocessing can effectively improve the retrieval performance of complex format documents and scanned documents."
"provider": "Document Processing Provider",
"provider_placeholder": "Choose a document processing provider",
"title": "Document Processing",
"tooltip": "In Settings -> Tools, set a document processing service provider. Document processing can effectively improve the retrieval performance of complex format documents and scanned documents."
},
"title": "Other Settings",
"websearch": {

View File

@ -2889,7 +2889,7 @@
"tagsPlaceholder": "タグを入力",
"timeout": "タイムアウト",
"timeoutTooltip": "このサーバーへのリクエストのタイムアウト時間、デフォルトは60秒です",
"title": "MCP 設定",
"title": "MCP",
"tools": {
"autoApprove": {
"label": "自動承認",

View File

@ -2889,7 +2889,7 @@
"tagsPlaceholder": "Введите теги",
"timeout": "Тайм-аут",
"timeoutTooltip": "Тайм-аут в секундах для запросов к этому серверу, по умолчанию 60 секунд",
"title": "Настройки MCP",
"title": "MCP",
"tools": {
"autoApprove": {
"label": "Автоматическое одобрение",
@ -3432,10 +3432,10 @@
"title": "Настройки",
"tool": {
"preprocess": {
"provider": редварительная обработка Поставщик",
"provider_placeholder": "Выберите поставщика услуг предварительной обработки",
"title": "Предварительная обработка",
"tooltip": "В настройках (Настройки -> Инструменты) укажите поставщика услуги предварительной обработки документов. Предварительная обработка документов может значительно повысить эффективность поиска для документов сложных форматов и отсканированных документов."
"provider": оставщик обработки документов",
"provider_placeholder": "Выберите поставщика услуг обработки документов",
"title": "Обработка документов",
"tooltip": "В настройках (Настройки -> Инструменты) укажите поставщика услуг обработки документов. Обработка документов может значительно повысить эффективность поиска для документов сложных форматов и отсканированных документов."
},
"title": "Другие настройки",
"websearch": {

View File

@ -176,7 +176,7 @@
"enableFirst": "请先在 MCP 设置中启用此服务器",
"label": "MCP 服务器",
"noServersAvailable": "无可用 MCP 服务器。请在设置中添加服务器",
"title": "MCP 设置"
"title": "MCP 服务器"
},
"model": "模型设置",
"more": "助手设置",
@ -2889,7 +2889,7 @@
"tagsPlaceholder": "输入标签",
"timeout": "超时",
"timeoutTooltip": "对该服务器请求的超时时间(秒),默认为 60 秒",
"title": "MCP 设置",
"title": "MCP",
"tools": {
"autoApprove": {
"label": "自动批准",
@ -3432,10 +3432,10 @@
"title": "设置",
"tool": {
"preprocess": {
"provider": "文档处理服务商",
"provider_placeholder": "选择一个文档处理服务商",
"title": "文档处理",
"tooltip": "在设置 -> 工具中设置文档处理服务商,文档处理可以有效提升复杂格式文档与扫描版文档的检索效果"
"provider": "文档处理服务商",
"provider_placeholder": "选择一个文档处理服务商",
"title": "文档处理",
"tooltip": "在设置 -> 工具中设置文档处理服务商,文档处理可以有效提升复杂格式文档与扫描版文档的检索效果"
},
"title": "其他设置",
"websearch": {

View File

@ -2889,7 +2889,7 @@
"tagsPlaceholder": "輸入標籤",
"timeout": "超時",
"timeoutTooltip": "對該伺服器請求的超時時間(秒),預設為 60 秒",
"title": "MCP 設定",
"title": "MCP",
"tools": {
"autoApprove": {
"label": "自動批准",
@ -3432,10 +3432,10 @@
"title": "設定",
"tool": {
"preprocess": {
"provider": "前置處理供應商",
"provider_placeholder": "選擇一個處理供應商",
"title": "前置處理",
"tooltip": "在「設定」->「工具」中設定文件處理服務供應商。文件處理可有效提升複雜格式文件及掃描文件的檢索效能"
"provider": "文件處理供應商",
"provider_placeholder": "選擇一個文件處理供應商",
"title": "文件處理",
"tooltip": "在「設定」->「工具」中設定文件處理服務供應商。文件處理可有效提升複雜格式文件及掃描文件的檢索效能"
},
"title": "其他設定",
"websearch": {

View File

@ -20,7 +20,7 @@ import {
SettingRowTitle,
SettingSubtitle,
SettingTitle
} from '../..'
} from '..'
interface Props {
provider: PreprocessProvider

View File

@ -6,7 +6,7 @@ import { Select } from 'antd'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '../..'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
import PreprocessProviderSettings from './PreprocessSettings'
const PreprocessSettings: FC = () => {

View File

@ -535,6 +535,7 @@ const ProviderListContainer = styled.div`
flex-direction: column;
min-width: calc(var(--settings-width) + 10px);
height: calc(100vh - var(--navbar-height));
padding-bottom: 5px;
border-right: 0.5px solid var(--color-border);
`

View File

@ -11,7 +11,7 @@ import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingTitle } from '..'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingTitle } from '.'
const { TextArea } = Input

View File

@ -1,10 +1,13 @@
import { GlobalOutlined } from '@ant-design/icons'
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import Scrollbar from '@renderer/components/Scrollbar'
import ModelSettings from '@renderer/pages/settings/ModelSettings/ModelSettings'
import { Divider as AntDivider } from 'antd'
import {
Brain,
Cloud,
Command,
FolderCog,
FileCode,
HardDrive,
Info,
MonitorCog,
@ -12,7 +15,8 @@ import {
PictureInPicture2,
Settings2,
SquareTerminal,
TextCursorInput
TextCursorInput,
Zap
} from 'lucide-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
@ -25,11 +29,13 @@ import DisplaySettings from './DisplaySettings/DisplaySettings'
import GeneralSettings from './GeneralSettings'
import MCPSettings from './MCPSettings'
import MemorySettings from './MemorySettings'
import PreprocessSettings from './PreprocessSettings'
import ProvidersList from './ProviderSettings'
import QuickAssistantSettings from './QuickAssistantSettings'
import QuickPhraseSettings from './QuickPhraseSettings'
import SelectionAssistantSettings from './SelectionAssistantSettings/SelectionAssistantSettings'
import ShortcutSettings from './ShortcutSettings'
import ToolSettings from './ToolSettings'
import WebSearchSettings from './WebSearchSettings'
const SettingsPage: FC = () => {
const { pathname } = useLocation()
@ -56,6 +62,7 @@ const SettingsPage: FC = () => {
{t('settings.model')}
</MenuItem>
</MenuItemLink>
<Divider />
<MenuItemLink to="/settings/general">
<MenuItem className={isRoute('/settings/general')}>
<Settings2 size={18} />
@ -74,30 +81,44 @@ const SettingsPage: FC = () => {
{t('settings.data.title')}
</MenuItem>
</MenuItemLink>
<Divider />
<MenuItemLink to="/settings/mcp">
<MenuItem className={isRoute('/settings/mcp')}>
<SquareTerminal size={18} />
{t('settings.mcp.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/websearch">
<MenuItem className={isRoute('/settings/websearch')}>
<GlobalOutlined style={{ fontSize: 18 }} />
{t('settings.tool.websearch.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/memory">
<MenuItem className={isRoute('/settings/memory')}>
<Brain size={18} />
{t('memory.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/preprocess">
<MenuItem className={isRoute('/settings/preprocess')}>
<FileCode size={18} />
{t('settings.tool.preprocess.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/quickphrase">
<MenuItem className={isRoute('/settings/quickphrase')}>
<Zap size={18} />
{t('settings.quickPhrase.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/shortcut">
<MenuItem className={isRoute('/settings/shortcut')}>
<Command size={18} />
{t('settings.shortcuts.title')}
</MenuItem>
</MenuItemLink>
<MenuItemLink to="/settings/tool">
<MenuItem className={isRoute('/settings/tool')}>
<FolderCog size={18} />
{t('settings.tool.title')}
</MenuItem>
</MenuItemLink>
<Divider />
<MenuItemLink to="/settings/quickAssistant">
<MenuItem className={isRoute('/settings/quickAssistant')}>
<PictureInPicture2 size={18} />
@ -110,6 +131,7 @@ const SettingsPage: FC = () => {
{t('selection.name')}
</MenuItem>
</MenuItemLink>
<Divider />
<MenuItemLink to="/settings/about">
<MenuItem className={isRoute('/settings/about')}>
<Info size={18} />
@ -121,7 +143,9 @@ const SettingsPage: FC = () => {
<Routes>
<Route path="provider" element={<ProvidersList />} />
<Route path="model" element={<ModelSettings />} />
<Route path="tool/*" element={<ToolSettings />} />
<Route path="websearch" element={<WebSearchSettings />} />
<Route path="preprocess" element={<PreprocessSettings />} />
<Route path="quickphrase" element={<QuickPhraseSettings />} />
<Route path="mcp/*" element={<MCPSettings />} />
<Route path="memory" element={<MemorySettings />} />
<Route path="general/*" element={<GeneralSettings />} />
@ -149,21 +173,22 @@ const ContentContainer = styled.div`
flex: 1;
flex-direction: row;
height: calc(100vh - var(--navbar-height));
padding: 1px 0;
`
const SettingMenus = styled.ul`
const SettingMenus = styled(Scrollbar)`
display: flex;
flex-direction: column;
min-width: var(--settings-width);
border-right: 0.5px solid var(--color-border);
padding: 10px;
user-select: none;
gap: 5px;
`
const MenuItemLink = styled(Link)`
text-decoration: none;
color: var(--color-text-1);
margin-bottom: 5px;
`
const MenuItem = styled.li`
@ -182,12 +207,6 @@ const MenuItem = styled.li`
font-size: 16px;
opacity: 0.8;
}
.iconfont {
font-size: 18px;
line-height: 18px;
opacity: 0.7;
margin-left: -1px;
}
&:hover {
background: var(--color-background-soft);
}
@ -203,4 +222,8 @@ const SettingContent = styled.div`
flex: 1;
`
const Divider = styled(AntDivider)`
margin: 3px 0;
`
export default SettingsPage

View File

@ -1,79 +0,0 @@
import { GlobalOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import ListItem from '@renderer/components/ListItem'
import { FileCode, Zap } from 'lucide-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { Link, Route, Routes, useLocation } from 'react-router-dom'
import styled from 'styled-components'
import PreprocessSettings from './PreprocessSettings'
import QuickPhraseSettings from './QuickPhraseSettings'
import WebSearchSettings from './WebSearchSettings'
const ToolSettings: FC = () => {
const { t } = useTranslation()
const { pathname } = useLocation()
const menuItems = [
{ key: 'web-search', title: 'settings.tool.websearch.title', icon: <GlobalOutlined style={{ fontSize: 16 }} /> },
{ key: 'preprocess', title: 'settings.tool.preprocess.title', icon: <FileCode size={16} /> },
{ key: 'quick-phrase', title: 'settings.quickPhrase.title', icon: <Zap size={16} /> }
]
const isActive = (key: string): boolean => {
const basePath = '/settings/tool'
if (key === 'web-search') {
return pathname === basePath || pathname === `${basePath}/` || pathname === `${basePath}/${key}`
}
return pathname === `${basePath}/${key}`
}
return (
<Container>
<MenuList>
{menuItems.map((item) => (
<Link key={item.key} to={`/settings/tool/${item.key}`} style={{ textDecoration: 'none', color: 'inherit' }}>
<ListItem
title={t(item.title)}
active={isActive(item.key)}
titleStyle={{ fontWeight: 500 }}
icon={item.icon}
/>
</Link>
))}
</MenuList>
<ContentArea>
<Routes>
<Route path="/" element={<WebSearchSettings />} />
<Route path="/web-search" element={<WebSearchSettings />} />
<Route path="/preprocess" element={<PreprocessSettings />} />
<Route path="/quick-phrase" element={<QuickPhraseSettings />} />
</Routes>
</ContentArea>
</Container>
)
}
const Container = styled(HStack)`
flex: 1;
`
const MenuList = styled.div`
display: flex;
flex-direction: column;
gap: 5px;
width: var(--settings-width);
padding: 12px;
border-right: 0.5px solid var(--color-border);
height: 100%;
.iconfont {
line-height: 16px;
}
`
const ContentArea = styled.div`
display: flex;
flex: 1;
height: 100%;
`
export default ToolSettings

View File

@ -7,7 +7,7 @@ import { t } from 'i18next'
import { Info } from 'lucide-react'
import { FC } from 'react'
import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '../..'
import { SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
const BasicSettings: FC = () => {
const { theme } = useTheme()

View File

@ -10,7 +10,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 '..'
import AddSubscribePopup from './AddSubscribePopup'
type TableRowSelection<T extends object = object> = TableProps<T>['rowSelection']

View File

@ -12,14 +12,7 @@ import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import {
SettingDivider,
SettingHelpLink,
SettingHelpText,
SettingHelpTextRow,
SettingSubtitle,
SettingTitle
} from '../..'
import { SettingDivider, SettingHelpLink, SettingHelpText, SettingHelpTextRow, SettingSubtitle, SettingTitle } from '..'
const logger = loggerService.withContext('WebSearchProviderSetting')
interface Props {

View File

@ -6,7 +6,7 @@ import { hasObjectKey } from '@renderer/utils'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '../..'
import { SettingContainer, SettingDivider, SettingGroup, SettingRow, SettingRowTitle, SettingTitle } from '..'
import BasicSettings from './BasicSettings'
import BlacklistSettings from './BlacklistSettings'
import CompressionSettings from './CompressionSettings'

View File

@ -7,7 +7,7 @@ export const SettingContainer = styled.div<{ theme?: ThemeMode }>`
display: flex;
flex-direction: column;
flex: 1;
padding: 10px;
padding: 15px 18px;
overflow-y: scroll;
background: ${(props) => (props.theme === 'dark' ? 'transparent' : 'var(--color-background-soft)')};