import { Middleware, ResponseContext } from "authentik-api"; import { css, CSSResult, customElement, html, LitElement, property, TemplateResult, } from "lit-element"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFNotificationDrawer from "@patternfly/patternfly/components/NotificationDrawer/notification-drawer.css"; import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css"; import AKGlobal from "../../authentik.css"; import { t } from "@lingui/macro"; import { EVENT_API_DRAWER_REFRESH, EVENT_API_DRAWER_TOGGLE } from "../../constants"; export interface RequestInfo { method: string; path: string; status: number; } export class APIMiddleware implements Middleware { post?(context: ResponseContext): Promise { const request: RequestInfo = { method: (context.init.method || "GET").toUpperCase(), path: context.url, status: context.response.status, }; window.dispatchEvent( new CustomEvent(EVENT_API_DRAWER_REFRESH, { bubbles: true, composed: true, detail: request, }), ); return Promise.resolve(context.response); } } @customElement("ak-api-drawer") export class APIDrawer extends LitElement { @property({ attribute: false }) requests: RequestInfo[] = []; static get styles(): CSSResult[] { return [ PFBase, PFNotificationDrawer, PFButton, PFContent, PFDropdown, AKGlobal, css` .pf-c-notification-drawer__header { height: 114px; align-items: center; } .pf-c-notification-drawer__header-action, .pf-c-notification-drawer__header-action-close, .pf-c-notification-drawer__header-action-close > .pf-c-button.pf-m-plain { height: 100%; } .pf-c-notification-drawer__list-item-description { white-space: pre-wrap; font-family: monospace; } `, ]; } constructor() { super(); window.addEventListener(EVENT_API_DRAWER_REFRESH, ((e: CustomEvent) => { this.requests.splice(0, 0, e.detail); if (this.requests.length > 50) { this.requests.shift(); } this.requestUpdate(); }) as EventListener); } renderItem(item: RequestInfo): TemplateResult { return html`
  • ${item.method}: ${item.status}

    ${item.path}
  • `; } render(): TemplateResult { return html`

    ${t`API Requests`}

      ${this.requests.map((n) => this.renderItem(n))}
    `; } }