web/elements: add loading spinner for charts, render middle text with css

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2023-02-19 20:10:37 +01:00
parent a68fa06ff9
commit 99baf1a29e
No known key found for this signature in database

View file

@ -1,5 +1,6 @@
import { EVENT_REFRESH } from "@goauthentik/common/constants"; import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/EmptyState";
import { import {
Chart, Chart,
ChartConfiguration, ChartConfiguration,
@ -20,7 +21,7 @@ import "chartjs-adapter-moment";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit"; import { CSSResult, TemplateResult, css, html } from "lit";
import { property } from "lit/decorators.js"; import { property, state } from "lit/decorators.js";
Chart.register(Legend, Tooltip); Chart.register(Legend, Tooltip);
Chart.register(LineController, BarController, DoughnutController); Chart.register(LineController, BarController, DoughnutController);
@ -55,6 +56,7 @@ export abstract class AKChart<T> extends AKElement {
abstract apiRequest(): Promise<T>; abstract apiRequest(): Promise<T>;
abstract getChartData(data: T): ChartData; abstract getChartData(data: T): ChartData;
@state()
chart?: Chart; chart?: Chart;
@property() @property()
@ -67,10 +69,18 @@ export abstract class AKChart<T> extends AKElement {
css` css`
.container { .container {
height: 100%; height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.container > span {
position: absolute;
font-size: 2.5rem;
} }
canvas { canvas {
width: 100px; width: 100px;
height: 100px; height: 100px;
z-index: 1;
} }
`, `,
]; ];
@ -139,29 +149,7 @@ export abstract class AKChart<T> extends AKElement {
} }
getPlugins(): Plugin[] { getPlugins(): Plugin[] {
return [ return [];
{
id: "center-text",
beforeDraw: (chart) => {
if (!chart.ctx) return;
if (!this.centerText) return;
const width = chart.width || 0;
const height = chart.height || 0;
const fontSize = (height / 114).toFixed(2);
chart.ctx.font = `${fontSize}em Overpass, Arial, sans-serif`;
chart.ctx.textBaseline = "middle";
chart.ctx.fillStyle = this.fontColour;
const textX = Math.round(
(width - chart.ctx.measureText(this.centerText).width) / 2,
);
const textY = height / 2;
chart.ctx.fillText(this.centerText, textX, textY);
},
},
];
} }
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string { timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
@ -216,7 +204,9 @@ export abstract class AKChart<T> extends AKElement {
render(): TemplateResult { render(): TemplateResult {
return html` return html`
<div class="container"> <div class="container">
<canvas></canvas> ${this.chart ? html`` : html`<ak-empty-state ?loading="${true}"></ak-empty-state>`}
${this.centerText ? html` <span>${this.centerText}</span> ` : html``}
<canvas style="${this.chart === undefined ? "display: none;" : ""}"></canvas>
</div> </div>
`; `;
} }