Files
Kanban/README.md
T
chenshoulin 442cbbd734 style: 重做界面视觉与信息层级
先截图审视现状,再针对性修改。主要问题与改动如下。

工具栏
- 标签筛选从「平铺全部标签」改为下拉面板,标签多时不再换行挤爆工具栏
- 备份与快捷键帮助移到导航栏 —— 它们是应用级操作,不该挤在看板工具栏里,
  顺带修好了「? 帮助只在看板可用」的问题
- 到期统计(今日到期 / 逾期)合并为可点击的筛选入口,去掉两个独立控件
- 移动端工具栏从占半屏降到三行紧凑布局

卡片
- 优先级从彩色胶囊改为左侧色条,扫视一列时比读文字更快分辨轻重
- 元信息改为「优先级 · 日期 · 标签」的轻量文本行,不再三种胶囊叠在一起
- 完成态用勾选图标 + 降低不透明度

布局
- 今日视图限宽居中(max-w-3xl):此前 1440px 下卡片被拉满整屏,
  标题与元信息之间出现大片空白
- 修复移动端卡片被压成细条:TaskCard 的 overflow-hidden(用于裁切左侧色条)
  会让 flex 项的最小尺寸解析为 0,补 shrink-0 修正;
  同时改为移动端按内容高度堆叠、桌面端列内滚动

其他
- 导航栏品牌改用看板图标,消除「看板」重复出现两次
- 统一卡片阴影、圆角与键盘焦点样式
- 新增 scripts/screenshot.mjs,便于后续对照审视视觉改动

验证:单元测试 452 个、端到端测试 23 个全部通过,lint 与构建无错误。
2026-10-18 14:05:06 +08:00

