web: fix locale inconsistencies (#4888)
start fixing locale inconsistencies Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
d11ee46589
commit
9b8c0e3924
|
@ -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}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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>({
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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> ${this.header ? this.header : ""}
|
<i class="${ifDefined(this.icon)}"></i> ${this.renderHeader()}
|
||||||
</div>
|
</div>
|
||||||
${this.renderHeaderLink()}
|
${this.renderHeaderLink()}
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in New Issue