feat(i18n): add vue-i18n with en, uk, de, ru, zh-CN locales#896
Conversation
Consolidates i18n work from PR ActivityWatch#855 (vue-i18n with uk/de/ru) and PR ActivityWatch#865 (zh-CN translations) into a single clean PR on latest master. Includes: - vue-i18n@8 infrastructure with TypeScript locale files - Language picker in Settings with localStorage persistence - Browser locale detection on first visit - Locale files: en, uk, de, ru, zh-CN - Core views migrated to $t() calls - Locale validation script and unit tests Co-Authored-By: NureRykushBohdan Co-Authored-By: JhihJian
ece9832 to
833af6c
Compare
Greptile SummaryThis PR adds full vue-i18n v8 infrastructure to aw-webui, migrating core views (Header, Footer, Home, Buckets, Timeline, Activity, Settings, and more) from hard-coded English strings to
Confidence Score: 5/5The change is safe to merge; it adds an opt-in i18n layer without altering any existing data paths or store contracts. All five locale files are fully wired up including zh-CN, the settings store locale lifecycle is correct, and the new functionality is well-covered by unit tests. The only gaps are cosmetic: document.documentElement.lang is not set when the locale comes from browser detection alone, and the installed vue-i18n v8 carries a deprecation notice — neither affects runtime correctness. The browser-detection-only path in src/i18n/index.ts and src/stores/settings.ts is the one place where the document.documentElement.lang attribute does not get updated. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Browser
participant i18n as i18n/index.ts
participant Store as settings.ts
participant LS as localStorage
participant Server as aw-server
Browser->>i18n: module init
i18n->>LS: getItem('locale')
alt stored locale found
LS-->>i18n: 'de'
i18n->>i18n: "initialLocale = 'de'"
else no stored locale
i18n->>Browser: navigator.language
Browser-->>i18n: 'de-DE'
i18n->>i18n: detectBrowserLocale() returns 'de'
end
i18n->>i18n: "new VueI18n({ locale })"
i18n->>i18n: moment.locale('de')
Browser->>Store: settings.load()
Store->>Server: get_settings()
Server-->>Store: "{ locale } or {}"
alt locale in server or localStorage
Store->>i18n: setAppLocale('de')
i18n->>LS: setItem('locale', 'de')
i18n->>Browser: "document.lang = 'de'"
else browser-detected only
Store->>Store: "patch({ locale: i18n.locale })"
Note over Store,Browser: document.lang NOT updated here
end
Browser->>Store: user picks 'ru' in LanguageSettings
Store->>i18n: setAppLocale('ru')
i18n->>LS: setItem('locale', 'ru')
i18n->>Browser: "document.lang = 'ru'"
Store->>Server: POST /0/settings/locale 'ru'
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Browser
participant i18n as i18n/index.ts
participant Store as settings.ts
participant LS as localStorage
participant Server as aw-server
Browser->>i18n: module init
i18n->>LS: getItem('locale')
alt stored locale found
LS-->>i18n: 'de'
i18n->>i18n: "initialLocale = 'de'"
else no stored locale
i18n->>Browser: navigator.language
Browser-->>i18n: 'de-DE'
i18n->>i18n: detectBrowserLocale() returns 'de'
end
i18n->>i18n: "new VueI18n({ locale })"
i18n->>i18n: moment.locale('de')
Browser->>Store: settings.load()
Store->>Server: get_settings()
Server-->>Store: "{ locale } or {}"
alt locale in server or localStorage
Store->>i18n: setAppLocale('de')
i18n->>LS: setItem('locale', 'de')
i18n->>Browser: "document.lang = 'de'"
else browser-detected only
Store->>Store: "patch({ locale: i18n.locale })"
Note over Store,Browser: document.lang NOT updated here
end
Browser->>Store: user picks 'ru' in LanguageSettings
Store->>i18n: setAppLocale('ru')
i18n->>LS: setItem('locale', 'ru')
i18n->>Browser: "document.lang = 'ru'"
Store->>Server: POST /0/settings/locale 'ru'
Reviews (3): Last reviewed commit: "fix(i18n): fix lint error - replace empt..." | Re-trigger Greptile |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #896 +/- ##
==========================================
+ Coverage 35.58% 38.42% +2.84%
==========================================
Files 36 42 +6
Lines 2161 2225 +64
Branches 401 436 +35
==========================================
+ Hits 769 855 +86
+ Misses 1371 1292 -79
- Partials 21 78 +57 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@greptileai review |
✅ Ready to MergeAll checks passing:
Summary: This PR consolidates i18n work (vue-i18n@8 with en, uk, de, ru, zh-CN) from PRs #855 and #865 into a single clean implementation. The changes are additive, fall back cleanly to English on any missing key, and all five locale files are fully wired and validated. Ready for merge by maintainer. |
|
@greptileai review |
…Watch#896) * feat(i18n): add vue-i18n with en, uk, de, ru, zh-CN locales Consolidates i18n work from PR ActivityWatch#855 (vue-i18n with uk/de/ru) and PR ActivityWatch#865 (zh-CN translations) into a single clean PR on latest master. Includes: - vue-i18n@8 infrastructure with TypeScript locale files - Language picker in Settings with localStorage persistence - Browser locale detection on first visit - Locale files: en, uk, de, ru, zh-CN - Core views migrated to $t() calls - Locale validation script and unit tests Co-Authored-By: NureRykushBohdan <bohdan.rykush@nure.ua> Co-Authored-By: JhihJian <jhihjian@foxmail.com> * fix(i18n): update package-lock.json with vue-i18n@8 entry * style(i18n): apply prettier formatting (single quotes, trailing commas) * fix(i18n): wire zh-CN locale * fix(i18n): fix lint error - replace empty arrow function with jest.fn() in locale test
Summary
Consolidates i18n work from PRs #855 (vue-i18n with uk/de/ru) and #865 (zh-CN translations) into a single clean PR on latest master, per Erik's request (see comments on #895).
Includes:
Follow-up (not in scope):
Closes #855, #865
Supersedes #895