diff --git a/CHANGELOG.md b/CHANGELOG.md index 26591baa..3941408b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ ## [Unreleased] +### Changed + +- 配置面板改为左右分区布局:左侧分区导航(常规 / 连接 / AI / 关于)、右侧按分区归类展示配置项,替代此前单列平铺;分区结构为后续扩展(主题、编辑器风格、上下文窗口等)预留。 + ## [0.6.0] - 2026-06-23 > 首个 0.6 正式版。本版重点: diff --git a/apps/desktop/src/renderer/src/components/common/Modal.tsx b/apps/desktop/src/renderer/src/components/common/Modal.tsx index b2d7a56f..a09ce85d 100644 --- a/apps/desktop/src/renderer/src/components/common/Modal.tsx +++ b/apps/desktop/src/renderer/src/components/common/Modal.tsx @@ -3,9 +3,10 @@ import { useTranslation } from 'react-i18next'; import type { CSSProperties, ReactNode } from 'react'; import { CloseIcon } from './icons'; -type ModalSize = 'md' | 'sm' | 'confirm'; +type ModalSize = 'lg' | 'md' | 'sm' | 'confirm'; const SIZE_CLASS: Record = { + lg: 'modal modal-lg', md: 'modal', sm: 'modal modal-sm', confirm: 'modal modal-confirm', diff --git a/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx b/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx index b0cc2d43..27db360a 100644 --- a/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx +++ b/apps/desktop/src/renderer/src/components/features/settings/SettingsModal.tsx @@ -1,6 +1,14 @@ +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import type { AppInfo, AppPaths, Config, SupportedLanguage } from '@meebox/shared'; -import { ConfirmModal, Modal } from '../../common'; +import { + ConfirmModal, + GlobeIcon, + Modal, + QuestionIcon, + RobotIcon, + SettingsIcon, +} from '../../common'; import { useSettingsDraft } from './hooks/useSettingsDraft'; import { ConnectionEditorModal } from './editors/ConnectionEditorModal'; import { LlmEditorModal } from './editors/LlmEditorModal'; @@ -15,6 +23,23 @@ import { WorkDirSection } from './sections/WorkDirSection'; import { CacheDirSection } from './sections/CacheDirSection'; import { RuntimeSection } from './sections/RuntimeSection'; +type SettingsCategory = 'general' | 'connection' | 'ai' | 'about'; + +/** + * 配置分区导航元数据(左侧栏)。新增配置分区在此登记一项,并在右侧面板的 switch + * 中渲染对应 section —— 分区结构为后续扩展(主题 / 编辑器 / 上下文窗口等)预留。 + */ +const SETTINGS_CATEGORIES: ReadonlyArray<{ + id: SettingsCategory; + labelKey: string; + Icon: typeof SettingsIcon; +}> = [ + { id: 'general', labelKey: 'settings.catGeneral', Icon: SettingsIcon }, + { id: 'connection', labelKey: 'settings.catConnection', Icon: GlobeIcon }, + { id: 'ai', labelKey: 'settings.catAi', Icon: RobotIcon }, + { id: 'about', labelKey: 'settings.catAbout', Icon: QuestionIcon }, +]; + interface SettingsModalProps { info: AppInfo; paths: AppPaths; @@ -48,6 +73,7 @@ export function SettingsModal({ onClose, }: SettingsModalProps) { const { t } = useTranslation(); + const [category, setCategory] = useState('general'); const s = useSettingsDraft({ config, paths, @@ -61,10 +87,11 @@ export function SettingsModal({ return ( <>
@@ -94,38 +121,70 @@ export function SettingsModal({ } > - - - - - s.setProxyEditor(s.proxy)} /> - void s.pickAgentDir()} - /> - - void s.pickReposDir()} - totalBytes={s.totalBytes} - /> - +
+ +
+ {category === 'general' && ( + + )} + {category === 'connection' && ( + <> + + + s.setProxyEditor(s.proxy)} /> + void s.pickReposDir()} + totalBytes={s.totalBytes} + /> + + )} + {category === 'ai' && ( + <> + + void s.pickAgentDir()} + /> + + )} + {category === 'about' && ( + <> + + + + )} +
+
{s.llmEditor && ( diff --git a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json index f04dd454..0cdab16a 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/de-DE.json +++ b/apps/desktop/src/renderer/src/i18n/locales/de-DE.json @@ -636,6 +636,10 @@ "cacheDirTitle": "Cache-Verzeichnis", "cacheUsage": "Cache-Nutzung", "calculating": "Berechne…", + "catAbout": "Info", + "catAi": "KI", + "catConnection": "Verbindung", + "catGeneral": "Allgemein", "checkFailed": "Prüfung fehlgeschlagen: {{error}}", "checkUpdate": "Nach Updates suchen", "checkUpdateTitle": "GitHub auf die neueste Version prüfen (nur Erkennung, keine automatische Installation)", diff --git a/apps/desktop/src/renderer/src/i18n/locales/en-US.json b/apps/desktop/src/renderer/src/i18n/locales/en-US.json index 48b89e92..2f2833a4 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/en-US.json +++ b/apps/desktop/src/renderer/src/i18n/locales/en-US.json @@ -636,6 +636,10 @@ "cacheDirTitle": "Cache Directory", "cacheUsage": "Cache Usage", "calculating": "Calculating…", + "catAbout": "About", + "catAi": "AI", + "catConnection": "Connection", + "catGeneral": "General", "checkFailed": "Check failed: {{error}}", "checkUpdate": "Check for Updates", "checkUpdateTitle": "Check GitHub for the latest version (detection only, no auto-install)", diff --git a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json index 2fc80f39..da1cddca 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json +++ b/apps/desktop/src/renderer/src/i18n/locales/ja-JP.json @@ -620,6 +620,10 @@ "cacheDirTitle": "キャッシュディレクトリ", "cacheUsage": "キャッシュ使用量", "calculating": "計算中…", + "catAbout": "情報", + "catAi": "AI", + "catConnection": "接続", + "catGeneral": "一般", "checkFailed": "チェックに失敗しました:{{error}}", "checkUpdate": "アップデートを確認", "checkUpdateTitle": "GitHub で最新バージョンを確認(検出のみ、自動インストールなし)", diff --git a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json index f16d2fbc..1f59c923 100644 --- a/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json +++ b/apps/desktop/src/renderer/src/i18n/locales/zh-CN.json @@ -620,6 +620,10 @@ "cacheDirTitle": "缓存目录", "cacheUsage": "缓存占用", "calculating": "计算中…", + "catAbout": "关于", + "catAi": "AI", + "catConnection": "连接", + "catGeneral": "常规", "checkFailed": "检查失败:{{error}}", "checkUpdate": "检查更新", "checkUpdateTitle": "查 GitHub 最新版本(仅检测,不自动安装)", diff --git a/apps/desktop/src/renderer/src/styles/common/modal.scss b/apps/desktop/src/renderer/src/styles/common/modal.scss index 8d2b2e17..91efe1cc 100644 --- a/apps/desktop/src/renderer/src/styles/common/modal.scss +++ b/apps/desktop/src/renderer/src/styles/common/modal.scss @@ -58,6 +58,14 @@ overflow-y: auto; } +// 宽尺寸:左右分区类模态(如 SettingsModal 分区导航 + 内容)需要更宽横向空间, +// 让左导航与右侧内容各得其所。定高(受 .modal 的 max-height: 84vh 上限约束), +// 使切换分区时模态尺寸恒定、右侧内容区独立滚动而非整体撑高。 +.modal-lg { + max-width: 880px; + height: 720px; +} + // ConfirmModal: 跟 SettingsModal 共用 .modal-backdrop/.modal/.modal-header,加几条 // 小尺寸 + 底部操作行特化 .modal-confirm { diff --git a/apps/desktop/src/renderer/src/styles/features/settings/forms.scss b/apps/desktop/src/renderer/src/styles/features/settings/forms.scss index 91352cd1..dc34ffc4 100644 --- a/apps/desktop/src/renderer/src/styles/features/settings/forms.scss +++ b/apps/desktop/src/renderer/src/styles/features/settings/forms.scss @@ -4,6 +4,76 @@ @use '../../tokens' as *; @use '../../mixins' as *; +// 配置面板左右分区:模态 body 去内边距、由本布局接管;左侧分区导航固定不滚, +// 右侧分区内容独立滚动。分区结构为后续扩展(主题 / 编辑器 / 上下文窗口等)预留。 +.modal-body.settings-modal-body { + padding: 0; + overflow: hidden; + display: flex; + flex: 1; + min-height: 0; +} +.settings-layout { + display: flex; + flex: 1; + min-width: 0; + // 撑满定高模态(.modal-lg):左导航固定、右面板独立滚动,不随分区内容增减高度 + min-height: 0; +} +.settings-nav { + flex: 0 0 168px; + display: flex; + flex-direction: column; + gap: $space-1; + padding: $space-5 $space-4; + // 与模态主体同色($bg-elev),仅以右侧分隔线区分导航区,避免色块割裂 + border-right: 1px solid $border-default; + overflow-y: auto; +} +.settings-nav-item { + display: flex; + align-items: center; + gap: $space-3; + padding: $space-3 $space-4; + border: none; + border-radius: $radius-md; + background: transparent; + color: $text-body; + font-size: $fs-lg; + text-align: left; + cursor: pointer; + + svg { + flex-shrink: 0; + color: $text-muted; + } + + &:hover { + background: $bg-hover; + } + + &.active { + background: $color-accent-bg-fade; + color: $text-primary; + font-weight: 500; + + svg { + color: $color-accent; + } + } +} +.settings-panel { + flex: 1; + min-width: 0; + overflow-y: auto; + padding: $space-8; + + // 分区内末个 section 去掉多余底部留白 + .modal-section:last-child { + margin-bottom: 0; + } +} + // 语言下拉:固定宽度、靠右(块定位),文本左对齐;不被 .settings-input 的 flex:1 撑满(复合选择器提权) .settings-input.settings-language-select { flex: 0 0 auto;