web/admin: fix flow diagram not updating on flow changes

closes #2932

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-05-23 19:48:33 +02:00
parent 7895d59da3
commit b2a42a68a4
3 changed files with 691 additions and 811 deletions

View File

@ -8,7 +8,7 @@ import AKGlobal from "../authentik.css";
import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css"; import PFTabs from "@patternfly/patternfly/components/Tabs/tabs.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css"; import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import { CURRENT_CLASS, ROUTE_SEPARATOR } from "../constants"; import { CURRENT_CLASS, EVENT_REFRESH, ROUTE_SEPARATOR } from "../constants";
import { getURLParams, updateURLParams } from "./router/RouteMatch"; import { getURLParams, updateURLParams } from "./router/RouteMatch";
@customElement("ak-tabs") @customElement("ak-tabs")
@ -72,6 +72,14 @@ export class Tabs extends LitElement {
const params: { [key: string]: string | undefined } = {}; const params: { [key: string]: string | undefined } = {};
params[this.pageIdentifier] = slot; params[this.pageIdentifier] = slot;
updateURLParams(params); updateURLParams(params);
const page = this.querySelector(`[slot='${this.currentPage}']`);
if (!page) return;
page.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
}),
);
} }
renderTab(page: Element): TemplateResult { renderTab(page: Element): TemplateResult {
@ -90,7 +98,7 @@ export class Tabs extends LitElement {
if (this.pageIdentifier in params) { if (this.pageIdentifier in params) {
if (this.querySelector(`[slot='${params[this.pageIdentifier]}']`) !== null) { if (this.querySelector(`[slot='${params[this.pageIdentifier]}']`) !== null) {
// To update the URL to match with the current slot // To update the URL to match with the current slot
this.currentPage = params[this.pageIdentifier]; this.currentPage = params[this.pageIdentifier] as string;
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import { FlowsApi } from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../api/Config"; import { DEFAULT_CONFIG } from "../../api/Config";
import { EVENT_REFRESH } from "../../constants"; import { EVENT_REFRESH } from "../../constants";
import { loading } from "../../utils"; import "../../elements/EmptyState";
export const FONT_COLOUR_DARK_MODE = "#fafafa"; export const FONT_COLOUR_DARK_MODE = "#fafafa";
export const FONT_COLOUR_LIGHT_MODE = "#151515"; export const FONT_COLOUR_LIGHT_MODE = "#151515";
@ -21,17 +21,19 @@ export class FlowDiagram extends LitElement {
@property() @property()
set flowSlug(value: string) { set flowSlug(value: string) {
this._flowSlug = value; this._flowSlug = value;
this.diagram = undefined;
new FlowsApi(DEFAULT_CONFIG) new FlowsApi(DEFAULT_CONFIG)
.flowsInstancesDiagramRetrieve({ .flowsInstancesDiagramRetrieve({
slug: value, slug: value,
}) })
.then((data) => { .then((data) => {
this.diagram = FlowChart.parse(data.diagram || ""); this.diagram = data.diagram;
this.requestUpdate();
}); });
} }
@property({ attribute: false }) @property({ attribute: false })
diagram?: FlowChart.Instance; diagram?: string;
@property() @property()
fontColour: string = FONT_COLOUR_DARK_MODE; fontColour: string = FONT_COLOUR_DARK_MODE;
@ -39,16 +41,19 @@ export class FlowDiagram extends LitElement {
@property() @property()
fill: string = FILL_DARK_MODE; fill: string = FILL_DARK_MODE;
handlerBound = false;
createRenderRoot(): Element | ShadowRoot { createRenderRoot(): Element | ShadowRoot {
return this; return this;
} }
get isInViewport(): boolean {
const rect = this.getBoundingClientRect();
return !(rect.x + rect.y + rect.width + rect.height === 0);
}
constructor() { constructor() {
super(); super();
this.addEventListener(EVENT_REFRESH, () => {
if (!this._flowSlug) return;
this.flowSlug = this._flowSlug;
});
const matcher = window.matchMedia("(prefers-color-scheme: light)"); const matcher = window.matchMedia("(prefers-color-scheme: light)");
const handler = (ev?: MediaQueryListEvent) => { const handler = (ev?: MediaQueryListEvent) => {
if (ev?.matches || matcher.matches) { if (ev?.matches || matcher.matches) {
@ -64,9 +69,33 @@ export class FlowDiagram extends LitElement {
handler(); handler();
} }
firstUpdated(): void {
if (this.handlerBound) return;
window.addEventListener(EVENT_REFRESH, this.refreshHandler);
this.handlerBound = true;
}
refreshHandler = (): void => {
if (!this._flowSlug) return;
this.flowSlug = this._flowSlug;
};
disconnectedCallback(): void {
super.disconnectedCallback();
window.removeEventListener(EVENT_REFRESH, this.refreshHandler);
}
render(): TemplateResult { render(): TemplateResult {
this.querySelectorAll("*").forEach((el) => {
try {
el.remove();
} catch {
console.debug(`authentik/flow/diagram: failed to remove element ${el}`);
}
});
if (this.diagram) { if (this.diagram) {
this.diagram.drawSVG(this, { const diagram = FlowChart.parse(this.diagram);
diagram.drawSVG(this, {
"font-color": this.fontColour, "font-color": this.fontColour,
"line-color": "#bebebe", "line-color": "#bebebe",
"element-color": "#bebebe", "element-color": "#bebebe",
@ -76,6 +105,6 @@ export class FlowDiagram extends LitElement {
}); });
return html``; return html``;
} }
return loading(this.diagram, html``); return html`<ak-empty-state ?loading=${true}></ak-empty-state>`;
} }
} }