web: fix theming issues when using automatic (#4898)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
0ef333f8ea
commit
59e54901fb
|
@ -70,7 +70,11 @@ export class AdminInterface extends Interface {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.pf-c-page {
|
.pf-c-page {
|
||||||
background-color: transparent !important;
|
background-color: var(--pf-c-page--BackgroundColor) !important;
|
||||||
|
}
|
||||||
|
/* Global page background colour */
|
||||||
|
:host([theme="dark"]) .pf-c-page {
|
||||||
|
--pf-c-page--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
|
|
@ -17,6 +17,7 @@ export const EVENT_FLOW_ADVANCE = "ak-flow-advance";
|
||||||
export const EVENT_LOCALE_CHANGE = "ak-locale-change";
|
export const EVENT_LOCALE_CHANGE = "ak-locale-change";
|
||||||
export const EVENT_REQUEST_POST = "ak-request-post";
|
export const EVENT_REQUEST_POST = "ak-request-post";
|
||||||
export const EVENT_MESSAGE = "ak-message";
|
export const EVENT_MESSAGE = "ak-message";
|
||||||
|
export const EVENT_THEME_CHANGE = "ak-theme-change";
|
||||||
|
|
||||||
export const WS_MSG_TYPE_MESSAGE = "message";
|
export const WS_MSG_TYPE_MESSAGE = "message";
|
||||||
export const WS_MSG_TYPE_REFRESH = "refresh";
|
export const WS_MSG_TYPE_REFRESH = "refresh";
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
|
import { EVENT_LOCALE_CHANGE, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { globalAK } from "@goauthentik/common/global";
|
|
||||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||||
|
|
||||||
import { LitElement } from "lit";
|
import { LitElement } from "lit";
|
||||||
|
@ -68,6 +67,10 @@ export class AKElement extends LitElement {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getTheme(): Promise<UiThemeEnum> {
|
||||||
|
return rootInterface()?.getTheme() || UiThemeEnum.Automatic;
|
||||||
|
}
|
||||||
|
|
||||||
async _initTheme(root: AdoptedStyleSheetsElement): Promise<void> {
|
async _initTheme(root: AdoptedStyleSheetsElement): Promise<void> {
|
||||||
// Early activate theme based on media query to prevent light flash
|
// Early activate theme based on media query to prevent light flash
|
||||||
// when dark is preferred
|
// when dark is preferred
|
||||||
|
@ -77,7 +80,7 @@ export class AKElement extends LitElement {
|
||||||
? UiThemeEnum.Light
|
? UiThemeEnum.Light
|
||||||
: UiThemeEnum.Dark,
|
: UiThemeEnum.Dark,
|
||||||
);
|
);
|
||||||
rootInterface()?._initTheme(root);
|
this._applyTheme(root, await this.getTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initCustomCSS(root: ShadowRoot): Promise<void> {
|
private async _initCustomCSS(root: ShadowRoot): Promise<void> {
|
||||||
|
@ -120,33 +123,36 @@ export class AKElement extends LitElement {
|
||||||
this._activateTheme(root, theme);
|
this._activateTheme(root, theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static themeToStylesheet(theme?: UiThemeEnum): CSSStyleSheet | undefined {
|
||||||
|
if (theme === UiThemeEnum.Dark) {
|
||||||
|
return ThemeDark;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
_activateTheme(root: AdoptedStyleSheetsElement, theme: UiThemeEnum) {
|
_activateTheme(root: AdoptedStyleSheetsElement, theme: UiThemeEnum) {
|
||||||
if (this._activeTheme === theme) {
|
console.log("activating theme", theme, this._activeTheme, this);
|
||||||
|
if (theme === this._activeTheme) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Make sure we only get to this callback once we've picked a concise theme choice
|
// Make sure we only get to this callback once we've picked a concise theme choice
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent("themeChange", {
|
new CustomEvent(EVENT_THEME_CHANGE, {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true,
|
composed: true,
|
||||||
detail: theme,
|
detail: theme,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
this._activeTheme = theme;
|
|
||||||
this.setAttribute("theme", theme);
|
this.setAttribute("theme", theme);
|
||||||
let stylesheet: CSSStyleSheet | undefined;
|
const stylesheet = AKElement.themeToStylesheet(theme);
|
||||||
if (theme === UiThemeEnum.Dark) {
|
const oldStylesheet = AKElement.themeToStylesheet(this._activeTheme);
|
||||||
stylesheet = ThemeDark;
|
if (stylesheet) {
|
||||||
}
|
|
||||||
if (!stylesheet) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (root.adoptedStyleSheets.indexOf(stylesheet) === -1) {
|
|
||||||
root.adoptedStyleSheets = [...root.adoptedStyleSheets, stylesheet];
|
root.adoptedStyleSheets = [...root.adoptedStyleSheets, stylesheet];
|
||||||
} else {
|
|
||||||
root.adoptedStyleSheets = root.adoptedStyleSheets.filter((v) => v !== stylesheet);
|
|
||||||
}
|
}
|
||||||
this.requestUpdate();
|
if (oldStylesheet) {
|
||||||
|
root.adoptedStyleSheets = root.adoptedStyleSheets.filter((v) => v !== oldStylesheet);
|
||||||
|
}
|
||||||
|
this._activeTheme = theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
|
@ -161,13 +167,8 @@ export class Interface extends AKElement {
|
||||||
super._activateTheme(document, theme);
|
super._activateTheme(document, theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initTheme(root: AdoptedStyleSheetsElement): Promise<void> {
|
async getTheme(): Promise<UiThemeEnum> {
|
||||||
const bootstrapTheme = globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
|
const config = await uiConfig();
|
||||||
this._applyTheme(root, bootstrapTheme);
|
return config.theme.base;
|
||||||
uiConfig().then((config) => {
|
|
||||||
if (config.theme.base) {
|
|
||||||
this._applyTheme(root, config.theme.base);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import * as yamlMode from "@codemirror/legacy-modes/mode/yaml";
|
||||||
import { Compartment, EditorState, Extension } from "@codemirror/state";
|
import { Compartment, EditorState, Extension } from "@codemirror/state";
|
||||||
import { oneDark } from "@codemirror/theme-one-dark";
|
import { oneDark } from "@codemirror/theme-one-dark";
|
||||||
import { EditorView, drawSelection, keymap, lineNumbers } from "@codemirror/view";
|
import { EditorView, drawSelection, keymap, lineNumbers } from "@codemirror/view";
|
||||||
|
import { EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import YAML from "yaml";
|
import YAML from "yaml";
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ export class CodeMirrorTextarea<T> extends AKElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated(): void {
|
firstUpdated(): void {
|
||||||
this.addEventListener("themeChange", ((ev: CustomEvent<UiThemeEnum>) => {
|
this.addEventListener(EVENT_THEME_CHANGE, ((ev: CustomEvent<UiThemeEnum>) => {
|
||||||
if (ev.detail === UiThemeEnum.Dark) {
|
if (ev.detail === UiThemeEnum.Dark) {
|
||||||
this.editor?.dispatch({
|
this.editor?.dispatch({
|
||||||
effects: this.theme.reconfigure(this.themeDark),
|
effects: this.theme.reconfigure(this.themeDark),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import mermaid, { MermaidConfig } from "mermaid";
|
import mermaid, { MermaidConfig } from "mermaid";
|
||||||
|
@ -53,7 +53,7 @@ export class Diagram extends AKElement {
|
||||||
firstUpdated(): void {
|
firstUpdated(): void {
|
||||||
if (this.handlerBound) return;
|
if (this.handlerBound) return;
|
||||||
window.addEventListener(EVENT_REFRESH, this.refreshHandler);
|
window.addEventListener(EVENT_REFRESH, this.refreshHandler);
|
||||||
this.addEventListener("themeChange", ((ev: CustomEvent<UiThemeEnum>) => {
|
this.addEventListener(EVENT_THEME_CHANGE, ((ev: CustomEvent<UiThemeEnum>) => {
|
||||||
if (ev.detail === UiThemeEnum.Dark) {
|
if (ev.detail === UiThemeEnum.Dark) {
|
||||||
this.config.theme = "dark";
|
this.config.theme = "dark";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/EmptyState";
|
import "@goauthentik/elements/EmptyState";
|
||||||
import {
|
import {
|
||||||
|
@ -93,7 +93,7 @@ export abstract class AKChart<T> extends AKElement {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
window.addEventListener("resize", this.resizeHandler);
|
window.addEventListener("resize", this.resizeHandler);
|
||||||
this.addEventListener(EVENT_REFRESH, this.refreshHandler);
|
this.addEventListener(EVENT_REFRESH, this.refreshHandler);
|
||||||
this.addEventListener("themeChange", ((ev: CustomEvent<UiThemeEnum>) => {
|
this.addEventListener(EVENT_THEME_CHANGE, ((ev: CustomEvent<UiThemeEnum>) => {
|
||||||
if (ev.detail === UiThemeEnum.Light) {
|
if (ev.detail === UiThemeEnum.Light) {
|
||||||
this.fontColour = FONT_COLOUR_LIGHT_MODE;
|
this.fontColour = FONT_COLOUR_LIGHT_MODE;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { globalAK } from "@goauthentik/common/global";
|
||||||
import { configureSentry } from "@goauthentik/common/sentry";
|
import { configureSentry } from "@goauthentik/common/sentry";
|
||||||
import { first } from "@goauthentik/common/utils";
|
import { first } from "@goauthentik/common/utils";
|
||||||
import { WebsocketClient } from "@goauthentik/common/ws";
|
import { WebsocketClient } from "@goauthentik/common/ws";
|
||||||
import { AdoptedStyleSheetsElement, Interface } from "@goauthentik/elements/Base";
|
import { Interface } from "@goauthentik/elements/Base";
|
||||||
import "@goauthentik/elements/LoadingOverlay";
|
import "@goauthentik/elements/LoadingOverlay";
|
||||||
import "@goauthentik/flow/stages/FlowErrorStage";
|
import "@goauthentik/flow/stages/FlowErrorStage";
|
||||||
import "@goauthentik/flow/stages/RedirectStage";
|
import "@goauthentik/flow/stages/RedirectStage";
|
||||||
|
@ -182,9 +182,8 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||||
tenant().then((tenant) => (this.tenant = tenant));
|
tenant().then((tenant) => (this.tenant = tenant));
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initTheme(root: AdoptedStyleSheetsElement): Promise<void> {
|
async getTheme(): Promise<UiThemeEnum> {
|
||||||
const bootstrapTheme = globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
|
return globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
|
||||||
this._applyTheme(root, bootstrapTheme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
submit(payload?: FlowChallengeResponseRequest): Promise<boolean> {
|
submit(payload?: FlowChallengeResponseRequest): Promise<boolean> {
|
||||||
|
|
Reference in a new issue