Missing i18n translations: event.title.approval_decided + event.title.member_role_changed render as raw keys #101
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
m's report (2026-05-25 15:23)
In an event-type filter list (looks like the /events or custom-view filter), two entries render as raw i18n keys instead of translated labels:
All the others use a proper translated label. Two keys missed the i18n catalog.
What to do
frontend/src/client/i18n.tsandfrontend/src/i18n-keys.ts:event.title.approval_decided→ DE: "Genehmigung entschieden" / EN: "Approval decided"event.title.member_role_changed→ DE: "Teamrolle geändert" / EN: "Team role changed"paliad.project_events.event_typeandKnownProjectEventKinds) and confirm each has both DE + EN labels.Files most likely touched
frontend/src/client/i18n.tsfrontend/src/i18n-keys.tsHard rules
cd frontend && bun run buildclean (i18n codegen runs; should catch missing keys).mai/<worker>/i18n-event-titles.Out of scope
Reporting
mai report completedwith branch + SHAs + the audited list of all event kinds + their DE/EN labels.Fix shipped
Branch:
mai/artemis/gitster-add-missing-i18nCommit:
f72e8a7—mAi: #101 - add missing event.title.approval_decided + member_role_changed i18nRoot cause
frontend/src/client/filter-bar/axes.ts:300-314hard-codes aPROJECT_EVENT_KINDSlist (the FilterBar chip cluster), then renders each chip's label via:tDyn(i18n.ts:6091-6093) falls back to the raw key when the catalog is missing the entry — exactly what was on screen. The catalog covered every other kind inPROJECT_EVENT_KINDSbut had no entries forapproval_decidedormember_role_changed.Changes
frontend/src/client/i18n.ts— two new entries per locale, placed right afterappointment_project_changedso the umbrella/admin kinds sit next to the lifecycle kinds and before the per-entity*_approval_*lifecycle block:event.title.approval_decidedevent.title.member_role_changedfrontend/src/i18n-keys.ts— regenerated byfrontend/build.ts'sgenerateI18nKeys(auto-generated from the source of truth above).bun run buildclean — i18n codegen reports 2864 keys, data-i18n scan clean, dist/ built.Audit — every KnownProjectEventKind has DE + EN now
Canonical list lives in
internal/services/filter_spec.go:200:project_createdproject_archivedproject_reparentedproject_type_changedstatus_changeddeadline_createddeadline_completeddeadline_reopeneddeadline_updateddeadline_deleteddeadlines_importedappointment_createdappointment_updatedappointment_deletedapproval_decided✨member_role_changed✨note_createdour_side_changed18 / 18 covered. ✨ = newly added.
Notes for follow-up
PROJECT_EVENT_KINDS(axes.ts) andKnownProjectEventKinds(filter_spec.go) remains. Today the frontend list is a hand-maintained subset — it omitsdeadline_updated,deadline_deleted,deadlines_imported,note_created, andour_side_changed. That divergence is intentional in the current state (the chip cluster is a curated UX, not a faithful mirror), but the file comment ataxes.ts:295says "Mirrors KnownProjectEventKinds", which is no longer true. Worth either (a) realigning the list, or (b) updating the comment. Out of scope for this issue — flagging for awareness, not patching.tDynreturning the key itself was what made this bug visible; that's the right contract (better than rendering an empty chip). Leaving it.*_approval_*per-entity audit kinds (event.title.deadline_approval_requested, etc.) are already covered; they're separate event_types and not the umbrellaapproval_decidedchip label.Reporting
No other rendering callsites (Verlauf row title via
translateEvent, ShapeList viat("event.title." + …)) were calling into the missing kinds because nopaliad.project_eventsrow carriesevent_type='approval_decided'(it's a filter-only umbrella). The actually-emittedmember_role_changedrows frominternal/services/partner_unit_service.go:369will now also render with a translated title wherever the event-rendering path passes them throughevent.title.*.