docs(tasks): export dialog polish brief (agent loop, issue #90)
The English-unavailable note moves from a line inside the dialog to one top toast per open; selected states take the theme accent on borders, dots and boxes with neutral backgrounds. Reverses the DESIGN.md neutral selected-state sentence; BUG-1078's no-dark-block rule stays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
308ca2a65c
commit
07730e3924
@@ -513,3 +513,4 @@
|
||||
| `TASK-synastry-report-chat-fix-20261020.md` | `PROGRESS-synastry-report-chat-20261018.md` | 大运核对要认报告里的「小运」和英文 mahadasha / antardasha;预填文案只留一句 | 已验收 | `549e37b99` |
|
||||
| `TASK-other-subject-birth-time-edit-20261021.md` | — | 其他人的出生时间可以修改(去掉 `chart_profiles_guard_birth` 的填报时间不可改;推翻 people-archive P1 §验收 2 该条;active 锁不变) | 排队(等 #86 合入) | `codex/other-subject-birth-time-edit-20261021`;动表;不进循环 |
|
||||
| `TASK-chart-ascendant-slash-20261021.md` | — | #87 上升状态格「不适用」改「/」+ 悬停 / 点按说明;报告上升行同改并在表下加说明(推翻 10-15 口径) | 待领取(等 #86 合入) | `codex/chart-ascendant-slash-20261021` |
|
||||
| `TASK-report-export-dialog-polish-20261021.md` | — | #90 导出弹窗:英文不可用说明改顶部浮层(每次打开一次);选中态描边 / 圆点 / 勾选框用主题色、底色中性(推翻 DESIGN「Selected states use canvas-muted + ink」,BUG-1078 主语保留) | 待领取(可与 #89 并行) | `codex/report-export-dialog-polish-20261021` |
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# 任务书:导出弹窗——英文不可用提示改顶部浮层,选中态改用主题色(2026-10-21)
|
||||
|
||||
## 基线
|
||||
|
||||
- `origin/staging` = `bd3ce0e7b`。开工前 `git fetch origin --prune`,以届时的 `origin/staging` 为准。
|
||||
- 执行方:**Grok(Windows + Docker)**;分支 `codex/report-export-dialog-polish-20261021`,工作树 `.worktrees/report-export-dialog-polish-20261021`,**只推这个分支**。
|
||||
- 关联:issue #90;BUG-1078(导出面板选中态深红褐底)、BUG-1079(全站实心按钮配色)、BUG-1094(导出显示真实大小)、BUG-1121(结果提示只经 `notify.ts`);`TASK-report-reader-polish-and-english-20260929`、导出面板 2026-09-30 重设计。
|
||||
- 纯前端,不涉及数据库、Python、`scripts/`。
|
||||
|
||||
## 现状实证(按符号定位)
|
||||
|
||||
| # | 现象 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| 1 | 英文版不可用时,弹窗里多出一行灰字占位置 | `frontend/src/components/personal-report/report-export-drawer.tsx` 的 `ReportExportDrawer`:`hasEnglish` 为假时渲染 `<p className="report-export-caption">`,两句固定文案——`englishEdition === "unavailable"` →「这份报告的英文版没有生成成功,只能导出中文版。」;否则(`"legacy"`)→「这份报告生成于英文版上线前,重新生成即可获得中英两版。」 |
|
||||
| 2 | 英文是否可用在弹窗打开时就已知,不需要再请求 | 同组件的 `hasEnglish = englishEdition === "ready" && Boolean(editions.en?.length)`。`englishEdition` 来自 `report-actions.tsx` 的 `ReportActions` 属性,再上游是 `personal-report-page.tsx` 的 `readEnglishEdition`(接口 `englishEdition` + 前端汉字复核)。弹窗由 `ReportActions` 的 `exportOpen` 状态控制,**每次打开都重新挂载**,挂载时 `useEffect(…, [])` 调 `showModal()`。注意两个组件的 `englishEdition` 默认值都是 `"legacy"` |
|
||||
| 3 | 英文可用时语言分段下方还有一行建议「拿去问 ChatGPT、Claude 等 AI,建议选 English,术语与原典一致。」,同样是 `.report-export-caption` | issue 只点名「英文不可用」与 legacy 两句,见决策 D1 |
|
||||
| 4 | 顶部浮层 API 已有 | `frontend/src/lib/notify.ts`:`notifySuccess` / `notifyInfo` / `notifyError(message, { id?, duration? })`,info 3 秒;同 `id` 后一条替换前一条;每次调用先 `liftToastsAboveModal()`——**只有当页面上已有 `dialog:modal` 时**才把浮层提到弹窗之上。弹窗现有用法:`download()` 里 `notifySuccess("已导出")`、`notifyError(…)`。其它处用 `id` 去重的例子:`personal-report-center.tsx` 的 `{ id: "reports-load-more" }`、`email-otp-login.tsx` 的 `AUTH_NOTICE` |
|
||||
| 5 | 选中态是灰底+黑字 | `frontend/src/app/globals.css`(按选择器找):`.report-export-segment button[aria-checked="true"]`(`--color-canvas` 底 + `--color-ink` + 阴影,轨道 `.report-export-segment` 是 `--color-canvas-muted`);`.report-export-mode[aria-checked="true"]`(边 `--color-ink-secondary`、底 `--color-canvas-muted`);`.report-export-mode[aria-checked="true"] .report-export-radio`(`border: 5px solid var(--color-ink)`);`.report-export-row:is([aria-checked="true"], [aria-checked="mixed"]) .report-export-box`(边与底 `--color-ink`,勾为 `--color-canvas`) |
|
||||
| 6 | 要推翻的那句设计规范 | `frontend/DESIGN.md`「导出报告 sheet (redesigned 2026-09-30 …)」条目末尾:「Selected states use `--color-canvas-muted` + `--color-ink`, never `--color-action-soft` (BUG-1078).」同一条目里还有「otherwise one caption saying why there is no English」;`frontend/docs/VOICE.md`「导出面板(2026-09-30 重设计)」条目末尾写了两句无英文说明 |
|
||||
| 7 | 主题色 token | DESIGN.md 色表:`--color-action-strong` 是「fill rank:rings, carets, **checked radios**」,`--color-action` 是文字/图标档。值:`--color-action-strong` 浅 `#cc785c`、深 `#d78064`;`--color-action` 浅 `#a9583e`、深 `#d78064`(`globals.css` `:root`、`@media (prefers-color-scheme: dark) :root:not([data-theme="light"])`、`:root[data-theme="dark"]` 三处)。BUG-1078 的深红褐是 **`--color-action-soft` 深色 `#3a2620`**;按钮专用 `--color-action-fill` 深色 `#8f4a33` 也偏深红褐。实测对比度:`#cc785c` 对浅底 `#fbfaf7` 3.14:1、`#d78064` 对深底 `#262624` 5.17:1(非文字 3:1 线都过);`#a9583e` 对浅底 4.85:1 |
|
||||
| 8 | 页面顶栏还有一个「中文 / English」胶囊 `.report-language-switch`(不在弹窗内),选中态也是 `--color-canvas-muted` + ink(DESIGN.md「中文 / English (2026-09-29)」条) | 见决策 D3 |
|
||||
|
||||
## 根因
|
||||
|
||||
1. 导出面板 2026-09-30 重设计时,把「为什么没有英文」当成面板内容写成常驻说明行;按 DESIGN.md「提示与报错:toast」口径,这是一次性告知,应走顶部浮层,不占布局。
|
||||
2. BUG-1078 当时为了躲开深色模式下 `--color-action-soft` 的深红褐色块,把选中态全部改成中性灰 + 黑,导致选中与未选中区分弱、不带品牌色。正确做法是**只把描边、圆点、勾选框换成主题色,底色保持中性**,既不出现大块深色底,也能一眼看出选中。
|
||||
|
||||
## 决策记录(产品负责人,issue #90)
|
||||
|
||||
| # | 决定 |
|
||||
| --- | --- |
|
||||
| D0 | 打开导出弹窗时若英文版不可用(`unavailable` 与 `legacy` 两种),出**一次**顶部浮层提示(复用 `notify.ts`),删除弹窗内对应的那行说明。文案沿用原两句,不改字 |
|
||||
| D0' | 「整篇报告 / 自选章节」选中态:描边与单选圆点用主题色,底色中性;深色模式不得出现 BUG-1078 那种深红褐底。勾选框、弹窗内中英切换的选中态同样处理 |
|
||||
| D0'' | **推翻 DESIGN.md「Selected states use `--color-canvas-muted` + `--color-ink`, never `--color-action-soft` (BUG-1078).」这一句**,同一提交更新 DESIGN.md。BUG-1078 的主语「导出面板选中态不得用 `--color-action-soft` 深色块」保留(不推翻) |
|
||||
| D1 | (Claude 按 issue 字面定,产品可否决)英文**可用**时那句「拿去问 ChatGPT…建议选 English」保留在语言分段下方,不改成浮层——它是选项说明,不是事件提示。`.report-export-caption` 类保留给它用 |
|
||||
| D2 | (Claude 定)主题色用 DESIGN 色表里的 fill 档 `--color-action-strong` 画描边/圆点/勾选框底;文字若需着色用文字档 `--color-action`。**不用** `--color-action-soft`、`--color-action-fill`、任何新色值 |
|
||||
| D3 | 页面顶栏的 `.report-language-switch` 胶囊**不在本单范围**(issue 写的是弹窗内);若产品要一并改,另开 issue |
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. `./node_modules/.bin/tsc --noEmit` 0 错;`npm run lint` 0 error。
|
||||
2. 前端全量 `npm test` 失败清单与开工时 `origin/staging` 基线逐条一致(`# fail`、`# cancelled` 与退出码一起看);测试总数不低于基线。
|
||||
3. `next build` 后 `/` 仍 `○ Static`;首屏 gzip 变化 ±2% 内(导出弹窗不在首屏,预期 0 变化)。
|
||||
4. 改 UI 的同一提交更新 `frontend/DESIGN.md`(含推翻那一句)与 `frontend/docs/VOICE.md`。
|
||||
5. 浮层**每次打开弹窗只出一次**:只在挂载时的 effect 里、`showModal()` **之后**调用(否则 `liftToastsAboveModal` 找不到 `dialog:modal`,浮层落在遮罩下);切换整篇/自选、勾选、切换语言等重渲染不得再出;必须带固定 `id`(如 `"report-export-english"`),React 严格模式开发环境 effect 双跑时也只剩一条。不得在 render 里调用 notify。
|
||||
6. 不新增任何加载动画、spinner、骨架、额外请求(`report-export-drawer.test.tsx` 现有 `doesNotMatch(/InlineSpinner|navigator\.clipboard|fetch\(/)` 保持)。
|
||||
7. 选中态不得出现 `--color-action-soft` / `--color-action-fill`,不得新造色值,不得改任何主题 token 值(`tests/test_frontend_theme_contract.py`、`dark-theme-contract`、`design-token-contract` 不动)。
|
||||
8. 改既有断言必须写「原值 / 新值 / 原因」三栏;不得静默弱化。不改 `.gitea/`、不升依赖、不顺手修范围外 warning。
|
||||
9. 公开仓库:测试与文档只用虚构 / 已有 golden fixture,不写任何真实个人资料。
|
||||
|
||||
## 必须同轮更新的源码文本合同测试(AGENTS §7.8)
|
||||
|
||||
| 文件 · 用例 | 现断言 | 本单后必须改成 |
|
||||
| --- | --- | --- |
|
||||
| `frontend/tests/report-buttons-scope-20260928.test.ts`「the BUG-1078 report-only override is gone; the selected export preset stays neutral」 | 对 `.report-export-mode[aria-checked="true"]`、`.report-export-segment button[aria-checked="true"]` 断言 `doesNotMatch(/--color-action-soft\|--color-action\b/)` 且 `match(/--color-ink\|--color-canvas/)`。**注意 `--color-action\b` 会命中 `--color-action-strong`**,改完必红 | 三栏:保留「不得用 `--color-action-soft` / `--color-action-fill`」;新增「选中描边 / 圆点用 `--color-action-strong`」;底色只许中性 token(`transparent` / `--color-canvas*`)。原因:issue #90 推翻 DESIGN 那一句,BUG-1078 主语不变 |
|
||||
| `frontend/tests/report-english-edition.test.tsx`「the export drawer suggests English for AI only when it can switch」 | legacy 时断言 `h.container.text.includes("重新生成即可获得中英两版")` | 三栏:改为断言弹窗内**不含**该句、`toast.info` 被调用一次且文案为该句;保留「没有 English 选项」与「建议选 English」两条断言 |
|
||||
| `frontend/tests/report-export-drawer.test.tsx`「drawer contract uses native dialog …」 | 只读 CSS 片段与源码 | 不需改既有断言;新增用例写在本文件(见 T1、T2) |
|
||||
|
||||
改前再按 §7.8 grep 一次:`grep -rn "report-export-\|英文版没有生成成功\|英文版上线前\|canvas-muted\` + \`--color-ink" frontend/tests tests`,以实际命中为准补进上表。
|
||||
|
||||
## 任务分解
|
||||
|
||||
| # | 内容 | 验收标准 |
|
||||
| --- | --- | --- |
|
||||
| T1 | `report-export-drawer.tsx`:删掉 `hasEnglish` 为假时的 `<p className="report-export-caption">` 分支;在挂载 effect 中 `showModal()` 之后,若英文不可用则 `notifyInfo(<原两句之一>, { id: "report-export-english" })`。判断条件与原分支完全一致(`!hasEnglish`;`englishEdition === "unavailable"` 用第一句,其余用 legacy 句)。英文可用时的 ChatGPT 建议句不动(D1) | 新增单测(`report-export-drawer.test.tsx`,桩 `toast.info`):① `legacy` 打开 → info 恰好 1 次、文案为 legacy 句、带 `id`;② `unavailable` 打开 → 1 次、文案为失败句;③ `ready` 打开 → 0 次;④ 打开后切「自选章节」、勾选 / 取消、展开分组 → 次数不变;⑤ 关闭(`render(null)`)再打开 → 再出 1 次;⑥ 弹窗 DOM 里不再有这两句。`report-english-edition.test.tsx` 按上表三栏改 |
|
||||
| T2 | `globals.css` 选中态(只改 `.report-export-*` 下列选择器,其余不动):`.report-export-mode[aria-checked="true"]` → `border-color: var(--color-action-strong)`,底色保持中性(`transparent`,与未选一致);`.report-export-mode[aria-checked="true"] .report-export-radio` → `border: 5px solid var(--color-action-strong)`;`.report-export-row:is([aria-checked="true"], [aria-checked="mixed"]) .report-export-box` → 边与底 `--color-action-strong`,勾 / 横线保持 `--color-canvas`;`.report-export-segment button[aria-checked="true"]` → 保留 `--color-canvas` 底与阴影,文字改 `--color-action`、加 `box-shadow` 内描边 1px `--color-action-strong`(或等价写法),字重 600 不变 | 按上表改 `report-buttons-scope-20260928.test.ts`;新增断言:四条选中规则都不含 `--color-action-soft` / `--color-action-fill`、背景值只在 `transparent` / `--color-canvas*` / `--color-action-strong`(仅勾选框 18px 小方块)之内;三处主题块 `--color-action-strong` 值仍为 `#cc785c` / `#d78064` / `#d78064` |
|
||||
| T3 | `frontend/DESIGN.md`「导出报告 sheet」条:删除「Selected states use `--color-canvas-muted` + `--color-ink`, never `--color-action-soft` (BUG-1078).」,换成「Selected states (issue #90, 2026-10-21, overrides the 2026-09-30 neutral rule): the scope card's border and radio dot, checked / mixed boxes, and the selected language segment use `--color-action-strong` (text `--color-action`); backgrounds stay neutral; never `--color-action-soft` or `--color-action-fill` (BUG-1078: no dark red-brown block in dark mode).」;「otherwise one caption saying why there is no English」改为「otherwise no caption: opening the sheet raises one info toast (id `report-export-english`) saying why」。`frontend/docs/VOICE.md` 导出面板条末句改为「没有英文版时弹窗内不写字,打开时顶部浮层提示一次:……(两句原文)」 | 文档 diff 与实现一致;同一提交 |
|
||||
| T4 | 记录:`docs/BUG_HISTORY.md` 新编号一条(现象:英文不可用说明占弹窗布局、选中态不带主题色;关联 BUG-1078 / 1079 / 1121;写明推翻 DESIGN 那一句、BUG-1078 主语保留);`CHANGELOG.md` 一行;`docs/tasks/PROGRESS-report-export-dialog-polish-20261021.md`(三栏、测试数字、Grok 自跑结果);`docs/tasks/README.md` 状态板改「待验收」;真机清单 `docs/testing/report-export-dialog-20261021.md`(Claude 已写好,执行方按实际偏差修订) | 文档齐;隐私守卫 `.venv/bin/python -m pytest tests/test_repo_privacy_markers.py -q` 通过 |
|
||||
|
||||
### 验收分工(按 `TASK-agent-loop-pilot-20261013.md`「T1 结果与定稿分工」)
|
||||
|
||||
| 检查 | Grok 自跑 | Claude 验收 |
|
||||
| --- | --- | --- |
|
||||
| `tsc --noEmit`、`npm run lint` | 必跑 | 复验 |
|
||||
| `report-export-drawer.test.tsx`、`report-english-edition.test.tsx`、`report-buttons-scope-20260928.test.ts`、`class-name-definition-contract.test.ts`、`dark-theme-contract.test.ts`、`design-token-contract.test.ts` | 必跑 | 复验 |
|
||||
| 前端全量 `npm test`(与基线逐条比对) | 不跑 | **以 Claude 为准** |
|
||||
| `npm run build`:`/` Static、首屏 gzip ±2% | 不跑 | **以 Claude 为准** |
|
||||
| `test:db` | 不需要(不动数据库访问层) | — |
|
||||
| 浅色 / 深色 / 手机宽度真机 | 不做 | 环境缺口,交产品按清单走 |
|
||||
|
||||
## 与 #89 的并行关系
|
||||
|
||||
#89(英文版漏译)预计改 `scripts/professional_report_reference.py`、`scripts/pl9_reader_english_terms.py`、`scripts/yoga_engine.py`、`tests/test_report_english_edition.py`,可能改 `frontend/src/lib/personal-report-english-edition.ts`(`acceptEnglishEdition`)。**业务代码无重叠,可并行**。可能撞车的只有:
|
||||
|
||||
- `frontend/tests/report-english-edition.test.tsx`:#89 若在此加 `acceptEnglishEdition` 用例会与本单 T1 改同一文件(不同用例,通常可自动合并)。本单只改上表那一个用例,新用例一律写进 `report-export-drawer.test.tsx`。
|
||||
- `docs/BUG_HISTORY.md`、`CHANGELOG.md`、`docs/tasks/README.md`:都是追加,后合入的一方 rebase 时手工合并,**BUG 编号以合入时最大号 +1 重新核对**。
|
||||
|
||||
## 让步顺序
|
||||
|
||||
时间不够时:T1(浮层 + 删说明行)> T2(选中态)> T3(文档,但 T2 落地则 T3 必须同提交)> T4。T1 与 T2 可分两个提交,但 T2 与 T3 不得拆开。
|
||||
|
||||
## 开工前置命令
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git worktree add -b codex/report-export-dialog-polish-20261021 .worktrees/report-export-dialog-polish-20261021 origin/staging
|
||||
cd .worktrees/report-export-dialog-polish-20261021
|
||||
git status -sb
|
||||
grep -n "report-export-caption\|notifyInfo\|showModal" frontend/src/components/personal-report/report-export-drawer.tsx
|
||||
grep -n 'report-export-\(mode\|radio\|box\|segment\)' frontend/src/app/globals.css
|
||||
grep -n "Selected states use" frontend/DESIGN.md
|
||||
grep -rn "report-export-\|英文版没有生成成功\|英文版上线前" frontend/tests tests
|
||||
grep -n "^## BUG-1[0-9][0-9][0-9]" docs/BUG_HISTORY.md | sort -t- -k2 -n | tail -3
|
||||
```
|
||||
|
||||
基线测试:开工时在 `origin/staging` 上先跑一次上表单文件测试,记数字进 PROGRESS。
|
||||
|
||||
## BUG 编号
|
||||
|
||||
当前最大 **BUG-1403**;**BUG-1404 起预留给 #85**。本单开工时核对 `docs/BUG_HISTORY.md` 最大号与 #85 / #89 已占用号,取当时最大号 +1,在 PROGRESS 写明。
|
||||
|
||||
> 备注(不在本单范围):`docs/BUG_HISTORY.md` 当前整份内容重复了一遍(`# Bug History` 出现在第 1 行和约第 18099 行,`## BUG-` 标题 2337 个、去重后 1199 个)。本单新增记录只追加在文件末尾,不要处理重复;已报给 Claude 另行处理。
|
||||
|
||||
Reference in New Issue
Block a user