mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-24 10:40:07 +08:00
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:
parent
d579872078
commit
2dd2bee940
@ -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')
|
||||
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -2889,7 +2889,7 @@
|
||||
"tagsPlaceholder": "タグを入力",
|
||||
"timeout": "タイムアウト",
|
||||
"timeoutTooltip": "このサーバーへのリクエストのタイムアウト時間(秒)、デフォルトは60秒です",
|
||||
"title": "MCP 設定",
|
||||
"title": "MCP",
|
||||
"tools": {
|
||||
"autoApprove": {
|
||||
"label": "自動承認",
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
SettingRowTitle,
|
||||
SettingSubtitle,
|
||||
SettingTitle
|
||||
} from '../..'
|
||||
} from '..'
|
||||
|
||||
interface Props {
|
||||
provider: PreprocessProvider
|
||||
@ -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 = () => {
|
||||
@ -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);
|
||||
`
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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()
|
||||
@ -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']
|
||||
@ -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 {
|
||||
@ -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'
|
||||
@ -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)')};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user