web/admin: Fix sidebar toggle synchronization. (#14487)

* web: Fix issue where resizing from tablet or smaller viewport desyncs the sidebar.

* web: Fix issue where focus style overrides hover state style.
This commit is contained in:
Teffen Ellis
2025-05-14 17:19:22 +02:00
committed by GitHub
parent ad4a765a80
commit ca96b27825
4 changed files with 55 additions and 37 deletions

View File

@ -4,7 +4,6 @@ import { ROUTES } from "@goauthentik/admin/Routes";
import { import {
EVENT_API_DRAWER_TOGGLE, EVENT_API_DRAWER_TOGGLE,
EVENT_NOTIFICATION_DRAWER_TOGGLE, EVENT_NOTIFICATION_DRAWER_TOGGLE,
EVENT_SIDEBAR_TOGGLE,
} from "@goauthentik/common/constants"; } from "@goauthentik/common/constants";
import { configureSentry } from "@goauthentik/common/sentry"; import { configureSentry } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users"; import { me } from "@goauthentik/common/users";
@ -26,7 +25,7 @@ import "@goauthentik/elements/sidebar/Sidebar";
import "@goauthentik/elements/sidebar/SidebarItem"; import "@goauthentik/elements/sidebar/SidebarItem";
import { CSSResult, TemplateResult, css, html, nothing } from "lit"; import { CSSResult, TemplateResult, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators.js"; import { customElement, eventOptions, property, query } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js"; import { classMap } from "lit/directives/class-map.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -37,6 +36,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { LicenseSummaryStatusEnum, SessionUser, UiThemeEnum } from "@goauthentik/api"; import { LicenseSummaryStatusEnum, SessionUser, UiThemeEnum } from "@goauthentik/api";
import { SidebarToggleEventDetail } from "../../elements/PageHeader.js";
import { import {
AdminSidebarEnterpriseEntries, AdminSidebarEnterpriseEntries,
AdminSidebarEntries, AdminSidebarEntries,
@ -52,28 +52,33 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
//#region Properties //#region Properties
@property({ type: Boolean }) @property({ type: Boolean })
notificationDrawerOpen = getURLParam("notificationDrawerOpen", false); public notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
@property({ type: Boolean }) @property({ type: Boolean })
apiDrawerOpen = getURLParam("apiDrawerOpen", false); public apiDrawerOpen = getURLParam("apiDrawerOpen", false);
ws: WebsocketClient; protected readonly ws: WebsocketClient;
@state() @property({
user?: SessionUser; type: Object,
attribute: false,
reflect: false,
})
public user?: SessionUser;
@query("ak-about-modal") @query("ak-about-modal")
aboutModal?: AboutModal; public aboutModal?: AboutModal;
@property({ type: Boolean, reflect: true }) @property({ type: Boolean, reflect: true })
public sidebarOpen: boolean; public sidebarOpen: boolean;
#toggleSidebar = () => { @eventOptions({ passive: true })
this.sidebarOpen = !this.sidebarOpen; protected sidebarListener(event: CustomEvent<SidebarToggleEventDetail>) {
}; this.sidebarOpen = !!event.detail.open;
}
#sidebarMatcher: MediaQueryList; #sidebarMatcher: MediaQueryList;
#sidebarListener = (event: MediaQueryListEvent) => { #sidebarMediaQueryListener = (event: MediaQueryListEvent) => {
this.sidebarOpen = event.matches; this.sidebarOpen = event.matches;
}; };
@ -141,8 +146,6 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
public connectedCallback() { public connectedCallback() {
super.connectedCallback(); super.connectedCallback();
window.addEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => { window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => {
this.notificationDrawerOpen = !this.notificationDrawerOpen; this.notificationDrawerOpen = !this.notificationDrawerOpen;
updateURLParams({ updateURLParams({
@ -157,13 +160,14 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
}); });
}); });
this.#sidebarMatcher.addEventListener("change", this.#sidebarListener); this.#sidebarMatcher.addEventListener("change", this.#sidebarMediaQueryListener, {
passive: true,
});
} }
public disconnectedCallback(): void { public disconnectedCallback(): void {
super.disconnectedCallback(); super.disconnectedCallback();
window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar); this.#sidebarMatcher.removeEventListener("change", this.#sidebarMediaQueryListener);
this.#sidebarMatcher.removeEventListener("change", this.#sidebarListener);
} }
async firstUpdated(): Promise<void> { async firstUpdated(): Promise<void> {
@ -196,7 +200,7 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
return html` <ak-locale-context> return html` <ak-locale-context>
<div class="pf-c-page"> <div class="pf-c-page">
<ak-page-navbar> <ak-page-navbar ?open=${this.sidebarOpen} @sidebar-toggle=${this.sidebarListener}>
<ak-version-banner></ak-version-banner> <ak-version-banner></ak-version-banner>
<ak-enterprise-status interface="admin"></ak-enterprise-status> <ak-enterprise-status interface="admin"></ak-enterprise-status>
</ak-page-navbar> </ak-page-navbar>

View File

@ -11,7 +11,6 @@ export const EVENT_REFRESH = "ak-refresh";
export const EVENT_NOTIFICATION_DRAWER_TOGGLE = "ak-notification-toggle"; export const EVENT_NOTIFICATION_DRAWER_TOGGLE = "ak-notification-toggle";
export const EVENT_API_DRAWER_TOGGLE = "ak-api-drawer-toggle"; export const EVENT_API_DRAWER_TOGGLE = "ak-api-drawer-toggle";
export const EVENT_FLOW_INSPECTOR_TOGGLE = "ak-flow-inspector-toggle"; export const EVENT_FLOW_INSPECTOR_TOGGLE = "ak-flow-inspector-toggle";
export const EVENT_SIDEBAR_TOGGLE = "ak-sidebar-toggle";
export const EVENT_WS_MESSAGE = "ak-ws-message"; export const EVENT_WS_MESSAGE = "ak-ws-message";
export const EVENT_FLOW_ADVANCE = "ak-flow-advance"; export const EVENT_FLOW_ADVANCE = "ak-flow-advance";
export const EVENT_LOCALE_CHANGE = "ak-locale-change"; export const EVENT_LOCALE_CHANGE = "ak-locale-change";

View File

@ -256,8 +256,13 @@ input[type="date"]::-webkit-calendar-picker-indicator {
color: var(--ak-dark-background-lighter); color: var(--ak-dark-background-lighter);
} }
.pf-c-button.pf-m-plain:hover { .pf-c-button.pf-m-plain {
color: var(--ak-dark-foreground); --pf-c-button--m-plain--focus--Color: var(--pf-global--Color--200);
--pf-c-button--m-plain--hover--Color: var(--ak-dark-foreground);
&:focus:hover {
color: var(--pf-c-button--m-plain--hover--Color);
}
} }
.pf-c-button.pf-m-control { .pf-c-button.pf-m-control {

View File

@ -1,8 +1,4 @@
import { import { EVENT_WS_MESSAGE, TITLE_DEFAULT } from "@goauthentik/common/constants";
EVENT_SIDEBAR_TOGGLE,
EVENT_WS_MESSAGE,
TITLE_DEFAULT,
} from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global"; import { globalAK } from "@goauthentik/common/global";
import { UIConfig, UserDisplay, getConfigForUser } from "@goauthentik/common/ui/config"; import { UIConfig, UserDisplay, getConfigForUser } from "@goauthentik/common/ui/config";
import { DefaultBrand } from "@goauthentik/common/ui/config"; import { DefaultBrand } from "@goauthentik/common/ui/config";
@ -29,6 +25,14 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { SessionUser } from "@goauthentik/api"; import { SessionUser } from "@goauthentik/api";
//#region Events
export interface SidebarToggleEventDetail {
open?: boolean;
}
//#endregion
//#region Page Navbar //#region Page Navbar
export interface PageNavbarDetails { export interface PageNavbarDetails {
@ -45,7 +49,10 @@ export interface PageNavbarDetails {
* dispatched by the `ak-page-header` component. * dispatched by the `ak-page-header` component.
*/ */
@customElement("ak-page-navbar") @customElement("ak-page-navbar")
export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavbarDetails { export class AKPageNavbar
extends WithBrandConfig(AKElement)
implements PageNavbarDetails, SidebarToggleEventDetail
{
//#region Static Properties //#region Static Properties
private static elementRef: AKPageNavbar | null = null; private static elementRef: AKPageNavbar | null = null;
@ -260,29 +267,31 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
//#region Properties //#region Properties
@property({ type: String }) @state()
icon?: string; icon?: string;
@property({ type: Boolean }) @state()
iconImage = false; iconImage = false;
@property({ type: String }) @state()
header?: string; header?: string;
@property({ type: String }) @state()
description?: string; description?: string;
@property({ type: Boolean }) @state()
hasIcon = true; hasIcon = true;
@property({ type: Boolean }) @property({
open = true; type: Boolean,
})
public open?: boolean;
@state() @state()
session?: SessionUser; protected session?: SessionUser;
@state() @state()
uiConfig!: UIConfig; protected uiConfig!: UIConfig;
//#endregion //#endregion
@ -305,9 +314,10 @@ export class AKPageNavbar extends WithBrandConfig(AKElement) implements PageNavb
this.open = !this.open; this.open = !this.open;
this.dispatchEvent( this.dispatchEvent(
new CustomEvent(EVENT_SIDEBAR_TOGGLE, { new CustomEvent<SidebarToggleEventDetail>("sidebar-toggle", {
bubbles: true, bubbles: true,
composed: true, composed: true,
detail: { open: this.open },
}), }),
); );
} }