# 主应用：Task 任务页 UI/UX

## 1. 页面定义

| 项目 | 内容 |
| --- | --- |
| 页面名称 | Task 任务管理 |
| 普通任务路由 | `/tasks` |
| 定时任务子页 | `/tasks?tab=scheduled` |
| 任务详情路由 | `/tasks/[taskId]` |
| 页面实现 | `app-instance/frontend/app/(app)/tasks/page.tsx`、`app-instance/frontend/app/(app)/tasks/[taskId]/page.tsx` |
| 关键组件 | `TaskManagementTabs`、`TaskLiveHeader`、`TaskTimeline`、`TaskTimelineCard`、`TaskSideRail`、`TaskAcceptanceControls` |
| 核心任务 | 查看任务列表、进入任务详情、删除任务、管理定时任务、查看任务时间线、提交验收反馈 |
| 测试状态 | 已修复并复测通过；普通任务、定时任务、任务详情和缺省态在实测视口均无横向越界 |

## 2. 信息架构与组件层级

```text
AppShell
└── main.pt-16
    ├── /tasks
    │   ├── Page Header
    │   │   ├── h1 Tasks
    │   │   ├── 页面说明
    │   │   └── TaskManagementTabs
    │   ├── OrdinaryTasks
    │   │   ├── Loading Card
    │   │   ├── Empty Card
    │   │   ├── < xl：OrdinaryTaskCard 列表
    │   │   └── >= xl：任务表格
    │   └── ScheduledTasks
    │       ├── 辅助说明
    │       ├── 刷新 / 新建定时任务
    │       ├── AddJobForm
    │       ├── < xl：ScheduledJobCard 列表
    │       └── >= xl：定时任务表格
    └── /tasks/[taskId]
        ├── TaskLiveHeader                 sticky top: 65px，避让全局头部
        └── main grid
            ├── 主列
            │   ├── 删除任务
            │   └── TaskTimeline
            │       ├── 任务创建
            │       ├── 计划 / 工具 / Agent / 产物 / 结果卡片
            │       ├── Details JSON 展开区
            │       └── TaskAcceptanceControls
            └── TaskSideRail
                ├── 任务状态
                ├── 活跃运行
                ├── 最新提醒
                ├── Agent team
                └── 产物
```

## 3. 布局与响应式规则

### 普通任务列表

- 页面外层使用 `max-w-7xl` 和响应式内边距。
- `< xl` 视口显示任务卡片，不再显示宽表格；状态、来源、运行数、技能数、更新时间和操作全部在卡片内可见。
- `>= xl` 视口显示完整表格，适合批量扫描和横向比较。
- 加载状态显示独立 loading card，不会在接口返回前误显示“暂无普通任务”。
- 删除任务前使用浏览器确认，取消后不改变列表，确认后从列表移除。

### 定时任务子页

- `< xl` 视口显示定时任务卡片，避免将“历史、状态、操作”藏在内部横向滚动表格右侧。
- `>= xl` 视口显示表格。
- 新建表单以内联卡片展示，包含任务名称、调度类型、调度参数、任务消息、来源会话说明、取消和创建。
- 定时任务删除前需要确认，降低误删风险。
- Switch、运行、删除、历史、刷新、新建等入口均有可访问名称和 44px 触控目标。

### 任务详情

- `TaskLiveHeader` 为 sticky，固定在全局头部下方 `65px`，避免与全局 header 的边框重叠。
- 主内容在 `xl` 以下单列排列：时间线在前，侧栏在后。
- `xl` 及以上使用 `minmax(0,1fr) + 360px` 双栏：左侧时间线，右侧状态和产物。
- 主列、侧栏、卡片和 JSON 区均使用 `min-w-0`、`max-w-full` 和受控换行，防止长 run id、session id、JSON 或产物标题撑破页面。
- `Details JSON` 的 summary 命中高度为 44px，支持触控展开。

## 4. 操作与 UX 逻辑

