web: re-organise frontend and cleanup common code (#3572)

* fix repo in api client

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: re-organise files to match their interface

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* core: include version in script tags

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* cleanup maybe broken

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* revert rename

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: get rid of Client.ts

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* move more to common

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* more moving

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* format

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* unfuck files that vscode fucked, thanks

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* move more

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* finish moving (maybe)

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* ok more moving

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix more stuff that vs code destroyed

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* get rid "web" prefix for virtual package

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix locales

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* use custom base element

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix css file

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* don't run autoDetectLanguage when importing locale

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix circular dependencies

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: fix build

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L
2022-09-15 00:05:21 +02:00
committed by GitHub
parent 369440652c
commit 4a91a7d2e2
291 changed files with 2062 additions and 1921 deletions

View File

@ -0,0 +1,89 @@
import { me } from "@goauthentik/common/users";
import { UserSelf } from "@goauthentik/api";
export enum UserDisplay {
username = "username",
name = "name",
email = "email",
}
export enum LayoutType {
row = "row",
column_2 = "2-column",
column_3 = "3-column",
}
export interface UIConfig {
enabledFeatures: {
// API Request drawer in navbar
apiDrawer: boolean;
// Notification drawer in navbar
notificationDrawer: boolean;
// Settings in user dropdown
settings: boolean;
// Application edit in library (only shown when user is superuser)
applicationEdit: boolean;
// Search bar
search: boolean;
};
navbar: {
userDisplay: UserDisplay;
};
theme: {
background: string;
cardBackground: string;
};
pagination: {
perPage: number;
};
layout: {
type: LayoutType;
};
locale: string;
}
export class DefaultUIConfig implements UIConfig {
enabledFeatures = {
apiDrawer: true,
notificationDrawer: true,
settings: true,
applicationEdit: true,
search: true,
};
layout = {
type: LayoutType.row,
};
navbar = {
userDisplay: UserDisplay.username,
};
theme = {
background: "",
cardBackground: "",
};
pagination = {
perPage: 20,
};
locale = "";
}
let globalUiConfig: Promise<UIConfig>;
export function getConfigForUser(user: UserSelf): UIConfig {
const settings = user.settings;
let config = new DefaultUIConfig();
if (!settings) {
return config;
}
config = Object.assign(new DefaultUIConfig(), settings);
return config;
}
export function uiConfig(): Promise<UIConfig> {
if (!globalUiConfig) {
globalUiConfig = me().then((user) => {
return getConfigForUser(user.user);
});
}
return globalUiConfig;
}

174
web/src/common/ui/locale.ts Normal file
View File

@ -0,0 +1,174 @@
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { Messages, i18n } from "@lingui/core";
import { detect, fromNavigator, fromUrl } from "@lingui/detect-locale";
import { t } from "@lingui/macro";
interface Locale {
locale: Messages;
// eslint-disable-next-line @typescript-eslint/ban-types
plurals: Function;
}
export const LOCALES: {
code: string;
label: string;
locale: () => Promise<Locale>;
}[] = [
{
code: "en",
label: t`English`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/en")).messages,
plurals: (await import("make-plural/plurals")).en,
};
},
},
{
code: "debug",
label: t`Debug`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/pseudo-LOCALE")).messages,
plurals: (await import("make-plural/plurals")).en,
};
},
},
{
code: "fr",
label: t`French`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/fr_FR")).messages,
plurals: (await import("make-plural/plurals")).fr,
};
},
},
{
code: "tr",
label: t`Turkish`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/tr")).messages,
plurals: (await import("make-plural/plurals")).tr,
};
},
},
{
code: "es",
label: t`Spanish`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/es")).messages,
plurals: (await import("make-plural/plurals")).es,
};
},
},
{
code: "pl",
label: t`Polish`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/pl")).messages,
plurals: (await import("make-plural/plurals")).pl,
};
},
},
{
code: "zh_TW",
label: t`Taiwanese Mandarin`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/zh_TW")).messages,
plurals: (await import("make-plural/plurals")).zh,
};
},
},
{
code: "zh-CN",
label: t`Chinese (simplified)`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/zh-Hans")).messages,
plurals: (await import("make-plural/plurals")).zh,
};
},
},
{
code: "zh-HK",
label: t`Chinese (traditional)`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/zh-Hant")).messages,
plurals: (await import("make-plural/plurals")).zh,
};
},
},
{
code: "de",
label: t`German`,
locale: async () => {
return {
locale: (await import("@goauthentik/locales/de")).messages,
plurals: (await import("make-plural/plurals")).de,
};
},
},
];
const DEFAULT_FALLBACK = () => "en";
export function autoDetectLanguage() {
const detected =
detect(
() => {
return globalAK()?.locale;
},
fromUrl("locale"),
fromNavigator(),
DEFAULT_FALLBACK,
) || DEFAULT_FALLBACK();
const locales = [detected];
// For now we only care about the first locale part
if (detected.includes("_")) {
locales.push(detected.split("_")[0]);
}
if (detected.includes("-")) {
locales.push(detected.split("-")[0]);
}
for (const tryLocale of locales) {
if (LOCALES.find((locale) => locale.code === tryLocale)) {
console.debug(`authentik/locale: Activating detected locale '${tryLocale}'`);
activateLocale(tryLocale);
return;
} else {
console.debug(`authentik/locale: No matching locale for ${tryLocale}`);
}
}
console.debug(`authentik/locale: No locale for '${locales}', falling back to en`);
activateLocale(DEFAULT_FALLBACK());
}
export function activateLocale(code: string) {
const urlLocale = fromUrl("locale");
if (urlLocale !== null && urlLocale !== "") {
code = urlLocale;
}
const locale = LOCALES.find((locale) => locale.code == code);
if (!locale) {
console.warn(`authentik/locale: failed to find locale for code ${code}`);
return;
}
locale.locale().then((localeData) => {
i18n.loadLocaleData(locale.code, { plurals: localeData.plurals });
i18n.load(locale.code, localeData.locale);
i18n.activate(locale.code);
window.dispatchEvent(
new CustomEvent(EVENT_LOCALE_CHANGE, {
bubbles: true,
composed: true,
}),
);
});
}