diff --git a/docs/plans/2026-08-28-chat-ui-fixes.md b/docs/plans/2026-08-28-chat-ui-fixes.md new file mode 100644 index 0000000..0e41876 --- /dev/null +++ b/docs/plans/2026-08-28-chat-ui-fixes.md @@ -0,0 +1,187 @@ +# 聊天前端 UI 修复计划(3 项) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans to implement task-by-task. + +**Goal:** 修复 3 个 UI 问题:(1) 项目管理抽屉内的「+新建项目」入口不可见 → 强化可见性与渲染鲁棒性;(2) 顶栏标题文本迁移到侧边栏品牌名下方;(3) 折叠侧边栏后折叠按钮遮挡 logo。 + +**Architecture:** 纯前端改动,仅涉及 `src/genesis/server/static/chat.html`(HTML 结构 + 内嵌 CSS + 内嵌 JS)。无后端、无 schema、无新依赖。 + +**Tech Stack:** 原生 HTML/CSS/JS(内嵌于 chat.html,无构建步骤、无前端测试框架);校验用 `node --check` + 浏览器手动核对。 + +## 根因说明(问题 1) + +代码层 `renderDrawerList()`(启动与 `openProjectDrawer → loadDrawerForm` 末尾均调用)确实会渲染「+新建项目」首项,且无 CSS 隐藏它、所有 `pf-*` 字段元素齐全。因此「看不到」是**可发现性问题**:该项与普通项目项外观几乎一致、位于左侧窄列易被忽略;同时若将来 `loadDrawerForm` 抛错会跳过 `renderDrawerList`,导致整列空白。 + +修复策略:**保留设计已有入口、不另增按钮**(遵循用户「不用再新增」的偏好),仅 (a) 给该项专属样式使其醒目,(b) 加固 `openProjectDrawer` 保证列表必现。 + +--- + +## File Structure + +- Modify: `src/genesis/server/static/chat.html` + - HTML:删除 header `

`;侧边栏 `.brand-name` 增加副标题;抽屉「+新建项目」项加 `di-create` 类。 + - CSS:新增 `.brand-sub`、`.drawer-item.di-create` 及其 hover;折叠态 `#sidebar-toggle` / `#session-list` 规则。 + - JS:`renderDrawerList` 首项加 `di-create` 类;`openProjectDrawer` 加固。 +- Docs: 本计划文档。 + +--- + +### Task 1: 让「+新建项目」可见且必现 + +**Files:** `src/genesis/server/static/chat.html` + +**Interfaces:** Consumes `renderDrawerList`、`openProjectDrawer`、`loadDrawerForm`、`guardDrawerDirty`、`drawerSelected`。 +**Produces:** 抽屉左侧顶部始终显示一个虚线蓝底、加粗的「+ 新建项目」项;即使 `loadDrawerForm` 异常也不影响该列表渲染。 + +- [ ] **Step 1: 写失败验收(手动)** + +浏览器打开(scripts/serve.py --fake)→ 顶栏项目下拉 → 点「+ 项目管理(打开抽屉)」→ 抽屉左侧列表**顶部**应有一个明显区别于项目项的「+ 新建项目」项,点击进入空白新建表单。 + +- [ ] **Step 2: 实现 — renderDrawerList 首项加 di-create 类** + +替换(656-658): +```javascript + let html = '
' + + '+新建项目
'; +``` +为: +```javascript + let html = '
' + + '新建项目
'; +``` + +- [ ] **Step 3: 实现 — openProjectDrawer 加固** + +替换(589-593): +```javascript +function openProjectDrawer(projectName) { + drawerOpen = true; + toggleProjectSwitcher(false); + drawer.classList.add('open'); + loadDrawerForm(projectName === undefined ? drawerSelected : projectName); +} +``` +为: +```javascript +function openProjectDrawer(projectName) { + drawerOpen = true; + toggleProjectSwitcher(false); + drawer.classList.add('open'); + const sel = (projectName === undefined || projectName === null) ? drawerSelected : projectName; + try { loadDrawerForm(sel); } catch (e) { console.error(e); } + renderDrawerList(); // 始终渲染左侧列表(含 +新建项目) +} +``` + +- [ ] **Step 4: 实现 — CSS 强化 di-create** + +在 `.drawer-item .di-new { color: var(--blue); }` 之后插入: +```css + .drawer-item.di-create { + border: 1px dashed var(--blue-100); background: var(--blue-50); + color: var(--blue-dark); font-weight: 700; justify-content: center; gap: 4px; + } + .drawer-item.di-create:hover { background: var(--blue-100); border-color: var(--blue); } +``` + +- [ ] **Step 5: 校验** + +Run: `node --check`(抽取