import "#admin/AdminInterface/AboutModal"; import type { AboutModal } from "#admin/AdminInterface/AboutModal"; import { adminCommands } from "#admin/AdminInterface/AdminCommands"; import { ROUTES } from "#admin/Routes"; import { EVENT_API_DRAWER_TOGGLE, EVENT_NOTIFICATION_DRAWER_TOGGLE } from "#common/constants"; import { configureSentry } from "#common/sentry/index"; import { me } from "#common/users"; import { WebsocketClient } from "#common/ws"; import { SidebarToggleEventDetail } from "#components/ak-page-header"; import { AuthenticatedInterface } from "#elements/AuthenticatedInterface"; import "#elements/ak-locale-context/ak-locale-context"; import "#elements/banner/EnterpriseStatusBanner"; import "#elements/banner/EnterpriseStatusBanner"; import "#elements/banner/VersionBanner"; import "#elements/banner/VersionBanner"; import "#elements/messages/MessageContainer"; import "#elements/messages/MessageContainer"; import { WithCapabilitiesConfig } from "#elements/mixins/capabilities"; import "#elements/notifications/APIDrawer"; import "#elements/notifications/NotificationDrawer"; import { getURLParam, updateURLParams } from "#elements/router/RouteMatch"; import "#elements/router/RouterOutlet"; import "#elements/sidebar/Sidebar"; import "#elements/sidebar/SidebarItem"; import "ninja-keys"; import { CSSResult, TemplateResult, css, html, nothing } from "lit"; 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"; import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css"; import PFNav from "@patternfly/patternfly/components/Nav/nav.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; import { CapabilitiesEnum, SessionUser, UiThemeEnum } from "@goauthentik/api"; import { AdminSidebarEnterpriseEntries, AdminSidebarEntries, renderSidebarItems, } from "./AdminSidebar.js"; if (process.env.NODE_ENV === "development") { await import("@goauthentik/esbuild-plugin-live-reload/client"); } @customElement("ak-interface-admin") export class AdminInterface extends WithCapabilitiesConfig(AuthenticatedInterface) { //#region Properties @property({ type: Boolean }) public notificationDrawerOpen = getURLParam("notificationDrawerOpen", false); @property({ type: Boolean }) public apiDrawerOpen = getURLParam("apiDrawerOpen", false); protected readonly ws: WebsocketClient; @property({ type: Object, attribute: false }) public user?: SessionUser; @query("ak-about-modal") public aboutModal?: AboutModal; @property({ type: Boolean, reflect: true }) public sidebarOpen = false; @eventOptions({ passive: true }) protected sidebarListener(event: CustomEvent) { this.sidebarOpen = !!event.detail.open; } #sidebarMatcher: MediaQueryList; #sidebarMediaQueryListener = (event: MediaQueryListEvent) => { this.sidebarOpen = event.matches; }; //#endregion //#region Styles static styles: CSSResult[] = [ PFBase, PFPage, PFButton, PFDrawer, PFNav, css` .pf-c-page__main, .pf-c-drawer__content, .pf-c-page__drawer { z-index: auto !important; background-color: transparent; } .display-none { display: none; } .pf-c-page { background-color: var(--pf-c-page--BackgroundColor) !important; } :host([theme="dark"]) { /* Global page background colour */ .pf-c-page { --pf-c-page--BackgroundColor: var(--ak-dark-background); } } ak-page-navbar { grid-area: header; } .ak-sidebar { grid-area: nav; } .pf-c-drawer__panel { z-index: var(--pf-global--ZIndex--xl); } ninja-keys { --ninja-z-index: 99999; --ninja-accent-color: var(--ak-accent); } `, ]; //#endregion //#region Lifecycle constructor() { configureSentry(true); super(); this.ws = new WebsocketClient(); this.#sidebarMatcher = window.matchMedia("(min-width: 1200px)"); this.sidebarOpen = this.#sidebarMatcher.matches; } public connectedCallback() { super.connectedCallback(); window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => { this.notificationDrawerOpen = !this.notificationDrawerOpen; updateURLParams({ notificationDrawerOpen: this.notificationDrawerOpen, }); }); window.addEventListener(EVENT_API_DRAWER_TOGGLE, () => { this.apiDrawerOpen = !this.apiDrawerOpen; updateURLParams({ apiDrawerOpen: this.apiDrawerOpen, }); }); this.#sidebarMatcher.addEventListener("change", this.#sidebarMediaQueryListener, { passive: true, }); } public disconnectedCallback(): void { super.disconnectedCallback(); this.#sidebarMatcher.removeEventListener("change", this.#sidebarMediaQueryListener); } async firstUpdated(): Promise { this.user = await me(); const canAccessAdmin = this.user.user.isSuperuser || // TODO: somehow add `access_admin_interface` to the API schema this.user.user.systemPermissions.includes("access_admin_interface"); if (!canAccessAdmin && this.user.user.pk > 0) { window.location.assign("/if/user/"); } } render(): TemplateResult { const sidebarClasses = { "pf-c-page__sidebar": true, "pf-m-light": this.activeTheme === UiThemeEnum.Light, "pf-m-expanded": this.sidebarOpen, "pf-m-collapsed": !this.sidebarOpen, }; const drawerOpen = this.notificationDrawerOpen || this.apiDrawerOpen; const drawerClasses = { "pf-m-expanded": drawerOpen, "pf-m-collapsed": !drawerOpen, }; return html`
${renderSidebarItems(AdminSidebarEntries)} ${this.can(CapabilitiesEnum.IsEnterprise) ? renderSidebarItems(AdminSidebarEnterpriseEntries) : nothing}
`; } } declare global { interface HTMLElementTagNameMap { "ak-interface-admin": AdminInterface; } }