This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/web/src/elements/Diagram.ts

93 lines
2.7 KiB
TypeScript

import { EVENT_REFRESH, EVENT_THEME_CHANGE } from "@goauthentik/common/constants";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/EmptyState";
import mermaid, { MermaidConfig } from "mermaid";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { until } from "lit/directives/until.js";
import { UiThemeEnum } from "@goauthentik/api";
@customElement("ak-diagram")
export class Diagram extends AKElement {
@property({ attribute: false })
diagram?: string;
refreshHandler = (): void => {
if (!this.textContent) return;
this.diagram = this.textContent;
};
handlerBound = false;
static get styles(): CSSResult[] {
return [
css`
:host {
display: flex;
justify-content: center;
}
`,
];
}
config: MermaidConfig;
constructor() {
super();
this.config = {
// The type definition for this says number
// but the example use strings
// and numbers don't work
logLevel: "fatal" as unknown as number,
startOnLoad: false,
flowchart: {
curve: "linear",
},
htmlLabels: false,
};
mermaid.initialize(this.config);
}
firstUpdated(): void {
if (this.handlerBound) return;
window.addEventListener(EVENT_REFRESH, this.refreshHandler);
this.addEventListener(EVENT_THEME_CHANGE, ((ev: CustomEvent<UiThemeEnum>) => {
if (ev.detail === UiThemeEnum.Dark) {
this.config.theme = "dark";
} else {
this.config.theme = "default";
}
mermaid.initialize(this.config);
}) as EventListener);
this.handlerBound = true;
this.refreshHandler();
}
disconnectedCallback(): void {
super.disconnectedCallback();
window.removeEventListener(EVENT_REFRESH, this.refreshHandler);
}
render(): TemplateResult {
this.querySelectorAll("*").forEach((el) => {
try {
el.remove();
} catch {
console.debug(`authentik/diagram: failed to remove element ${el}`);
}
});
if (!this.diagram) {
return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
}
return html`${until(
mermaid.render("graph", this.diagram).then((r) => {
r.bindFunctions?.(this.shadowRoot as unknown as Element);
return unsafeHTML(r.svg);
}),
)}`;
}
}