web: fix locale inconsistencies (#4888)

start fixing locale inconsistencies

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-03-09 23:57:54 +01:00 committed by GitHub
parent d11ee46589
commit 9b8c0e3924
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 32 deletions

View file

@ -15,7 +15,6 @@ import { AdminApi, OutpostsApi, System } from "@goauthentik/api";
export class SystemStatusCard extends AdminStatusCard<System> { export class SystemStatusCard extends AdminStatusCard<System> {
now?: Date; now?: Date;
header = t`System status`;
icon = "pf-icon pf-icon-server"; icon = "pf-icon pf-icon-server";
@state() @state()
@ -82,6 +81,10 @@ export class SystemStatusCard extends AdminStatusCard<System> {
}); });
} }
renderHeader(): TemplateResult {
return html`${t`System status`}`;
}
renderValue(): TemplateResult { renderValue(): TemplateResult {
return html`${this.statusSummary}`; return html`${this.statusSummary}`;
} }

View file

@ -13,7 +13,6 @@ import { AdminApi, Version } from "@goauthentik/api";
@customElement("ak-admin-status-version") @customElement("ak-admin-status-version")
export class VersionStatusCard extends AdminStatusCard<Version> { export class VersionStatusCard extends AdminStatusCard<Version> {
header = t`Version`;
headerLink = "https://goauthentik.io/docs/releases"; headerLink = "https://goauthentik.io/docs/releases";
icon = "pf-icon pf-icon-bundle"; icon = "pf-icon pf-icon-bundle";
@ -40,6 +39,10 @@ export class VersionStatusCard extends AdminStatusCard<Version> {
}); });
} }
renderHeader(): TemplateResult {
return html`${t`Version`}`;
}
renderValue(): TemplateResult { renderValue(): TemplateResult {
if (this.value?.buildHash) { if (this.value?.buildHash) {
return html` return html`

View file

@ -6,14 +6,13 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { AdminApi } from "@goauthentik/api"; import { AdminApi } from "@goauthentik/api";
@customElement("ak-admin-status-card-workers") @customElement("ak-admin-status-card-workers")
export class WorkersStatusCard extends AdminStatusCard<number> { export class WorkersStatusCard extends AdminStatusCard<number> {
header = t`Workers`;
icon = "pf-icon pf-icon-server"; icon = "pf-icon pf-icon-server";
getPrimaryValue(): Promise<number> { getPrimaryValue(): Promise<number> {
@ -22,6 +21,10 @@ export class WorkersStatusCard extends AdminStatusCard<number> {
}); });
} }
renderHeader(): TemplateResult {
return html`${t`Workers`}`;
}
getStatus(value: number): Promise<AdminStatus> { getStatus(value: number): Promise<AdminStatus> {
if (value < 1) { if (value < 1) {
return Promise.resolve<AdminStatus>({ return Promise.resolve<AdminStatus>({

View file

@ -1,9 +1,11 @@
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants"; import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global"; import { globalAK } from "@goauthentik/common/global";
import { messages as enLocale } from "@goauthentik/locales/en";
import { PluralCategory } from "make-plural"; import { PluralCategory } from "make-plural";
import { en } from "make-plural/plurals";
import { Messages, i18n } from "@lingui/core"; import { Messages, i18n } from "@lingui/core";
import { detect, fromNavigator, fromUrl } from "@lingui/detect-locale"; import { fromNavigator, fromUrl } from "@lingui/detect-locale";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
interface Locale { interface Locale {
@ -21,8 +23,8 @@ export const LOCALES: {
label: t`English`, label: t`English`,
locale: async () => { locale: async () => {
return { return {
locale: (await import("@goauthentik/locales/en")).messages, locale: enLocale,
plurals: (await import("make-plural/plurals")).en, plurals: en,
}; };
}, },
}, },
@ -32,7 +34,7 @@ export const LOCALES: {
locale: async () => { locale: async () => {
return { return {
locale: (await import("@goauthentik/locales/pseudo-LOCALE")).messages, locale: (await import("@goauthentik/locales/pseudo-LOCALE")).messages,
plurals: (await import("make-plural/plurals")).en, plurals: en,
}; };
}, },
}, },
@ -121,23 +123,35 @@ export const LOCALES: {
const DEFAULT_FALLBACK = () => "en"; const DEFAULT_FALLBACK = () => "en";
export function autoDetectLanguage() { export function autoDetectLanguage() {
const detected = // Always load en locale at the start so we have something and don't error
detect( i18n.loadLocaleData("en", { plurals: en });
() => { i18n.load("en", enLocale);
return globalAK()?.locale; i18n.activate("en");
},
fromUrl("locale"), const locales: string[] = [];
fromNavigator(), // Get all locales we can, in order
DEFAULT_FALLBACK, // - Global authentik settings (contains user settings)
) || DEFAULT_FALLBACK(); // - URL parameter
const locales = [detected]; // - Navigator
// - Fallback (en)
// Remove any invalid values, add broader locales (fr-FR becomes fr)
// Remove any duplicate values
[globalAK()?.locale || "", fromUrl("locale"), fromNavigator(), DEFAULT_FALLBACK()]
.filter((v) => v && v !== "")
.map((locale) => {
locales.push(locale);
// For now we only care about the first locale part // For now we only care about the first locale part
if (detected.includes("_")) { if (locale.includes("_")) {
locales.push(detected.split("_")[0]); locales.push(locale.split("_")[0]);
} }
if (detected.includes("-")) { if (locale.includes("-")) {
locales.push(detected.split("-")[0]); locales.push(locale.split("-")[0]);
} }
})
.filter((v, idx, arr) => {
return arr.indexOf(v) === idx;
});
console.debug(`authentik/local: Locales to try: ${locales}`);
for (const tryLocale of locales) { for (const tryLocale of locales) {
if (LOCALES.find((locale) => locale.code === tryLocale)) { if (LOCALES.find((locale) => locale.code === tryLocale)) {
console.debug(`authentik/locale: Activating detected locale '${tryLocale}'`); console.debug(`authentik/locale: Activating detected locale '${tryLocale}'`);
@ -150,6 +164,7 @@ export function autoDetectLanguage() {
console.debug(`authentik/locale: No locale for '${locales}', falling back to en`); console.debug(`authentik/locale: No locale for '${locales}', falling back to en`);
activateLocale(DEFAULT_FALLBACK()); activateLocale(DEFAULT_FALLBACK());
} }
export function activateLocale(code: string) { export function activateLocale(code: string) {
const urlLocale = fromUrl("locale"); const urlLocale = fromUrl("locale");
if (urlLocale !== null && urlLocale !== "") { if (urlLocale !== null && urlLocale !== "") {
@ -161,6 +176,10 @@ export function activateLocale(code: string) {
return; return;
} }
locale.locale().then((localeData) => { locale.locale().then((localeData) => {
console.debug(`authentik/locale: Loaded locale '${code}'`);
if (i18n.locale === code) {
return;
}
i18n.loadLocaleData(locale.code, { plurals: localeData.plurals }); i18n.loadLocaleData(locale.code, { plurals: localeData.plurals });
i18n.load(locale.code, localeData.locale); i18n.load(locale.code, localeData.locale);
i18n.activate(locale.code); i18n.activate(locale.code);

View file

@ -50,10 +50,14 @@ export class AKElement extends LitElement {
get activeTheme(): UiThemeEnum | undefined { get activeTheme(): UiThemeEnum | undefined {
return this._activeTheme; return this._activeTheme;
} }
private _handleLocaleChange: () => void;
constructor() { constructor() {
super(); super();
this.addEventListener(EVENT_LOCALE_CHANGE, this._handleLocaleChange); this._handleLocaleChange = (() => {
this.requestUpdate();
}).bind(this);
window.addEventListener(EVENT_LOCALE_CHANGE, this._handleLocaleChange);
} }
protected createRenderRoot(): ShadowRoot | Element { protected createRenderRoot(): ShadowRoot | Element {
@ -147,11 +151,7 @@ export class AKElement extends LitElement {
disconnectedCallback() { disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
this.removeEventListener(EVENT_LOCALE_CHANGE, this._handleLocaleChange); window.removeEventListener(EVENT_LOCALE_CHANGE, this._handleLocaleChange);
}
private _handleLocaleChange() {
this.requestUpdate();
} }
} }

View file

@ -66,11 +66,15 @@ export class AggregateCard extends AKElement {
: ""}`; : ""}`;
} }
renderHeader(): TemplateResult {
return html`${this.header ? this.header : ""}`;
}
render(): TemplateResult { render(): TemplateResult {
return html`<div class="pf-c-card pf-c-card-aggregate"> return html`<div class="pf-c-card pf-c-card-aggregate">
<div class="pf-c-card__header pf-l-flex pf-m-justify-content-space-between"> <div class="pf-c-card__header pf-l-flex pf-m-justify-content-space-between">
<div class="pf-c-card__title"> <div class="pf-c-card__title">
<i class="${ifDefined(this.icon)}"></i>&nbsp;${this.header ? this.header : ""} <i class="${ifDefined(this.icon)}"></i>&nbsp;${this.renderHeader()}
</div> </div>
${this.renderHeaderLink()} ${this.renderHeaderLink()}
</div> </div>