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 {
EVENT_API_DRAWER_TOGGLE,
EVENT_NOTIFICATION_DRAWER_TOGGLE,
EVENT_SIDEBAR_TOGGLE,
} from "@goauthentik/common/constants";
import { configureSentry } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users";
@ -26,7 +25,7 @@ import "@goauthentik/elements/sidebar/Sidebar";
import "@goauthentik/elements/sidebar/SidebarItem";
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 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 { SidebarToggleEventDetail } from "../../elements/PageHeader.js";
import {
AdminSidebarEnterpriseEntries,
AdminSidebarEntries,
@ -52,28 +52,33 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
//#region Properties
@property({ type: Boolean })
notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
public notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
@property({ type: Boolean })
apiDrawerOpen = getURLParam("apiDrawerOpen", false);
public apiDrawerOpen = getURLParam("apiDrawerOpen", false);
ws: WebsocketClient;
protected readonly ws: WebsocketClient;
@state()
user?: SessionUser;
@property({
type: Object,
attribute: false,
reflect: false,
})
public user?: SessionUser;
@query("ak-about-modal")
aboutModal?: AboutModal;
public aboutModal?: AboutModal;
@property({ type: Boolean, reflect: true })
public sidebarOpen: boolean;
#toggleSidebar = () => {
this.sidebarOpen = !this.sidebarOpen;
};
@eventOptions({ passive: true })
protected sidebarListener(event: CustomEvent<SidebarToggleEventDetail>) {
this.sidebarOpen = !!event.detail.open;
}
#sidebarMatcher: MediaQueryList;
#sidebarListener = (event: MediaQueryListEvent) => {
#sidebarMediaQueryListener = (event: MediaQueryListEvent) => {
this.sidebarOpen = event.matches;
};
@ -141,8 +146,6 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
public connectedCallback() {
super.connectedCallback();
window.addEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => {
this.notificationDrawerOpen = !this.notificationDrawerOpen;
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 {
super.disconnectedCallback();
window.removeEventListener(EVENT_SIDEBAR_TOGGLE, this.#toggleSidebar);
this.#sidebarMatcher.removeEventListener("change", this.#sidebarListener);
this.#sidebarMatcher.removeEventListener("change", this.#sidebarMediaQueryListener);
}
async firstUpdated(): Promise<void> {
@ -196,7 +200,7 @@ export class AdminInterface extends WithLicenseSummary(AuthenticatedInterface) {
return html` <ak-locale-context>
<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-enterprise-status interface="admin"></ak-enterprise-status>
</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_API_DRAWER_TOGGLE = "ak-api-drawer-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_FLOW_ADVANCE = "ak-flow-advance";
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);
}
.pf-c-button.pf-m-plain:hover {
color: var(--ak-dark-foreground);
.pf-c-button.pf-m-plain {
--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 {

View File

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