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:
@ -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>
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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 },
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user