Skip to content

fix(i18n): BPM task buttons and remaining Harmonia chrome localize - task labels land in the catalog, views resolve them by name (#6521) - #6531

Merged
delchev merged 1 commit into
masterfrom
fix/harmonia-i18n-task-buttons
Aug 5, 2026
Merged

fix(i18n): BPM task buttons and remaining Harmonia chrome localize - task labels land in the catalog, views resolve them by name (#6521)#6531
delchev merged 1 commit into
masterfrom
fix/harmonia-i18n-task-buttons

Conversation

@delchev

@delchev delchev commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Problem

On a fully localized generated app (BG catalogs complete), the in-record BPM task buttons — Approve, Issue, Send, … — stayed English, along with a set of non-process chrome strings. The task buttons bound the raw runtime task.name (the BPMN user-task name) with no translation key anywhere in the chain: no processes section in the catalog, no label map on the .model, no T() at the six render sites.

Fix

BPM task buttons — resolved entirely at generation time (the task set is part of the process definition, so nothing is derived at runtime):

  • EdmIntentGenerator puts a processTaskLabels map on the .model root, keyed by the authored step name (managerReview"Manager Review") — the customActionLabels convention from fix(i18n): custom per-record action buttons localize — translation keys + catalog labels (#6523) #6524.
  • The template engine's translate action folds it into the generated en catalog's processes section.
  • The Harmonia full-stack template bakes the reverse map (runtime task name → step-name key) into the generated config.js, and the six view sites (manage form, document, list, manage list, master ×2) translate by exact lookup: T('<project>:<tprefix>.processes.' + processTaskKeys[task.name], task.name) — raw name as fallback for hand-authored BPMN / cross-project processes.

Remaining hardcoded chrome localized (new catalog keys defaults.pageOf/newTitle/deleteLine, messages.deleteItemsRecalc/deleteLineConfirm/printLanguage/noDataTitle/reportNoRows): the Page x / y paginators, the "New " buttons and related-create dialog titles, every delete-confirm dialog (incl. the document "Delete line" dialog whose Cancel/Delete were raw), both Print language pickers, the my/partner Select... placeholders, the report "No data" states, and the settings Language placeholder.

Standalone report page gets i18n wired in — it had zero T(): an inline App.config.projectName bootstrap + i18n.js, all chrome strings (Filters/Refresh/Export/Print/Apply/Clear/Prev/Next/Total/No data/placeholders + the report title via its catalog key) through a new shell.report.* section shipped in both en-US and bg-BG shared shell catalogs.

Latent translator bug fixed: the T() fallback path returned baked strings verbatim, so {{name}}-style placeholders with runtime values (Updated {{time}}, New task: {{name}}, and the new keys) rendered literal braces in the default language. i18n.js (store + window.T) and the app.js stub now interpolate the fallback.

Testing

  • IntentEngineIT locks both new halves: the en catalog's processes section and the baked config.js name→key map (targeted run green).
  • New unit test EdmIntentGeneratorTest.processUserTasksEmitTheirLabelCatalogMap; engine-intent 302/302.
  • formatter:validate and the javadoc release-profile check on engine-intent are clean.

Known gaps (deliberate)

The task-form dialog title and the shell Inbox/bell still show the raw task name — those surfaces are cross-project and cannot know which project catalog owns a task (would need a key on the TaskDTO). Report column headers come from the SQL response aliases. Existing localized apps need a regen for the new keys to appear in their en catalogs, then the language catalogs extended.

🤖 Generated with Claude Code

…task labels land in the catalog, views resolve them by name (#6521)

On a localized generated app the in-record BPM task buttons (Approve,
Issue, Send, ...) stayed English: the views bound the raw runtime
task.name with no translation key anywhere in the chain. Since the task
set is part of the process definition, everything is resolved at
generation time: EdmIntentGenerator puts a processTaskLabels map
(authored step name -> humanized task name) on the .model root, the
translate action folds it into the en catalog's processes section, and
the Harmonia template bakes the reverse (runtime name -> key) map into
config.js so the six view sites translate by exact lookup -
T('<project>:<tprefix>.processes.' + processTaskKeys[task.name],
task.name) - with the raw name as fallback. No runtime key derivation.

The sweep also localizes the remaining hardcoded chrome: the
Page x / y paginators, the "New <entity>" buttons and dialog titles,
every delete-confirm dialog (including the document "Delete line"
dialog whose Cancel/Delete were raw), both Print language pickers, the
my/partner "Select..." placeholders, the report "No data" states and
the settings Language placeholder - via new catalog keys - and wires
i18n into the standalone report page (App bootstrap + i18n.js + a new
shell.report section in the shared en/bg shell catalogs).

Also fixes a latent translator bug: the T() fallback path returned
baked strings verbatim, so {{name}}-style placeholders with runtime
values (Updated {{time}}, New task: {{name}}) rendered literal braces
in the default language; i18n.js and the app.js stub now interpolate
the fallback.

IntentEngineIT locks the catalog's processes section and the baked
config.js map; engine-intent 302/302 unit tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev
delchev merged commit c109162 into master Aug 5, 2026
10 checks passed
@delchev
delchev deleted the fix/harmonia-i18n-task-buttons branch August 5, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant