feat(workspace): unify projects and conversations in one menu

Replace separate project and activity navigation with a fixed-height two-line button and a shared workspace menu. Browse local, remote and channel projects, preview sessions on hover, restore the last opened conversation, and show ten recent conversations alongside active work.

Preserve project settings, recovery actions, draft leave guards and completion reminders. Reuse conversation summaries and windowed lists without hover fetches or polling.

Validation: focused component and App tests, real Electron layout and interaction checks, typecheck and lint passed. The earlier full suite timed out and reported Supervisor settings/layout failures.

Release note: 左上角统一项目与活动入口,支持分类查找、悬停预览和最近 10 个会话;双行按钮整体点击,保留项目设置与跨项目会话切换。
This commit is contained in:
mesalogo
2026-10-04 09:53:11 +08:00
parent ae4c6d2423
commit e89db96b85
28 changed files with 2173 additions and 511 deletions
@@ -19,8 +19,8 @@
```text
品牌
项目选择
项目活动汇总(仅有活动时显示)
项目名称(固定双行控件的第一行)
全局活动汇总/暂无活动(第二行)
[新对话] [搜索图标]
当前对话
@@ -307,27 +307,20 @@ OCR 忙碌或模型不可用时禁用加载与释放,并在执行模块再次
对应 [FR-14](./prd.md#fr-14-项目活动汇总),状态与计数遵守
[活动逻辑](./logic-design.md#9-项目活动汇总)。
- 全局汇总按钮仅在有活动行时显示在项目选择器下方,紧凑显示待处理、运行中与已完成数量,无活动行时整行隐藏,
右侧显示展开箭头,与下方新建会话保留 `8px` 间距。可访问名称明确数量属于“全项目活动”。
- 项目菜单在项目行显示同口径数量,保留“本地项目 / 远程项目 / 远程通道”分组和 SSH Host
层级,不因活动状态重排项目。数量为零时不显示标记,连接状态仍独立显示。
项目名独占一行,状态数量排列在名称下方,避免窄侧栏中数量挤占名称宽度。
- 点击汇总在按钮下方打开项目菜单,只列有活动会话的项目,每项显示项目名和同口径计数。
桌面鼠标悬停或点击项目展开右侧会话菜单,右侧空间不足且左侧可容纳时向左展开。两个面板
相接,各自拥有边框、圆角与阴影;会话层对齐所选项目行,底部空间不足时仅上移会话层,
不改变项目层的位置或高度。指针离开项目行进入会话层时不收起。展开项目不切换当前会话。
- 会话层顶部显示项目名,每行显示完整可换行的会话标题与明确状态文字,待处理会话排在
运行中会话之前,已完成未查看会话排在最后并显示“已完成”。项目行保留子菜单箭头,会话行不显示箭头。不展开 Task、Job 或 Run 列表。
- 点击会话先关闭菜单并恢复入口焦点,再请求进入该条会话;允许离开当前页面后,
选择所属项目、清除搜索和该会话未读标记、清除任务选择与会话操作菜单,窄窗口同时关闭侧栏。
设置页沿用未保存修改的离开检查,取消离开时保留原页面和完成通知。完成通知在目标聊天
实际可见后清除,从普通侧栏进入也相同;设置覆盖下的聊天或隐藏文档不触发清除。
- 菜单挂载到 body,使用 `menu`、`menuitem`、`aria-haspopup`、`aria-expanded` 与控制关系,
不隔离背景、不增加遮罩。原生浏览器相交遮挡沿用共享机制。
- 打开后焦点进入首个项目;上下方向键循环选择当前层项目或会话,Home、End 到首尾,
Enter、Space 激活,右方向键进入会话层。左方向键或 Escape 返回项目层并恢复对应项目
焦点;顶层 Escape 关闭并恢复汇总焦点,不继续关闭窄侧栏。Tab 关闭菜单后继续正常焦点
顺序;点击外部、焦点离开、再次点击入口或隐藏侧栏也关闭菜单。
- 单面板宽度为 `264px`,窗口小于 `620px` 或项目菜单两侧均无法容纳子菜单时,就地进入会话层并显示“返回项目列表”,
触控无需悬停。浮层距窗口边缘至少 `16px`,每层最大高度为 `480px`,短窗口进一步限制
高度并独立滚动。成功完成但尚未查看的会话继续保留;所有活动行移除后,关闭已打开菜单并隐藏摘要。
左上角是固定高 `60px` 的单个按钮,第一行显示项目名称,第二行显示全局待处理、运行中、已完成数量,无活动时显示“暂无活动”。点击任一行都打开锚定整个按钮的工作空间菜单,默认预览当前项目;菜单内点击“全部项目”切换至全局范围。按钮只有一个键盘焦点、焦点环及展开状态,`aria-controls` 关联菜单,`aria-describedby` 关联活动描述和控件下方的远程恢复反馈。活动变化不改变按钮高度,也不关闭已打开的菜单;长内容单行截断。
左栏固定搜索、分类及底部“新建项目”,项目列表独立滚动。分类使用共享 `PageTabs` 的 `segmented` 变体,依次为“全部项目、本地、远程、消息通道”,保留 `tablist`/`tab`/`tabpanel`、游标焦点及方向键语义;远程能力关闭时隐藏远程分类。搜索跨分类匹配,SSH Host 分组可折叠,连接状态独立于会话数量。
左栏使用 `--surface-subtle`,与右栏之间以 `1px` 的 `--border-control` 竖线分隔。搜索框使用 `border-box`,宽度包含边框和内边距,并扣除左右外边距,避免越过分隔线。全部项目及搜索结果按实际存在的本地、远程、消息通道显示分组标题,组间用横线和留白区分;远程组内保留 Host 标题。
项目行显示名称、活动数量、目录三行,无活动时省略数量行,高度随内容增长;恢复状态继续显示在目录下方。当前项目以勾选和 `aria-checked` 标识,预览使用单独背景。设置按钮独立,桌面悬停或聚焦显示,窄窗口及粗指针设备可直接访问;打开既有真实项目设置,保留目录选择、Runtime、模式、删除及远程恢复等适用操作,不触发项目切换。悬停或聚焦项目只预览右栏,点击项目直接进入;通道无会话时保留空态。
右栏顶部用共享 `SegmentedControl` 显示“全部、待处理、运行中、已完成”,采用辅助字号和紧凑内边距,与靠右的“新建会话”同排。新建使用预览项目,全部项目范围使用当前项目;消息通道禁用并显示自动创建说明。默认会话列表按待处理、运行中、最近会话分组,最近最多 10 条,完成未查看在行内标注;“已完成”筛选不受此上限限制。会话标题单行截断,全部项目范围补充项目名,不展开 Task、Job 或 Run。无活动仍显示最近会话,无匹配会话时显示空态。
点击会话关闭菜单并请求确切 ID 导航;通过既有未保存离开检查后,选择所属项目、清除侧栏搜索、未读标记、任务选择和会话菜单,窄窗口关闭侧栏。取消离开保留原页面和完成通知。完成通知仅在目标聊天实际可见后清除,预览、设置覆盖或隐藏文档不触发清除。
菜单使用共享 `FloatingPortal`,外层为非模态 `dialog`,入口提供 `aria-haspopup="dialog"`、展开状态及控制关系,不增加遮罩或背景隔离。项目列表使用 `menu`/`menuitemradio`,独立操作使用 `menuitem`;会话列表使用 `list`/`listitem` 和按钮。原生浏览器相交遮挡沿用共享机制。
打开后聚焦选中分类。列表内上下方向键循环移动,Home、End 到首尾;右方向键进入会话列表,左方向键返回预览项目,项目不可见时回到选中分类。Enter、Space 激活按钮;Tab 在控件间正常移动,焦点离开后关闭。Escape 关闭整个菜单并恢复仍可用的触发入口焦点,触发入口已卸载时回到项目入口,不继续关闭窄侧栏。点击外部、再次点击入口或隐藏侧栏也关闭。
菜单最大宽度 `920px`,高度 `640px` 且受视口限制,距窗口边缘至少 `16px`,锚点下方间隔 `8px`。桌面左栏为 `240px` 至 `360px`,窄窗口仍保留双栏并各自滚动,不使用旧级联返回页。状态筛选可横向滚动,新建按钮保持可见。项目和会话列表均采用共享窗口化渲染,键盘可到达完整列表首尾。