05 — Screen Inventory (i18n Module)
- Legend
- 1. Translation Key List (
/admin/i18n/keys) (planned) - 2. Key Editor (
/admin/i18n/keys/:key) (planned) - 3. New Key (
/admin/i18n/keys/new) (planned) - 4. Locale Management (
/admin/i18n/locales) (planned) - 5. Translation Sync / Drift view (
/admin/i18n/sync) (planned) - 6. Mobile app surface
- Shared components used
- Analytics events (proposed)
- Keyboard, landscape, tablet, desktop
Every screen of the i18n surface: one public API-facing screen (none — the mobile app has no dedicated i18n screen; it consumes catalogs) plus the (planned) admin translation console. Authoritative components in 00-shared/03; this file enumerates which ones each screen uses with module specifics.
Legend
States = idle / loading / success / empty / error(offline, rate, invalid) /
disabled / permission. Analytics follow {module}.{screen}.{action}
(proposed; SDK open — 00-shared/10 §8).
1. Translation Key List (/admin/i18n/keys) (planned)
| Field | Detail |
|---|---|
| Purpose | Browse, search, filter all translation keys across locales |
| Entry | admin console home; console nav |
| Exit | row tap → Key Editor; FAB → New Key; Locale chip → Locale Management |
| Source | GET /api/v1/i18n/keys (planned) — list with per-locale status |
| Widgets | AppSearchBar, AppDataTable/AppListTile, AppChips (locale filter), AppBadge (missing, stale, ok), AppEmptyState, AppSkeleton |
| Row data | key, namespace group, params {days}, coverage badge, last edited |
| States | loading skeleton; empty ("No keys"); error (401 → login); permission-denied (no i18n.* role) |
| Sort/filter | by namespace, by missing-in-locale, by placeholder presence |
| Bulk actions (planned) | select keys → bulk edit / delete / export |
| Analytics (proposed) | i18n.keys.{open,search,filter,open_row,create} |
2. Key Editor (/admin/i18n/keys/:key) (planned)
| Field | Detail |
|---|---|
| Purpose | View/edit one key's value in every locale |
| Entry | row tap in Key List; inline "missing" badge CTA |
| Exit | save → back to list; delete → confirm dialog |
| Layout | master-detail on tablet: key list left, editor right |
| Content | read-only key + params chips; per-locale AppTextFields (en source + all shipped/declared locales), one tab/tile per locale; missing locales highlighted |
| Validation | placeholders must match source (see 08_Form_Specifications.md §2); non-empty if locale shipped |
| Save | PUT /api/v1/i18n/keys/:key (planned); optimistic, rollback on fail |
| States | dirty indicator, per-field save state, conflict → reload prompt |
| Analytics (proposed) | i18n.key.{open,edit,save,delete,params_mismatch} |
3. New Key (/admin/i18n/keys/new) (planned)
| Field | Detail |
|---|---|
| Purpose | Create a key + source value in one step |
| Form | key (dotted path, uniqueness), params chips (optional), en value required, optional first-edit of other locales |
| Create | POST /api/v1/i18n/keys (planned) → jumps to Key Editor |
| States | duplicate-key 409 inline |
4. Locale Management (/admin/i18n/locales) (planned)
| Field | Detail |
|---|---|
| Purpose | View supported locales, coverage %, promote/demote, add new locale |
| Source | GET /api/v1/i18n/locales (planned) |
| Widgets | AppCard per locale: name, tag, coverage ring (missing/total), status chip (shipped/declared), "add locale" |
| Actions | add locale (creates empty catalog), coverage drill-down → Key List filtered |
| Note | today SUPPORTED_LOCALES is a code constant (i18n.service.ts:11-21); promoting a locale is a deploy. The console makes this data-driven (planned) |
5. Translation Sync / Drift view (/admin/i18n/sync) (planned)
| Field | Detail |
|---|---|
| Purpose | CI/Crowdin drift report: which keys are missing/stale per locale |
| Source | GET /api/v1/i18n/drift (planned) or CI artifact (IMPLEMENTATION_PLAN.md:845) |
| Content | table of locale × missing keys; "diff" of placeholder mismatches; export CSV |
| CTA | "Open missing in editor" |
6. Mobile app surface
No dedicated screen. The app fetches the catalog once
(GET /api/v1/i18n/messages?locale=, i18n.controller.ts:13-17), caches it,
and renders through Flutter's intl/ARB (see 15_Flutter_Implementation_Guide.md).
In-app locale switching is (forward-looking).
Shared components used
AppTextField, AppButton, AppSnackbar, AppCard, AppListTile,
AppDataTable, AppBottomSheet, AppDialog, AppMenu, AppSkeleton,
AppEmptyState, AppOfflineBanner, AppChips, AppBadge, AppSearchBar,
AppFAB. Module-specific: per-locale field group, coverage ring —
defined in 07_Component_Library.md.
Analytics events (proposed)
i18n.keys.{open,search,filter,open_row,create},
i18n.key.{open,edit,save,delete,params_mismatch},
i18n.locale.{open,add,promote}, i18n.sync.{open,export}.
Keyboard, landscape, tablet, desktop
- Key Editor: per-locale fields in scrollable columns; tablet splits list/detail; desktop constrains form width ≤ 720 dp.
- All fields keyboard-avoidance +
ScrollViewresizeToAvoidBottomInset. - Devanagari/Indic IMEs: fields must not force Latin keyboards; keep
TextCapitalization.nonefor translation fields.