Skip to content

fix(app-showcase): record-action success toasts name the record - #26604

Merged
objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/issue-26459-showcase-action-toasts
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 6 commits into
mainfrom
claude/issue-26459-showcase-action-toasts

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #26459

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:showcase 的五个记录级动作(Mark Done、Recalculate Estimate、Recalculate Selection、Archive、Submit for Sign-off)的成功提示现在点名被改的记录,例如 "PII access review marked done.",发票用发票号 "INV-1002 submitted for finance + legal sign-off."。只改了 examples/app-showcase/src/ui/actions/index.ts 里的 successMessage 文案,外加一个钉住提示原文的测试和一个 changeset。
  • 为什么改:用户连续标记多条任务完成时,每次都只看到 "Task marked done.",分不清改的是哪一条;裁决 C(qa(checklist): ux-conventions — 5 ledger edits from the 18.2.0 release sweep (#25807) #25849)要求记录级写操作点名记录(标题)或数量。
  • 风险与回滚:风险低,只动示例应用的文案。若某个列表行没带出 title 列,文案自动退回原来的对象措辞(如 "Task marked done."),不会出现空引号或原样的占位符。回滚即还原这一个提交。
  • 先看:examples/app-showcase/src/ui/actions/index.ts 的五处 successMessage,以及新测试 examples/app-showcase/test/record-action-success-names-record.test.ts。
  • 两分钟验证:pnpm --filter @objectstack/example-showcase exec vitest run test/record-action-success-names-record.test.ts,10 条全绿;或启动 showcase,打开一条 done 为 false 的任务,点 Mark Done,提示应为该任务标题加 "marked done."。
  • 需要你做的:无须操作即可合入。可选:中文语言包里这几条 successMessage 仍是不带记录名的旧译文(本单按认领禁改语言包),是否另开卡由你定。

What

The showcase's record-level actions now name the record they changed in their success toast:

Action Before After (record carries its title) After (no title bound)
Mark Done Task marked done. PII access review marked done. Task marked done.
Recalculate Estimate Estimate recalculated. Estimate recalculated for PII access review. Estimate recalculated for the task.
Recalculate Selection Estimates recalculated for the whole selection. Estimates recalculated for PII access review. Estimates recalculated for the whole selection.
Archive Task archived (demo — no data changed). PII access review archived (demo — no data changed). Task archived (demo — no data changed).
Submit for Sign-off Invoice submitted for finance + legal sign-off. INV-1002 submitted for finance + legal sign-off. Invoice submitted for finance + legal sign-off.

Why

Ruling C on #25849: a record-level write names the record (its title) or the count. The console renders an authored successMessage verbatim, so the fix is the showcase's own copy, not the runner.

How the hole binds (read from the runner, not changed)

ActionRunner.composeSuccessMessage (objectui core) shows a successMessage as written unless it carries a template hole; then fillTemplateHoles fills it through @objectstack/formula's templateEngine over exactly two roots: result (the handler's payload) and record (the dispatch's record: the clicked row's _rowRecord, else the page's record). So the record.title hole names a task and the record.name hole names an invoice (its "Invoice Number" field).

An unbound path prints EMPTY. A list row whose view does not project title would therefore have read as a sentence with a hole-shaped gap, so every message pipes the hole through the engine's default formatter, and falls back to the object wording the toast used before. No sentence can render a raw hole or an empty quoted name.

The count is not reachable from this copy: the copy's holes bind record and result, never the selection (ctx.selection is a target-interpolation scope only). It is also not needed. On the selection bar the aggregate dispatch runs with the success toast off (ObjectGrid.runBulkActionAggregate passes showOnSuccess: false), and the bulk dialog reports its own count ("Succeeded N / M"). The only placement where Recalculate Selection's toast shows is its declared record_more entry, a single-record dispatch, so it names that record and keeps "the whole selection" as the fallback.

Tests

All at head 6399091d (after merging origin/main, closure rebuilt under the verify lock):

  • Red first, at f9e79460 (pin only, copy unchanged): vitest run test/record-action-success-names-record.test.ts, 6 failed / 4 passed (10). The 4 that passed are the fallback cases, which equal today's wording by design. Example: Expected: "PII access review marked done." Received: "Task marked done.".
  • Green: the same file, 10/10 passed.
  • pnpm --filter @objectstack/example-showcase test: Test Files 40 passed (40), Tests 494 passed (494).
  • pnpm --filter @objectstack/example-showcase typecheck: exit 0.
  • pnpm --filter @objectstack/example-showcase validate (objectstack validate, which judges action copy templates): Validation passed.

Gates

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 6399091d: 50 derived; 49 ran with exit 0. pnpm check:dual-build-cjs-loads exited 3, PREREQUISITE NOT MET (it needs every package's dist/, and this card builds only the showcase closure), so it is NOT MEASURED locally and is left to CI's build. --ran reconciliation: 50 accounted, 49 run, 1 NOT-MEASURED. node scripts/check-sdui-manifest.mjs: exit 0.

Acceptance notes

  • The zh-CN pack in examples/app-showcase/src/system/translations/index.ts still carries the old record-less wording for these actions (e.g. 任务已标记为完成。). Locale packs are outside this card's claimed file surface, so a zh-CN viewer still sees no record name.
  • docs/qa/platform-checklist/areas/ux-conventions.json quotes the old Mark Done string in its variant text. It is the QA ledger's evidence prose, left to the QA seat.
  • GenerateInvoicePdfAction ("The PDF is attached to the invoice.") is also record-level copy, but the card does not name it, so it is unchanged.

Generated by Claude Code

Mark Done, Recalculate Estimate, Recalculate Selection, Archive and Submit
for Sign-off now name the task title (or invoice number) through a template
hole over the dispatched record, falling back to the object wording through
the default formatter when the dispatch carries no title.

Claude-Session: https://claude.ai/code/session_01SMps7wq7rBTk53e8KTSEup
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 27, 2026
The zh-CN bundle entries for Mark Done, Recalculate Estimate, Recalculate
Selection and Archive replace the source copy for a zh-CN viewer, so they
carry the same record.title hole with a default fallback to the old wording.

Claude-Session: https://claude.ai/code/session_01SMps7wq7rBTk53e8KTSEup
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:showcase 五个记录级动作的成功提示现在点名被改的记录,英文如 "PII access review marked done."、发票 "INV-1002 submitted for finance + legal sign-off.";示例应用自带的中文语言包里四条译文同样点名,如「个人信息访问审查已标记为完成。」。只改 examples/app-showcase 的动作文案、该示例的中文语言包、一个钉住提示原文的测试和一个 changeset。
为什么改:连续标记多条任务完成时只看到 "Task marked done." 或「任务已标记为完成。」,分不清改的是哪一条;裁决 C(#25849)要求记录级写操作点名记录或数量,中英文用户都应如此(#26459)。
风险与回滚:只动示例应用的文案;行里没带出标题列时,中英文都退回原来的对象措辞,不会出现空白或原样的占位符。回滚 = revert 本 PR。
先看:examples/app-showcase/src/ui/actions/index.ts 的五处 successMessage → examples/app-showcase/src/system/translations/index.ts 中 zh-CN 的四条 → 测试 examples/app-showcase/test/record-action-success-names-record.test.ts。
两分钟验证:pnpm --filter @objectstack/example-showcase exec vitest run test/record-action-success-names-record.test.ts,预期 18 个用例全过。
需要你做的:无,席位落地。
席位意见:ACCEPT(补一轮后)。首轮只改了英文,席位要求补上示例应用自带的中文译文(认领里禁改的「语言包」指 ui/packages/i18n,不含示例自己的翻译包);PR 正文验收备注里「中文译文未改」已过时,以本记录为准。英文标题接中文无空格(如「PII access review已标记为完成。」)是为了让无标题时的退回文案与原文逐字相同,接受。

席位核对

seat 2 · 2026-10-27T10:29Z · head bb657a00 (#26459)

item reading
form 4 files, +163/−9: five successMessage strings in ui/actions/index.ts use the record.title hole (record.name, the invoice number, for invoices) with the default formatter falling back to the old object wording; four zh-CN entries in the showcase's own bundle do the same (Submit for Sign-off has no zh-CN entry); 18-cell pin (en + zh, named + fallback); root .changeset/ patch on @objectstack/example-showcase (private, not in the changesets ignore list)
premise measured ActionRunner.composeSuccessMessage fills holes over two roots, result and record (the clicked row, else the page's record); useActionTextLocalizer swaps in the bundle entry before the run, and i18next passes the hole through untouched (existing pin useActionTextLocalizer.templateEnvelope-13367); the selection bar runs the bulk action with its toast off, so the selection-wide message only shows from one record's overflow menu
gates (check-runs on bb657a00) 28 success, 11 skipped, 0 failing (examples-only diff: the ui jobs are path-skipped). Local: round 1 red 6/10, round 2 red 5/18, green 18/18; showcase suite 40 files / 502 tests; typecheck exit 0; objectstack validate passed; check-sdui-manifest exit 0; 49 of 50 derived gates exit 0, check:dual-build-cjs-loads exit 3 (needs every package's dist), left to CI
accepted deviations the PR body's acceptance note on zh-CN is stale (corrected here; the body is not edited after pr_create); PR body puts Fixes #26459 before the declaration lines
out of scope GenerateInvoicePdfAction copy ("The PDF is attached to the invoice.") and the QA checklist variant text quoting "Task marked done." (docs/qa/platform-checklist/areas/ux-conventions.json, the QA seat's)
landing not governed (check-governed-merges: 172 changed lines, no hit paths); git merge-tree against origin/main c8ed4c9 clean; no other open PR on these files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants