Compare commits

..

4 Commits

9 changed files with 123 additions and 186 deletions

View File

@ -66,13 +66,13 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
aboutModal?: AboutModal; aboutModal?: AboutModal;
@property({ type: Boolean, reflect: true }) @property({ type: Boolean, reflect: true })
public sidebarOpen: boolean; public sidebarOpen = true;
#toggleSidebar = () => { #toggleSidebar = () => {
this.sidebarOpen = !this.sidebarOpen; this.sidebarOpen = !this.sidebarOpen;
}; };
#sidebarMatcher: MediaQueryList; sidebarMatcher = window.matchMedia("(min-width: 1200px)");
#sidebarListener = (event: MediaQueryListEvent) => { #sidebarListener = (event: MediaQueryListEvent) => {
this.sidebarOpen = event.matches; this.sidebarOpen = event.matches;
}; };
@ -133,9 +133,6 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
constructor() { constructor() {
super(); super();
this.ws = new WebsocketClient(); this.ws = new WebsocketClient();
this.#sidebarMatcher = window.matchMedia("(min-width: 1200px)");
this.sidebarOpen = this.#sidebarMatcher.matches;
} }
public connectedCallback() { public connectedCallback() {
@ -157,13 +154,13 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
}); });
}); });
this.#sidebarMatcher.addEventListener("change", this.#sidebarListener); this.sidebarMatcher.addEventListener("change", this.#sidebarListener);
} }
public disconnectedCallback(): void { public disconnectedCallback(): void {
super.disconnectedCallback(); super.disconnectedCallback();
window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar); window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
this.#sidebarMatcher.removeEventListener("change", this.#sidebarListener); this.sidebarMatcher.removeEventListener("change", this.#sidebarListener);
} }
async firstUpdated(): Promise<void> { async firstUpdated(): Promise<void> {

View File

@ -58,9 +58,6 @@ export class AdminOverviewPage extends AdminOverviewBase {
PFContent, PFContent,
PFDivider, PFDivider,
css` css`
.pf-l-grid__item {
height: 100%;
}
.pf-l-grid__item.big-graph-container { .pf-l-grid__item.big-graph-container {
height: 35em; height: 35em;
} }
@ -74,6 +71,10 @@ export class AdminOverviewPage extends AdminOverviewBase {
line-height: normal; line-height: normal;
font-size: var(--pf-global--icon--FontSize--sm); font-size: var(--pf-global--icon--FontSize--sm);
} }
.chart-item {
aspect-ratio: 2 / 1;
}
`, `,
]; ];
} }
@ -104,15 +105,21 @@ export class AdminOverviewPage extends AdminOverviewBase {
</ak-page-header> </ak-page-header>
<section class="pf-c-page__main-section"> <section class="pf-c-page__main-section">
<div class="pf-l-grid pf-m-gutter"> <div class="pf-l-grid pf-m-gutter">
<!-- row 1 --> <div class="pf-l-grid__item pf-m-12-col pf-m-2-row pf-m-9-col-on-xl">
<div <ak-recent-events pageSize="6"></ak-recent-events>
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl pf-l-grid pf-m-gutter" </div>
> <div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-sm pf-m-3-col-on-xl">
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl">
<ak-quick-actions-card .actions=${this.quickActions}> <ak-quick-actions-card .actions=${this.quickActions}>
</ak-quick-actions-card> </ak-quick-actions-card>
</div> </div>
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-4-col-on-2xl">
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-sm pf-m-3-col-on-xl">
<ak-admin-status-version> </ak-admin-status-version>
</div>
<div class="pf-l-grid pf-l-grid__item pf-m-12-col pf-m-gutter">
${this.renderSecondaryRow()}
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-md chart-item">
<ak-aggregate-card <ak-aggregate-card
icon="pf-icon pf-icon-zone" icon="pf-icon pf-icon-zone"
header=${msg("Outpost status")} header=${msg("Outpost status")}
@ -121,24 +128,13 @@ export class AdminOverviewPage extends AdminOverviewBase {
<ak-admin-status-chart-outpost></ak-admin-status-chart-outpost> <ak-admin-status-chart-outpost></ak-admin-status-chart-outpost>
</ak-aggregate-card> </ak-aggregate-card>
</div> </div>
<div <div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-md chart-item">
class="pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-4-col-on-2xl"
>
<ak-aggregate-card icon="fa fa-sync-alt" header=${msg("Sync status")}> <ak-aggregate-card icon="fa fa-sync-alt" header=${msg("Sync status")}>
<ak-admin-status-chart-sync></ak-admin-status-chart-sync> <ak-admin-status-chart-sync></ak-admin-status-chart-sync>
</ak-aggregate-card> </ak-aggregate-card>
</div> </div>
<div class="pf-l-grid__item pf-m-12-col">
<hr class="pf-c-divider" />
</div>
${this.renderCards()}
</div>
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl">
<ak-recent-events pageSize="6"></ak-recent-events>
</div>
<div class="pf-l-grid__item pf-m-12-col">
<hr class="pf-c-divider" />
</div> </div>
<!-- row 3 --> <!-- row 3 -->
<div <div
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-8-col-on-2xl big-graph-container" class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-8-col-on-2xl big-graph-container"
@ -166,32 +162,34 @@ export class AdminOverviewPage extends AdminOverviewBase {
</section>`; </section>`;
} }
renderCards() { renderSecondaryRow() {
const isEnterprise = this.hasEnterpriseLicense; const isEnterprise = this.hasEnterpriseLicense;
const colSpan = isEnterprise ? 4 : 6;
const classes = { const classes = {
"card-container": true, "card-container": true,
"pf-l-grid__item": true, "pf-l-grid__item": true,
"pf-m-6-col": true, [`pf-m-12-col`]: true,
"pf-m-4-col-on-md": !isEnterprise, [`pf-m-${colSpan}-col-on-md`]: true,
"pf-m-4-col-on-xl": !isEnterprise,
"pf-m-3-col-on-md": isEnterprise,
"pf-m-3-col-on-xl": isEnterprise,
}; };
return html`<div class=${classMap(classes)}> return html`
<div class=${classMap(classes)}>
<ak-admin-status-system> </ak-admin-status-system> <ak-admin-status-system> </ak-admin-status-system>
</div> </div>
<div class=${classMap(classes)}>
<ak-admin-status-version> </ak-admin-status-version>
</div>
<div class=${classMap(classes)}> <div class=${classMap(classes)}>
<ak-admin-status-card-workers> </ak-admin-status-card-workers> <ak-admin-status-card-workers> </ak-admin-status-card-workers>
</div> </div>
${isEnterprise ${isEnterprise
? html` <div class=${classMap(classes)}> ? html`
<div class=${classMap(classes)}>
<ak-admin-fips-status-system> </ak-admin-fips-status-system> <ak-admin-fips-status-system> </ak-admin-fips-status-system>
</div>` </div>
: nothing} `; `
: nothing}
`;
} }
renderActions() { renderActions() {

View File

@ -92,9 +92,6 @@ export function normalizeCSSSource(input: StyleSheetInit): CSSResultOrNative {
return input; return input;
} }
/**
* Create a `CSSStyleSheet` from the given input.
*/
export function createStyleSheetUnsafe(input: StyleSheetInit): CSSStyleSheet { export function createStyleSheetUnsafe(input: StyleSheetInit): CSSStyleSheet {
const result = normalizeCSSSource(input); const result = normalizeCSSSource(input);
if (result instanceof CSSStyleSheet) return result; if (result instanceof CSSStyleSheet) return result;
@ -111,82 +108,41 @@ export function createStyleSheetUnsafe(input: StyleSheetInit): CSSStyleSheet {
return result.styleSheet; return result.styleSheet;
} }
/**
* A symbol to indicate that a stylesheet has been adopted by a style parent.
*
* @remarks
* Safari considers stylesheet removed from the `adoptedStyleSheets` array
* ready for garbage collection. Reuse of the stylesheet will result in tab-crash.
*
* Always discard the stylesheet after use.
*/
const StyleSheetAdoptedParent = Symbol("stylesheet-adopted");
/**
* A CSS style sheet that has been adopted by a style parent.
*/
export interface AdoptedStyleSheet extends CSSStyleSheet {
[StyleSheetAdoptedParent]: WeakRef<StyleSheetParent>;
}
/**
* Type-predicate to determine if a given stylesheet has been adopted.
*/
export function isAdoptedStyleSheet(styleSheet: CSSStyleSheet): styleSheet is AdoptedStyleSheet {
if (!(StyleSheetAdoptedParent in styleSheet)) return false;
return styleSheet[StyleSheetAdoptedParent] instanceof WeakRef;
}
/** /**
* Append stylesheet(s) to the given roots. * Append stylesheet(s) to the given roots.
*
* @see {@linkcode removeStyleSheet} to remove a stylesheet from a given roots.
*/ */
export function appendStyleSheet( export function appendStyleSheet(
styleParent: StyleSheetParent, insertions: CSSStyleSheet | Iterable<CSSStyleSheet>,
...insertions: CSSStyleSheet[] ...styleParents: StyleSheetParent[]
): void { ): void {
insertions = Array.isArray(insertions) ? insertions : [insertions]; insertions = Array.isArray(insertions) ? insertions : [insertions];
for (const styleSheetInsertion of insertions) { for (const nextStyleSheet of insertions) {
if (isAdoptedStyleSheet(styleSheetInsertion)) { for (const styleParent of styleParents) {
console.warn("Attempted to append adopted stylesheet", { if (styleParent.adoptedStyleSheets.includes(nextStyleSheet)) return;
styleSheetInsertion,
currentParent: styleSheetInsertion[StyleSheetAdoptedParent]?.deref(),
rules: serializeStyleSheet(styleSheetInsertion),
});
throw new TypeError("Attempted to append a previously adopted stylesheet"); styleParent.adoptedStyleSheets = [...styleParent.adoptedStyleSheets, nextStyleSheet];
} }
if (styleParent.adoptedStyleSheets.includes(styleSheetInsertion)) return;
styleParent.adoptedStyleSheets = [...styleParent.adoptedStyleSheets, styleSheetInsertion];
Object.assign(styleSheetInsertion, {
[StyleSheetAdoptedParent]: new WeakRef(styleParent),
});
} }
} }
/** /**
* Remove a stylesheet from the given roots, matching by referential equality. * Remove a stylesheet from the given roots, matching by referential equality.
*
* @see {@linkcode appendStyleSheet} to append a stylesheet to a given roots.
*/ */
export function removeStyleSheet( export function removeStyleSheet(
styleParent: StyleSheetParent, currentStyleSheet: CSSStyleSheet,
...removals: CSSStyleSheet[] ...styleParents: StyleSheetParent[]
): void { ): void {
for (const styleParent of styleParents) {
const nextAdoptedStyleSheets = styleParent.adoptedStyleSheets.filter( const nextAdoptedStyleSheets = styleParent.adoptedStyleSheets.filter(
(styleSheet) => !removals.includes(styleSheet), (styleSheet) => styleSheet !== currentStyleSheet,
); );
if (nextAdoptedStyleSheets.length === styleParent.adoptedStyleSheets.length) return; if (nextAdoptedStyleSheets.length === styleParent.adoptedStyleSheets.length) return;
styleParent.adoptedStyleSheets = nextAdoptedStyleSheets; styleParent.adoptedStyleSheets = nextAdoptedStyleSheets;
} }
}
/** /**
* Serialize a stylesheet to a string. * Serialize a stylesheet to a string.

View File

@ -67,6 +67,12 @@ export class NavigationButtons extends AKElement {
:host([theme="light"]) .pf-c-page__header-tools-group .pf-c-button { :host([theme="light"]) .pf-c-page__header-tools-group .pf-c-button {
color: var(--ak-global--Color--100) !important; color: var(--ak-global--Color--100) !important;
} }
@media (max-width: 768px) {
.pf-c-avatar {
display: none;
}
}
`, `,
]; ];
} }
@ -95,7 +101,7 @@ export class NavigationButtons extends AKElement {
); );
}; };
return html`<div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-xl"> return html`<div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg">
<button class="pf-c-button pf-m-plain" type="button" @click=${onClick}> <button class="pf-c-button pf-m-plain" type="button" @click=${onClick}>
<pf-tooltip position="top" content=${msg("Open API drawer")}> <pf-tooltip position="top" content=${msg("Open API drawer")}>
<i class="fas fa-code" aria-hidden="true"></i> <i class="fas fa-code" aria-hidden="true"></i>
@ -116,7 +122,7 @@ export class NavigationButtons extends AKElement {
); );
}; };
return html`<div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-xl"> return html`<div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg">
<button <button
class="pf-c-button pf-m-plain" class="pf-c-button pf-m-plain"
type="button" type="button"
@ -175,7 +181,7 @@ export class NavigationButtons extends AKElement {
renderAvatar() { renderAvatar() {
return html`<img return html`<img
class="pf-c-page__header-tools-item pf-c-avatar pf-m-hidden pf-m-visible-on-xl" class="pf-c-avatar"
src=${ifDefined(this.me?.user.avatar)} src=${ifDefined(this.me?.user.avatar)}
alt="${msg("Avatar image")}" alt="${msg("Avatar image")}"
/>`; />`;
@ -212,8 +218,8 @@ export class NavigationButtons extends AKElement {
</div> </div>
${this.renderImpersonation()} ${this.renderImpersonation()}
${this.userDisplayName != "" ${this.userDisplayName != ""
? html`<div class="pf-c-page__header-tools-group pf-m-hidden"> ? html`<div class="pf-c-page__header-tools-group">
<div class="pf-c-page__header-tools-item pf-m-visible-on-2xl"> <div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-md">
${this.userDisplayName} ${this.userDisplayName}
</div> </div>
</div>` </div>`

View File

@ -7,14 +7,7 @@ import {
removeStyleSheet, removeStyleSheet,
resolveStyleSheetParent, resolveStyleSheetParent,
} from "@goauthentik/common/stylesheets"; } from "@goauthentik/common/stylesheets";
import { import { ResolvedUITheme, createUIThemeEffect, resolveUITheme } from "@goauthentik/common/theme";
CSSColorSchemeValue,
ResolvedUITheme,
UIThemeListener,
createUIThemeEffect,
formatColorScheme,
resolveUITheme,
} from "@goauthentik/common/theme";
import { type ThemedElement } from "@goauthentik/common/theme"; import { type ThemedElement } from "@goauthentik/common/theme";
import { localized } from "@lit/localize"; import { localized } from "@lit/localize";
@ -25,15 +18,18 @@ import AKGlobal from "@goauthentik/common/styles/authentik.css";
import OneDark from "@goauthentik/common/styles/one-dark.css"; import OneDark from "@goauthentik/common/styles/one-dark.css";
import ThemeDark from "@goauthentik/common/styles/theme-dark.css"; import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
import { UiThemeEnum } from "@goauthentik/api"; import { CurrentBrand, UiThemeEnum } from "@goauthentik/api";
// Re-export the theme helpers // Re-export the theme helpers
export { rootInterface } from "@goauthentik/common/theme"; export { rootInterface } from "@goauthentik/common/theme";
export interface AKElementInit {
brand?: Partial<CurrentBrand>;
styleParents?: StyleSheetParent[];
}
@localized() @localized()
export class AKElement extends LitElement implements ThemedElement { export class AKElement extends LitElement implements ThemedElement {
//#region Properties
/** /**
* The resolved theme of the current element. * The resolved theme of the current element.
* *
@ -49,19 +45,7 @@ export class AKElement extends LitElement implements ThemedElement {
}) })
public activeTheme: ResolvedUITheme; public activeTheme: ResolvedUITheme;
//#endregion protected static readonly DarkColorSchemeStyleSheet = createStyleSheetUnsafe(ThemeDark);
//#region Private Properties
readonly #preferredColorScheme: CSSColorSchemeValue;
#customCSSStyleSheet: CSSStyleSheet | null;
#darkThemeStyleSheet: CSSStyleSheet | null = null;
#themeAbortController: AbortController | null = null;
//#endregion
//#region Lifecycle
protected static finalizeStyles(styles?: CSSResultGroup): CSSResultOrNative[] { protected static finalizeStyles(styles?: CSSResultGroup): CSSResultOrNative[] {
// Ensure all style sheets being passed are really style sheets. // Ensure all style sheets being passed are really style sheets.
@ -79,62 +63,63 @@ export class AKElement extends LitElement implements ThemedElement {
return [styles, ...baseStyles].map(createStyleSheetUnsafe); return [styles, ...baseStyles].map(createStyleSheetUnsafe);
} }
constructor() { constructor(init?: AKElementInit) {
super(); super();
const { brand } = globalAK(); const config = globalAK();
const { brand = config.brand, styleParents = [] } = init || {};
this.#preferredColorScheme = formatColorScheme(brand.uiTheme);
this.activeTheme = resolveUITheme(brand?.uiTheme); this.activeTheme = resolveUITheme(brand?.uiTheme);
this.#styleParents = styleParents;
this.#customCSSStyleSheet = brand?.brandingCustomCss this.#customCSSStyleSheet = brand?.brandingCustomCss
? createStyleSheetUnsafe(brand.brandingCustomCss) ? createStyleSheetUnsafe(brand.brandingCustomCss)
: null; : null;
} }
#styleParents: StyleSheetParent[] = [];
#customCSSStyleSheet: CSSStyleSheet | null;
#themeAbortController: AbortController | null = null;
public disconnectedCallback(): void { public disconnectedCallback(): void {
super.disconnectedCallback(); super.disconnectedCallback();
this.#themeAbortController?.abort(); this.#themeAbortController?.abort();
} }
#styleRoot?: StyleSheetParent;
#dispatchTheme: UIThemeListener = (nextUITheme) => {
if (!this.#styleRoot) return;
if (nextUITheme === UiThemeEnum.Dark) {
this.#darkThemeStyleSheet ||= createStyleSheetUnsafe(ThemeDark);
appendStyleSheet(this.#styleRoot, this.#darkThemeStyleSheet);
this.activeTheme = UiThemeEnum.Dark;
} else if (this.#darkThemeStyleSheet) {
removeStyleSheet(this.#styleRoot, this.#darkThemeStyleSheet);
this.#darkThemeStyleSheet = null;
this.activeTheme = UiThemeEnum.Light;
}
};
protected createRenderRoot(): HTMLElement | DocumentFragment { protected createRenderRoot(): HTMLElement | DocumentFragment {
const renderRoot = super.createRenderRoot(); const renderRoot = super.createRenderRoot();
this.#styleRoot = resolveStyleSheetParent(renderRoot);
const styleRoot = resolveStyleSheetParent(renderRoot);
const styleParents = Array.from(
new Set<StyleSheetParent>([styleRoot, ...this.#styleParents]),
);
if (this.#customCSSStyleSheet) { if (this.#customCSSStyleSheet) {
console.debug(`authentik/element[${this.tagName.toLowerCase()}]: Adding custom CSS`); console.debug(`authentik/element[${this.tagName.toLowerCase()}]: Adding custom CSS`);
appendStyleSheet(this.#styleRoot, this.#customCSSStyleSheet); styleRoot.adoptedStyleSheets = [
...styleRoot.adoptedStyleSheets,
this.#customCSSStyleSheet,
];
} }
this.#themeAbortController = new AbortController(); this.#themeAbortController = new AbortController();
if (this.#preferredColorScheme === "dark") { createUIThemeEffect(
this.#dispatchTheme(UiThemeEnum.Dark); (currentUITheme) => {
} else if (this.#preferredColorScheme === "auto") { if (currentUITheme === UiThemeEnum.Dark) {
createUIThemeEffect(this.#dispatchTheme, { appendStyleSheet(AKElement.DarkColorSchemeStyleSheet, ...styleParents);
signal: this.#themeAbortController.signal, } else {
}); removeStyleSheet(AKElement.DarkColorSchemeStyleSheet, ...styleParents);
} }
this.activeTheme = currentUITheme;
},
{
signal: this.#themeAbortController.signal,
},
);
return renderRoot; return renderRoot;
} }
//#endregion
} }

View File

@ -5,7 +5,7 @@ import {
} from "@goauthentik/common/stylesheets"; } from "@goauthentik/common/stylesheets";
import { ThemedElement } from "@goauthentik/common/theme"; import { ThemedElement } from "@goauthentik/common/theme";
import { UIConfig } from "@goauthentik/common/ui/config"; import { UIConfig } from "@goauthentik/common/ui/config";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement, AKElementInit } from "@goauthentik/elements/Base";
import { VersionContextController } from "@goauthentik/elements/Interface/VersionContextController"; import { VersionContextController } from "@goauthentik/elements/Interface/VersionContextController";
import { ModalOrchestrationController } from "@goauthentik/elements/controllers/ModalOrchestrationController.js"; import { ModalOrchestrationController } from "@goauthentik/elements/controllers/ModalOrchestrationController.js";
@ -19,6 +19,7 @@ import { BrandContextController } from "./BrandContextController";
import { ConfigContextController } from "./ConfigContextController"; import { ConfigContextController } from "./ConfigContextController";
import { EnterpriseContextController } from "./EnterpriseContextController"; import { EnterpriseContextController } from "./EnterpriseContextController";
const brandContext = Symbol("brandContext");
const configContext = Symbol("configContext"); const configContext = Symbol("configContext");
const modalController = Symbol("modalController"); const modalController = Symbol("modalController");
const versionContext = Symbol("versionContext"); const versionContext = Symbol("versionContext");
@ -26,6 +27,8 @@ const versionContext = Symbol("versionContext");
export abstract class Interface extends AKElement implements ThemedElement { export abstract class Interface extends AKElement implements ThemedElement {
protected static readonly PFBaseStyleSheet = createStyleSheetUnsafe(PFBase); protected static readonly PFBaseStyleSheet = createStyleSheetUnsafe(PFBase);
[brandContext]: BrandContextController;
[configContext]: ConfigContextController; [configContext]: ConfigContextController;
[modalController]: ModalOrchestrationController; [modalController]: ModalOrchestrationController;
@ -36,15 +39,19 @@ export abstract class Interface extends AKElement implements ThemedElement {
@state() @state()
public brand?: CurrentBrand; public brand?: CurrentBrand;
constructor() { constructor({ styleParents = [], ...init }: AKElementInit = {}) {
super();
const styleParent = resolveStyleSheetParent(document); const styleParent = resolveStyleSheetParent(document);
super({
...init,
styleParents: [styleParent, ...styleParents],
});
this.dataset.akInterfaceRoot = this.tagName.toLowerCase(); this.dataset.akInterfaceRoot = this.tagName.toLowerCase();
appendStyleSheet(styleParent, Interface.PFBaseStyleSheet); appendStyleSheet(Interface.PFBaseStyleSheet, styleParent);
this.addController(new BrandContextController(this)); this[brandContext] = new BrandContextController(this);
this[configContext] = new ConfigContextController(this); this[configContext] = new ConfigContextController(this);
this[modalController] = new ModalOrchestrationController(this); this[modalController] = new ModalOrchestrationController(this);
} }
@ -70,8 +77,8 @@ export class AuthenticatedInterface extends Interface implements AkAuthenticated
@state() @state()
public version?: Version; public version?: Version;
constructor() { constructor(init?: AKElementInit) {
super(); super(init);
this[enterpriseContext] = new EnterpriseContextController(this); this[enterpriseContext] = new EnterpriseContextController(this);
this[versionContext] = new VersionContextController(this); this[versionContext] = new VersionContextController(this);

View File

@ -89,7 +89,6 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
--ak-brand-background-color: var( --ak-brand-background-color: var(
--pf-c-page__sidebar--m-light--BackgroundColor --pf-c-page__sidebar--m-light--BackgroundColor
); );
--host-navbar-height: var(--ak-c-page-header--height, 7.5rem);
} }
:host([theme="dark"]) { :host([theme="dark"]) {
@ -106,6 +105,7 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
display: flex; display: flex;
flex-direction: row; flex-direction: row;
min-height: 6rem;
display: grid; display: grid;
row-gap: var(--pf-global--spacer--sm); row-gap: var(--pf-global--spacer--sm);
@ -116,10 +116,6 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
"brand toggle primary secondary" "brand toggle primary secondary"
"brand toggle description secondary"; "brand toggle description secondary";
@media (min-width: 426px) {
height: var(--host-navbar-height);
}
@media (max-width: 768px) { @media (max-width: 768px) {
row-gap: var(--pf-global--spacer--xs); row-gap: var(--pf-global--spacer--xs);
@ -165,15 +161,7 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
&.page-description { &.page-description {
grid-area: description; grid-area: description;
margin-block-end: var(--pf-global--spacer--md); padding-block-end: var(--pf-global--spacer--md);
display: box;
display: -webkit-box;
line-clamp: 2;
-webkit-line-clamp: 2;
box-orient: vertical;
-webkit-box-orient: vertical;
overflow: hidden;
@media (max-width: 425px) { @media (max-width: 425px) {
display: none; display: none;

View File

@ -80,6 +80,7 @@ export class AggregateCard extends AKElement implements IAggregateCard {
.center-value { .center-value {
font-size: var(--pf-global--icon--FontSize--lg); font-size: var(--pf-global--icon--FontSize--lg);
text-align: center; text-align: center;
place-content: center;
} }
.subtext { .subtext {
margin-top: var(--pf-global--spacer--sm); margin-top: var(--pf-global--spacer--sm);

View File

@ -1,7 +1,6 @@
import { import {
appendStyleSheet, appendStyleSheet,
assertAdoptableStyleSheetParent, assertAdoptableStyleSheetParent,
createStyleSheetUnsafe,
} from "@goauthentik/common/stylesheets.js"; } from "@goauthentik/common/stylesheets.js";
import { TemplateResult, render as litRender } from "lit"; import { TemplateResult, render as litRender } from "lit";
@ -16,6 +15,6 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
export const render = (body: TemplateResult) => { export const render = (body: TemplateResult) => {
assertAdoptableStyleSheetParent(document); assertAdoptableStyleSheetParent(document);
appendStyleSheet(document, ...[PFBase, AKGlobal].map(createStyleSheetUnsafe)); appendStyleSheet([PFBase, AKGlobal], document);
return litRender(body, document.body); return litRender(body, document.body);
}; };