207 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 看板 · 个人任务管理
一个轻量的个人看板工具:打开即用、数据存在本地、不依赖后端。
- 固定三列:**待办 / 进行中 / 已完成**
- 快速新增、拖拽排序、详情编辑、删除撤销
- 搜索与筛选(关键词 / 优先级 / 标签 / 今日到期 / 逾期)
- **今日视图**:按紧急度汇总今天要做的事,含本周完成等统计
- 键盘快捷键
- 导出导入 JSON + 启动自动备份
- **可安装为 PWA,支持离线使用**
---
## 快速开始
```bash
npm install
npm run dev
```
打开终端提示的地址即可。首次进入是空看板,在任意列顶部的输入框里输入标题、回车即可创建任务。
## 脚本
| 命令 | 说明 |
|---|---|
| `npm run dev` | 启动开发服务器 |
| `npm run build` | 类型检查 + 生产构建,产物在 `dist/` |
| `npm run preview` | 本地预览生产构建 |
| `npm run typecheck` | 只做类型检查 |
| `npm run test` | 单元测试(Vitest) |
| `npm run test:coverage` | 单元测试 + 覆盖率报告 |
| `npm run test:e2e` | 端到端测试(Playwright,默认驱动系统已安装的 Chrome) |
| `node scripts/screenshot.mjs` | 生成界面截图(需先起 dev server),产物在 `.screenshots/` |
| `npm run lint` / `npm run format` | 代码检查与格式化 |
## 快捷键
| 按键 | 作用 |
|---|---|
| `N` | 聚焦「待办」列的快速新增输入框 |
| `/` | 聚焦搜索框 |
| `?` | 打开快捷键帮助 |
| `Esc` | 关闭当前面板 |
在输入框内输入时不会触发快捷键。
---
## 两个视图
顶部导航可在两个视图之间切换:
| 视图 | 路径 | 组织方式 |
|---|---|---|
| 看板 | `/` | 按**状态**:待办 / 进行中 / 已完成 |
| 今日 | `/today` | 按**紧急度**:已逾期 → 今天到期 → 进行中 |
今日视图顶部有四张统计卡片(今日待办 / 逾期 / 今天到期 / 本周完成),下方是可直接勾选完成的待办列表。
分组是**互斥**的:一张卡片只会出现在一组里,归属优先级为「逾期 > 今天到期 > 进行中」,所以你能一眼数清今天到底有几件事。已完成和已归档的任务不会出现在今日视图。
---
## 安装与离线(PWA)
应用可以像原生应用一样安装到桌面或手机主屏,安装后支持**完全离线**使用 —— Service Worker 会预缓存页面与静态资源,断网后照常打开,数据本来就在本地。
- 桌面 Chrome / Edge:地址栏右侧会出现安装图标
- 手机:浏览器菜单 →「添加到主屏幕」
- 安装后长按图标有「今日」快捷方式,直达 `/today`
更新策略是 **prompt**:检测到新版本时会在底部弹出提示,由你决定何时刷新,不会打断正在进行的编辑。
图标由 `scripts/generate-icons.py`(Pillow)生成,需要改图标时运行:
```bash
python scripts/generate-icons.py
```
---
## 数据与备份(重要)
**数据只保存在你这台设备的浏览器里**(localStorage,键名 `kanban.tasks`)。没有服务端,也不会自动同步到其它设备。
这意味着以下操作会导致数据丢失:
- 清理浏览器数据 / 缓存
- 使用隐私模式
- 换浏览器或换设备
- Safari 的 7 天未访问存储清理策略
因此工具内置了两道保护:
1. **启动自动备份**:每次打开看板时留一份快照,最多保留最近 3 份,可在「备份」面板中一键恢复。
2. **手动导出**:「备份」面板 → 导出为 JSON,文件名形如 `kanban-2026-10-18.json`。
导入是**覆盖式**的:选中文件后会先校验,再显示将被覆盖的任务数量,需要二次确认才会执行。文件不合法时不会改动任何现有数据。
> 如果需要在多设备间同步,需要自行接入后端;`TaskRepository` 接口就是为此预留的扩展点(见下)。
---
## 部署
产物是纯静态文件,把 `dist/` 目录交给任意静态托管即可(Nginx、Vercel、Netlify、GitHub Pages 等)。
```bash
npm run build
# 将 dist/ 上传或指向静态服务器
```
Nginx 示例:
```nginx
server {
listen 80;
root /var/www/kanban/dist;
index index.html;
location / {
# 必须配置:/today 是真实路径,刷新时文件不存在,需要回落到 index.html
try_files $uri $uri/ /index.html;
}
}
```
Netlify / Vercel 等平台,在 `dist/` 同级放一个 `_redirects` 或配置即可:
```
/* /index.html 200
```
> **注意**:应用使用前端路由(`/today`),因此**必须**配置 SPA 回落,否则直接访问或刷新 `/today` 会 404。
> 这不是可选项。若你的托管环境无法配置回落,可以改用 hash 路由(把 `src/router/index.ts` 里的
> `createWebHistory()` 换成 `createWebHashHistory()`),代价是 URL 变成 `/#/today`。
Service Worker 的 `navigateFallback` 已设为 `index.html`,因此**离线状态下**深链 `/today` 也能正常打开,
无需服务器参与。
---
## 技术栈
Vue 3 · TypeScript · Vite · Pinia · Vue Router · Tailwind CSS v4 · vue-draggable-plus (SortableJS) · dayjs · vite-plugin-pwa (Workbox) · Vitest · Playwright
## 目录结构
```
src/
├── components/ # 看板列、卡片、抽屉、工具栏、导航、PWA 提示等 UI 组件
├── composables/ # 可复用的组合式逻辑(键盘快捷键)
├── data/ # 持久化:schema 与迁移、仓库实现、快照
├── router/ # 路由定义(看板 / 今日)
├── stores/ # Pinia:任务、筛选、提示
├── types/ # 领域类型与常量
├── utils/ # 纯函数:排序、筛选、日期、归档、拖拽解析、今日分组、统计
└── views/ # 页面级组件(BoardView / TodayView)
docs/
├── adr.md # 架构决策记录
├── tasks.md # 开发任务卡(含验收标准)
└── tasks.json # 可导入看板的种子数据
e2e/ # Playwright 端到端测试
scripts/ # 图标生成等辅助脚本
```
## 架构要点
- **单一数据源**:Pinia store 是内存态的唯一来源,所有变更经由 `TaskRepository` 落盘;拖拽也只消费事件,不接管数据。看板与今日视图共享同一份数据。
- **持久化端口**:`TaskRepository` 采用「整份快照读写」(`load` / `save`),而非细粒度 CRUD。要换成 IndexedDB 或后端 API,只需实现同一接口。
- **显式迁移**:落盘结构带 `schemaVersion`,升级规则登记在 `MIGRATIONS` 表中。当前版本为 2(v1 → v2 为归档功能补 `archivedAt`)。
- **损坏数据先备份再报错**:读取失败时把原始内容另存到 `kanban.tasks.corrupt.<时间戳>`,不覆盖用户数据。
- **视图与数据解耦**:今日视图只做「分组 + 排序」,全部逻辑在 `src/utils/today.ts` 与 `stats.ts` 的纯函数里,组件不持有业务规则。
更多取舍与理由见 [docs/adr.md](docs/adr.md)。
## 测试
- 单元测试:437 个用例,覆盖 `src/` 下的纯逻辑与组件行为,行覆盖率约 97%。
- 端到端测试:23 个用例,分两组运行 —— 交互类跑 dev server,PWA 类跑生产构建(Service Worker 只在构建产物中生成)。覆盖「新增 → 拖拽 → 完成 → 刷新保持」「导出 → 清空 → 导入还原」「删除撤销」「搜索筛选」「键盘快捷键」「今日视图」「离线打开」等主链路,每个用例使用独立的浏览器上下文。
```bash
npm run test:coverage
npm run test:e2e
```
### 关于 E2E 使用的浏览器
默认驱动**系统已安装的 Chrome**(`channel: 'chrome'`),不下载 Playwright 自带的 Chromium —— 后者约 197MB,在网络受限的环境下容易超时失败。
如需改用其它通道:
```bash
PLAYWRIGHT_CHANNEL=msedge npm run test:e2e # 用系统 Edge
PLAYWRIGHT_CHANNEL=chromium npm run test:e2e # 用自带 Chromium(需先 npx playwright install chromium)
```
## 已知限制
- 单用户、单设备,无协作与同步能力(离线可用,但多设备之间不会同步)。
- 标签是字符串数组,重命名标签需要逐个任务修改。
- 看板列固定为三列,不支持自定义。
- 归档阈值固定为「已完成超过 7 天」,暂不可配置。
- 今日视图的分组规则固定(逾期 > 今天到期 > 进行中),不可自定义。
- 统计只覆盖本周完成数等基础指标,没有趋势图或历史留存。