From b04cf865d210d3de3d5ea0fbbaf9795249a1fc85 Mon Sep 17 00:00:00 2001 From: jackwener Date: Tue, 23 Jun 2026 18:59:23 +0800 Subject: [PATCH] =?UTF-8?q?PR-SETTINGS-NAV-REGROUP-0:=205=20nav=20groups?= =?UTF-8?q?=20=E2=86=92=203=20+=20Beta=20badge=20primitive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WAWQAQ msg `a9ef0d5d`: maka has 5 settings nav groups (基础, AI, 集成, 数据, 其他) with `数据` carrying only a single item — visibly noisy. Reference uses 3 groups with one big "kitchen sink" group instead. Changes: - `NAV_GROUP_ORDER` 5 → 3: - 基础 → 通用 - AI + 集成 → AI 与集成 (merged) - 数据 + 其他 → 系统 (merged) - `deriveNavGroupSummary` updated: AI 与集成 falls through AI summary first, then integrations summary if no AI signals to surface. - `SettingsNavItem.badge?: 'Beta'` field added; renders a small accent-tinted chip in the 3rd grid column of `.settingsNavItem`. Initial use: 联网搜索 → Beta (the Tavily provider integration is the only beta-stage feature live today). - `.settingsNavBadge` primitive: 18px tall, 6px radius, 12% accent bg, accent text, 10px / 600 / 0.04em tracking. - `.settingsNavItem` grid `24 1fr` → `24 1fr auto` for badge column. Contract test (settings-roadmap-cleanup-contract) loosened the class-name ban on `settingsNavBadge` since the primitive is now legitimately reused as a Beta chip. The copy-level "即将推出 / roadmap / providerComingSoon" bans still hold. 1466 / 1466 tests pass. --- .../settings-roadmap-cleanup-contract.test.ts | 9 +++- .../src/renderer/settings/SettingsModal.tsx | 52 ++++++++++++------- .../renderer/settings/nav-group-summary.ts | 26 ++++++---- apps/desktop/src/renderer/styles.css | 23 ++++++-- 4 files changed, 78 insertions(+), 32 deletions(-) diff --git a/apps/desktop/src/main/__tests__/settings-roadmap-cleanup-contract.test.ts b/apps/desktop/src/main/__tests__/settings-roadmap-cleanup-contract.test.ts index bb8f4f130f..9b65577fff 100644 --- a/apps/desktop/src/main/__tests__/settings-roadmap-cleanup-contract.test.ts +++ b/apps/desktop/src/main/__tests__/settings-roadmap-cleanup-contract.test.ts @@ -27,7 +27,11 @@ describe('Settings coming-soon cleanup contract', () => { const styles = await readRepo('apps/desktop/src/renderer/styles.css'); const providerCatalog = await readRepo('packages/core/src/llm-connections.ts'); assert.doesNotMatch(settings, /comingSoon\??:/, 'Settings nav items must not carry stale comingSoon flags'); - assert.doesNotMatch(settings, /settingsNavBadge/, 'Settings nav must not render stale Roadmap badges'); + // PR-SETTINGS-NAV-REGROUP-0 (WAWQAQ msg `a9ef0d5d`): `settingsNavBadge` + // is now legitimately reused as a Beta chip on shipping features. + // The earlier blanket ban on the class name is dropped; the other + // copy-level assertions in this block (e.g. command palette `即将推出` + // ban below) still guard the original intent. assert.doesNotMatch(palette, /即将推出/, 'Command palette settings entries must not advertise dead coming-soon hints'); assert.doesNotMatch(palette, /comingSoon/, 'Command palette must not read removed nav comingSoon flags'); assert.doesNotMatch(providers, /即将支持的 OAuth 订阅登录/, 'Providers header must not advertise future OAuth login as a model-provider affordance'); @@ -37,6 +41,9 @@ describe('Settings coming-soon cleanup contract', () => { assert.doesNotMatch(providers, /还没有供应商/, 'ProvidersPanel empty state should not read like unfinished product setup'); assert.doesNotMatch(providerCatalog, /catalogBadge:\s*'Soon'|future phase/, 'provider catalog metadata must not keep soon/future-phase copy'); assert.doesNotMatch(styles, /ComingSoonPage|roadmap banner|providerComingSoon|providerCatalogSoon/, 'Settings CSS must not keep stale coming-soon/provider-roadmap naming'); + // PR-SETTINGS-NAV-REGROUP-0: `.settingsNavBadge` is reused as the Beta + // chip primitive. Lock it down so we don't lose it accidentally. + assert.match(styles, /\.settingsNavBadge\s*\{/); }); it('keeps feature status pages product-scoped instead of demo-version or future-roadmap copy', async () => { diff --git a/apps/desktop/src/renderer/settings/SettingsModal.tsx b/apps/desktop/src/renderer/settings/SettingsModal.tsx index 71b2b5cd63..8dea8eeaed 100644 --- a/apps/desktop/src/renderer/settings/SettingsModal.tsx +++ b/apps/desktop/src/renderer/settings/SettingsModal.tsx @@ -137,6 +137,12 @@ type SettingsNavItem = { * label. Helps the user understand "where am I?" at the page top. */ description?: string; + /** + * PR-SETTINGS-NAV-REGROUP-0 (WAWQAQ msg `a9ef0d5d`): render a small + * "Beta" chip next to the nav label. Reference uses this for the + * 应用快照 / 工作台 items. + */ + badge?: 'Beta'; }; type AccountSecretProbeStatus = boolean | 'loading' | 'error'; @@ -211,37 +217,40 @@ export type { SettingsNavGroup }; // PR-SETTINGS-IA-CONSOLIDATE-0 + PR-SETTINGS-REVIEW-0: WAWQAQ msg // `886f6406` rolled back the 记忆+回顾 merge — the combined page was // too dense. 记忆 and 每日回顾 are separate nav items again. +// PR-SETTINGS-NAV-REGROUP-0 (WAWQAQ msg `a9ef0d5d`): 5 narrow groups +// → 3 wider groups. 基础→通用, AI+集成→「AI 与集成」, 数据+其他→系统. +// Mirrors reference's tighter grouping (1 big group + a couple small +// ones) instead of 5 categories with only 1-3 items each. export const SETTINGS_NAV: SettingsNavItem[] = [ - // Group 1: 基础 — 通用 (kitchen sink) + 外观 (personalization + theme merged) - { id: 'general', label: '通用', Icon: SettingsIcon, enabled: true, group: '基础', + // Group 1: 通用 + { id: 'general', label: '通用', Icon: SettingsIcon, enabled: true, group: '通用', description: '隐身、启动、对话默认与网络代理等系统偏好。' }, - { id: 'appearance', label: '外观', Icon: Palette, enabled: true, group: '基础', + { id: 'appearance', label: '外观', Icon: Palette, enabled: true, group: '通用', description: '主题、配色、字体面板与个性化身份。' }, - // Group 2: AI — models, usage, memory, daily-review, voice+gateway - { id: 'models', label: '模型', Icon: Cpu, enabled: true, group: 'AI', + // Group 2: AI 与集成 — models, usage, memory, daily-review, voice+gateway, bots, search + { id: 'models', label: '模型', Icon: Cpu, enabled: true, group: 'AI 与集成', description: '模型连接、API key 与 OAuth 订阅管理。' }, - { id: 'usage', label: '使用统计', Icon: BarChart3, enabled: true, group: 'AI', + { id: 'usage', label: '使用统计', Icon: BarChart3, enabled: true, group: 'AI 与集成', description: 'token、模型、工具使用走势与配额追踪。' }, - { id: 'memory', label: '记忆', Icon: Brain, enabled: true, group: 'AI', + { id: 'memory', label: '记忆', Icon: Brain, enabled: true, group: 'AI 与集成', description: '本地 MEMORY.md、项目指令文件与上下文注入开关。' }, - { id: 'daily-review', label: '每日回顾', Icon: CalendarDays, enabled: true, group: 'AI', + { id: 'daily-review', label: '每日回顾', Icon: CalendarDays, enabled: true, group: 'AI 与集成', description: '当天对话、模型与工具用量汇总。' }, - { id: 'voice-gateway', label: '语音与网关', Icon: Volume2, enabled: true, group: 'AI', + { id: 'voice-gateway', label: '语音与网关', Icon: Volume2, enabled: true, group: 'AI 与集成', description: '语音转写与 Maka 开放网关 SSE 接入。' }, - // Group 3: 集成 — bot、搜索 (network/proxy now lives inside 通用) - { id: 'bot-chat', label: '机器人对话', Icon: Bot, enabled: true, group: '集成', + { id: 'bot-chat', label: '机器人对话', Icon: Bot, enabled: true, group: 'AI 与集成', description: 'Telegram / 飞书 / 企业微信等机器人凭据与运行状态。' }, - { id: 'search', label: '联网搜索', Icon: Search, enabled: true, group: '集成', - description: '联网搜索供应商(如 Tavily)凭据与隐私边界。' }, - // Group 4: 数据 - { id: 'data', label: '数据', Icon: Database, enabled: true, group: '数据', + { id: 'search', label: '联网搜索', Icon: Search, enabled: true, group: 'AI 与集成', + description: '联网搜索供应商(如 Tavily)凭据与隐私边界。', + badge: 'Beta' }, + // Group 3: 系统 — data, permissions, health, about + { id: 'data', label: '数据', Icon: Database, enabled: true, group: '系统', description: '本地工作区路径、备份与恢复。' }, - // Group 5: 其他 - { id: 'permissions', label: '权限与能力', Icon: ShieldCheck, enabled: true, group: '其他', + { id: 'permissions', label: '权限与能力', Icon: ShieldCheck, enabled: true, group: '系统', description: '系统权限授予状态与 Maka 能力运行时检查。' }, - { id: 'health', label: '健康', Icon: Activity, enabled: true, group: '其他', + { id: 'health', label: '健康', Icon: Activity, enabled: true, group: '系统', description: '运行时连接、模型探针与本地健康状态。' }, - { id: 'about', label: '关于', Icon: Info, enabled: true, group: '其他', + { id: 'about', label: '关于', Icon: Info, enabled: true, group: '系统', description: '版本、运行环境与隐私承诺。' }, ]; @@ -1002,6 +1011,11 @@ function SettingsSurface(props: { {item.label} + {item.badge && ( + + {item.badge} + + )} ))} diff --git a/apps/desktop/src/renderer/settings/nav-group-summary.ts b/apps/desktop/src/renderer/settings/nav-group-summary.ts index 95ef0c1e30..8b78ee9a25 100644 --- a/apps/desktop/src/renderer/settings/nav-group-summary.ts +++ b/apps/desktop/src/renderer/settings/nav-group-summary.ts @@ -16,13 +16,20 @@ import type { AppSettings, LlmConnection } from '@maka/core'; -export type SettingsNavGroup = '基础' | 'AI' | '集成' | '数据' | '其他'; +/** + * PR-SETTINGS-NAV-REGROUP-0 (WAWQAQ msg `a9ef0d5d`): 5 narrow groups + * collapsed to 3. `基础` → `通用`, `AI` + `集成` → `AI 与集成`, + * `数据` + `其他` → `系统`. Mirrors reference's tighter nav grouping + * (通用 / 扩展与集成 / 高级设置) where one big group carries most + * items instead of 5 tiny ones. + */ +export type SettingsNavGroup = '通用' | 'AI 与集成' | '系统'; /** * The render order used by the Settings modal sidebar. Lives here so the * nav-group enum and its presentation order stay in one place. */ -export const NAV_GROUP_ORDER: SettingsNavGroup[] = ['基础', 'AI', '集成', '数据', '其他']; +export const NAV_GROUP_ORDER: SettingsNavGroup[] = ['通用', 'AI 与集成', '系统']; export interface NavGroupSummary { /** Short text rendered next to the group label, e.g. "3 verified · 1 needs reauth". */ @@ -49,13 +56,14 @@ export interface NavGroupSummaryInput { */ export function deriveNavGroupSummary(input: NavGroupSummaryInput): NavGroupSummary | undefined { switch (input.group) { - case 'AI': - return summarizeAi(input.connections, input.defaultSlug); - case '集成': - return summarizeIntegrations(input.connections, input.settings); - case '数据': - case '基础': - case '其他': + case 'AI 与集成': + // PR-SETTINGS-NAV-REGROUP-0: AI and 集成 groups merged. Prefer + // showing the highest-urgency message — AI connection errors + // outrank proxy/bot status. + return summarizeAi(input.connections, input.defaultSlug) + ?? summarizeIntegrations(input.connections, input.settings); + case '通用': + case '系统': return undefined; } } diff --git a/apps/desktop/src/renderer/styles.css b/apps/desktop/src/renderer/styles.css index c393041887..d336e8d693 100644 --- a/apps/desktop/src/renderer/styles.css +++ b/apps/desktop/src/renderer/styles.css @@ -6997,13 +6997,12 @@ button:active { .settingsNavItem { /* PR-SETTINGS-SIDEBAR-SPACIOUS-0: roomier nav row matching reference. - Height 32→38, icon column 20→24, label gap 8→12, side padding - 8→12, label font 13→14. */ + PR-SETTINGS-NAV-REGROUP-0: 3rd grid column for optional Beta badge. */ width: calc(100% - 8px); height: 38px; min-height: 38px; display: grid; - grid-template-columns: 24px minmax(0, 1fr); + grid-template-columns: 24px minmax(0, 1fr) auto; align-items: center; gap: 12px; border: 0; @@ -7019,6 +7018,24 @@ button:active { transition: background-color 150ms var(--ease-out-strong), color 150ms var(--ease-out-strong); } +/* PR-SETTINGS-NAV-REGROUP-0 (WAWQAQ msg `a9ef0d5d`): small chip on nav + items that are still in beta — matches reference's pattern of + surfacing maturity inline rather than relegating to a separate + release notes view. */ +.settingsNavBadge { + display: inline-flex; + align-items: center; + height: 18px; + padding: 0 6px; + border-radius: 4px; + background: oklch(from var(--accent) l c h / 0.12); + color: var(--accent); + font-size: 10px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: none; +} + .settingsSidebar .settingsNavItem, .settingsSidebar .settingsNavItem[data-active="true"], .settingsSidebar .settingsNavItem:hover {