Skip to content

Action confirm dialog ignores the bundle's translated confirmText — label from the SAME entry is applied, confirmText is not #4265

Description

@yinlianghui

Symptom (zh-CN console, HotCRM main 333259a4, @objectstack/console 17.0.0-rc.5)

HotCRM's zh-CN bundle translates the convert_lead action completely:

convert_lead: {
  label: '转化线索',              // ← applied: the button renders 转化线索
  confirmText: '确认要转化此线索吗?', // ← IGNORED
  successMessage: '线索转化成功!',
},

Clicking the (correctly translated) 转化线索 button opens the confirm dialog with the console's own chrome in Chinese (title 确认操作, buttons 取消/继续) but the body in authored English: "Are you sure you want to convert this lead?" — the confirmText from src/actions/lead.actions.ts, not the bundle's translation.

Same entry, two fates: label goes through translation resolution, confirmText reaches the dialog untranslated. The actions surface of TranslationBundle explicitly carries confirmText, so the metadata contract says this should work.

Expected

The confirm dialog body resolves actions.<name>.confirmText from the active locale's bundle exactly like label does (and presumably successMessage on the toast wants checking too).

Repro

zh-CN console → HotCRM → any unconverted lead → click 转化线索 → dialog body is English while its button was Chinese.

Activity

  1. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Triage: pm:queue (+ bug). Sibling-repo card — no domain:* by design (whole-repo seat).

    • Classification: concrete defect with a repro and a named asymmetry — label from the same bundle entry resolves, confirmText does not. The TranslationBundle actions surface declares confirmText, so this is declared≠enforced on the consumer side, not a feature ask.
    • Landing anchors (read on origin/main @ b954120): the translated-action channel exists and carries all three keys (_actions.<name>.* — label / confirmText / successMessage, recorded in packages/app-shell/CHANGELOG.md:4241); the confirm-dialog plumbing takes a plain string body via useObjectActions.ts:28 (onConfirm(message, …)) into views/ActionConfirmDialog.tsx:23 — the fix is wiring the resolved confirmText (and checking successMessage on the toast, as the card notes) into that path.
    • Dedup: no open sibling — 注册路径的全屏长文本对话框全是英文字面量:Cancel / Done / Edit text / "Edit {label} fullscreen" 不走 i18n,而同一功能的内置分支已翻译(键早已存在于十个语言包) #3404 is closed and covered console chrome literals, not authored action text. The card's own observation that dialog chrome (确认操作/取消/继续) is already localized confirms this is the authored-metadata half only.
    • Stale-premise: checked against current main — no recent merge touches confirmText resolution in app-shell hooks (git log clean on that surface; the useConsoleActionRuntime.tsx:190 inline per-locale resolution covers param labels, not confirm bodies).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. self-assigned this
    on Aug 11, 2026
  3. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    CollaboratorAuthor

    CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3(objectui whole-repo PM seat),dispatching now。Branch: claude/issue-4265-confirmtext-translation。

    按 triage 锚点执行:把已解析的 _actions.<name>.confirmText 接进 useObjectActions.ts:28 → ActionConfirmDialog.tsx:23 的裸字符串通道,successMessage 的 toast 路径同 PR 核查(卡片点名"presumably wants checking")。要求:label 已走的解析通道是唯一事实源——confirmText/successMessage 必须复用同一个解析函数,不得为对话框再发明一条按 locale 取词的方言(useConsoleActionRuntime.tsx:190 的内联 per-locale 解析只覆盖 param labels,不要照抄第二份)。核心 pin:同一 bundle 条目,label 与 confirmText 同渲染同语言;无翻译条目时回退 authored 原文(对照)。

    Surface:packages/app-shell hooks/views(useObjectActions、ActionConfirmDialog、toast 路径)+ 测试;app-shell 面当前无在飞持有者(#4046/#4230 均已交付落地)。


    Generated by Claude Code

  4. yinlianghui commented on Aug 11, 2026

    @yinlianghui
    CollaboratorAuthor

    ACCEPT + 代决(安置问题) — PM review of record (session session_017Qqyix2QcnpUC9XeYVDzx3)。

    PR #4313 验收要点:

    • 测量修正了 triage 的锚点,且修正方式正确:useObjectLabel 早已暴露全部三个 resolver(actionLabel/actionConfirm/actionSuccess,同一 resolve() + 同一键约定)——通道从未缺失,是调用点漂移:六个动作渲染点里三个只解析 label(containers.tsx 的 page:header、record-quick-actions、RelatedRecordActionsBridge)。派单预设的 app-shell 落点被证伪,dev 按实测改道且如实声明,未触碰被 [P2] objectui: every package type-checks its tests or declares why not — and guards must prove they can fail (measured: 355 errors across 19 packages) #4040 持有的 packages/i18n。
    • 收敛形状对:useActionTextLocalizer() 是既有 resolver 的一次应用而非新方言,六站点全部走它——"局部化一个键、忘掉其余键"从结构上不再可能;顺手删掉只能载 label 的 actionLabel 注入口并跨包类型反证。
    • 边界条款有长期价值:confirmText/successMessage 仅在元数据声明时才解析——bundle 不能凭空给动作加确认门或 toast。回退语义(无条目 ⇒ 原文)双侧钉住。
    • 反向验证复现卡片原文("同一条目,两种命运":revert 态按钮仍是 转化线索 而对话框是英文);一处既有断言从引用同一改为结构相等,理由(六站点现在统一产出局部化副本)与"authored 节点不可变"补丁一并落地。CI 20 项收敛零失败;changeset patch×4。

    安置裁决:A(留在 @object-ui/react)。react 已 re-export 整个 i18n hook 面,零新依赖边、零第二词汇;迁移是纯文件移动,无累积成本,今天对着 #4040 在编辑的包开跨包移动才是贵的选择。B 的实质内容(SAFE_FIELD_LABEL_FALLBACK 补 actionConfirm/actionSuccess 以消灭 as any)记为将来 i18n 面卡片的候选 rider,不现在排。

    #4314(confirm.message 压过 confirmText 却无 bundle 键 + crud.ts 的 @deprecated 把作者指向不可翻译拼写)留 finding 池待分诊——休眠但类型自相矛盾,值得记录。

    Flipping ready + auto-merge。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions