web: fix theming issues when using automatic (#4898)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
		| @ -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 New Issue
	
	Block a user
	 Jens L
					Jens L