| 操作 | 触发方式 | 状态变化与反馈 | UX 目的 | 当前结果 |
| --- | --- | --- | --- | --- |
| 切换普通/定时任务 | 点击 TaskManagementTabs | URL 在 `/tasks` 与 `/tasks?tab=scheduled` 间切换，当前 tab 高亮 | 区分用户任务和自动触发任务 | 正常 |
| 普通任务进入详情 | 点击“进入任务 / Open task” | 跳转 `/tasks/[taskId]` | 查看时间线、运行过程和验收 | 正常 |
| 删除普通任务 | 点击删除按钮后确认 | 取消不变；确认后调用 `DELETE /api/tasks/[id]` 并移除行/卡片 | 防止误删，保持列表干净 | 正常 |
| 刷新定时任务 | 点击刷新 | 重新调用定时任务列表接口 | 获取最新调度状态 | 正常 |
| 新建定时任务 | 点击新建，填写表单并创建 | 提交 `POST /api/cron/jobs`，成功后收起表单并刷新列表 | 创建自动提醒入口 | 正常 |
| 切换定时任务启用 | 点击 Switch | 调用 toggle 接口，刷新列表 | 快速暂停/恢复自动任务 | 正常 |
| 立即运行定时任务 | 点击播放按钮 | 调用 run 接口，刷新列表 | 手动触发一次计划任务 | 正常 |
| 删除定时任务 | 点击删除按钮后确认 | 取消不变；确认后调用删除接口并刷新列表 | 防止误删自动任务 | 正常 |
| 返回任务列表 | 详情页点击 Back to tasks | 返回 `/tasks` | 提供明确退出路径 | 正常 |
| 返回对话 | 详情页点击 Chat | 返回 `/` | 回到任务来源工作台 | 正常 |
| 跳到验收区 | 点击 Review | 定位到当前结果验收卡片 | 减少长时间线中的查找成本 | 正常 |
| 展开 Details JSON | 点击 summary | 展开或收起 JSON 明细 | 为调试和审计保留细节 | 正常 |
| 提交修改意见 | 填写验收说明，点击 Needs revision | 调用 `/api/chat/acceptance`，提交 `revise` 和 comment | 将验收反馈记录到当前 run | 正常 |
| 下载产物 | 点击 Download | 对内联产物生成下载 | 获取任务输出 | 正常 |
| 任务不存在 | 访问缺失 task id | 显示“任务不存在”和返回任务列表 | 明确异常恢复路径 | 正常 |

## 5. 响应式测试矩阵

测试日期：2026-06-04。浏览器：Playwright Chromium。环境：本地生产构建 `next build` + `next start` 以及实际 `terminaltest` 实例；API 使用模拟数据，所有布局和交互在真实浏览器中执行。

| 页面 | 视口 | 横向越界 | 小触控目标 | 关键结论 |
| --- | --- | --- | --- | --- |
| 普通任务 | `320×568` | 无 | 0 | 卡片信息完整，操作可见 |
| 普通任务 | `390×844` | 无 | 0 | 手机竖屏可直接进入和删除 |
| 普通任务 | `844×390` 横屏 | 无 | 0 | 横屏不需要页面横向滚动 |
| 普通任务 | `768×1024` | 无 | 0 | 平板单列卡片正常 |
| 普通任务 | `1024×768` | 无 | 0 | 窄桌面单列卡片正常 |
| 普通任务 | `1365×900` | 无 | 0 | 宽屏表格正常 |
| 定时任务 | `390×844` | 无 | 0 | 定时任务卡片完整显示历史、状态和操作 |
| 任务详情 | `320×568` | 无 | 0 | 长 session id、JSON、验收区均未撑破页面 |
| 任务详情 | `390×844` | 无 | 0 | sticky 头部避让全局头部 |
| 任务详情 | `768×1024` | 无 | 0 | 单列详情和侧栏顺序正常 |
| 任务详情 | `1365×900` | 无 | 0 | 双栏详情正常，侧栏产物可下载 |

### 关键量化证据

- 普通任务所有实测视口 `scrollWidth === clientWidth`。
- 定时任务 `390×844` 视口 `scrollWidth === clientWidth`。
- 任务详情 `320×568`、`390×844`、`768×1024`、`1365×900` 均无页面级横向越界。
- 任务详情 sticky 头部实测 `globalBottom=65`、`taskTop=65`、`overlapsGlobal=false`。
- 最终复测中所有检查视口可见小触控目标数为 `0`。
- 部署到 `terminaltest` 后，同一套 Task QA 自动化用例 `14 passed`。

## 6. 已修复问题

| 等级 | 问题 | 修复 |
| --- | --- | --- |
| P1 | 普通任务和定时任务在手机端只露出表格左侧，核心操作藏在内部横向滚动区 | `< xl` 改为卡片布局，宽屏保留表格 |
| P1 | 任务详情在 `320px` 和 `390px` 被时间线内容撑到约 `626px`，产生页面级横向越界 | 主列、卡片、侧栏加入 `min-w-0/max-w-full`，控制长文本和 JSON |
| P1 | 任务详情 sticky 头部滚动后与全局固定头部重叠 | sticky top 改为 `65px`，避让全局 header 和边框 |
| P1 | React Strict Mode 下任务详情 `mountedRef` 清理后不恢复，详情可能停留在“任务不存在/加载中” | effect 挂载时重置 `mountedRef.current = true` |
| P2 | 定时任务删除无确认 | 删除前增加确认弹窗 |
| P2 | 定时任务播放/删除图标按钮无可访问名称且目标偏小 | 补充 `aria-label/title`，扩大到 44px |
| P2 | tabs、summary、switch 等控件命中高度不足 44px | 统一提高到 44px 触控目标 |
| P2 | 普通任务首次加载可能误显示空状态 | 增加 loading 状态 |

## 7. 剩余观察项

- 本轮自动化使用模拟 API 数据验证布局和交互；真实后端数据的极端状态仍需在后续页面联测中持续观察。
- Playwright 报告中存在一次 404 控制台日志，来源为浏览器资源请求，不影响 Task 页面核心 API 与交互。
