From 2e5952a444a681750a2070e152036a683e11c310 Mon Sep 17 00:00:00 2001 From: sua yoo Date: Mon, 23 Oct 2023 16:25:16 -0700 Subject: [PATCH] Display crawl time usage history table (#1304) Partially resolves #1223, fixes #1298 - Adds crawl usage table in dashboard under metrics - Shows skeleton loading indicator when metrics are loading (@Shrinks99 feel free to adjust how this looks) - Shows max number of concurrent crawls running if any are running ("`running` / `max` Crawls Running") --- frontend/src/pages/org/dashboard.ts | 85 ++++++++++++++++++++++++++--- frontend/src/types/org.ts | 8 +++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/frontend/src/pages/org/dashboard.ts b/frontend/src/pages/org/dashboard.ts index 44b64018..072bdfd5 100644 --- a/frontend/src/pages/org/dashboard.ts +++ b/frontend/src/pages/org/dashboard.ts @@ -4,6 +4,7 @@ import { when } from "lit/directives/when.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { msg, localized, str } from "@lit/localize"; import type { SlSelectEvent } from "@shoelace-style/shoelace"; +import humanizeDuration from "pretty-ms"; import LiteElement, { html } from "../../utils/LiteElement"; import type { AuthState } from "../../utils/AuthService"; @@ -180,7 +181,10 @@ export class Dashboard extends LiteElement { (metrics) => html`
${this.renderStat({ - value: metrics.workflowsRunningCount, + value: + metrics.workflowsRunningCount && metrics.maxConcurrentCrawls + ? `${metrics.workflowsRunningCount} / ${metrics.maxConcurrentCrawls}` + : metrics.workflowsRunningCount, singleLabel: msg("Crawl Running"), pluralLabel: msg("Crawls Running"), iconProps: { @@ -224,6 +228,7 @@ export class Dashboard extends LiteElement { ` )} +
${this.renderUsageHistory()}
`; } @@ -337,17 +342,16 @@ export class Dashboard extends LiteElement { renderFooter?: (metric: Metrics) => TemplateResult ) { return html` -
+

${title}

- ${when(this.metrics, () => renderContent(this.metrics!))} + ${when( + this.metrics, + () => renderContent(this.metrics!), + this.renderCardSkeleton + )}
${when(renderFooter && this.metrics, () => renderFooter!(this.metrics!) @@ -394,6 +398,71 @@ export class Dashboard extends LiteElement { `; } + private renderCardSkeleton = () => + html` + + + + + `; + + // TODO fix style when data-table is converted to slots + readonly usageTableCols = [ + msg("Month"), + html` + ${msg("Execution Time")} + +
+ ${msg("Total running time of all crawler instances")} +
+ +
+ `, + html` + ${msg("Total Crawl Duration")} + +
+ ${msg("Total time elapsed between when crawl starts and ends")} +
+ +
+ `, + ]; + + private renderUsageHistory() { + if (!this.org) return; + const rows = Object.entries(this.org.usage || {}) + // Sort latest + .reverse() + .map(([mY, crawlTime]) => { + const value = this.org!.crawlExecSeconds?.[mY]; + return [ + html` + + + `, + value ? humanizeDuration(value * 1000) : "--", + humanizeDuration((crawlTime || 0) * 1000), + ]; + }); + return html` +

+ ${msg("Usage History")} +

+
+ +
+ `; + } + private renderPercentage(ratio: number) { const percent = ratio * 100; if (percent < 1) return `<1%`; diff --git a/frontend/src/types/org.ts b/frontend/src/types/org.ts index 2ae86191..0c2c6fd7 100644 --- a/frontend/src/types/org.ts +++ b/frontend/src/types/org.ts @@ -14,6 +14,14 @@ export type OrgData = { slug: string; quotas: Record; bytesStored: number; + usage: { + // Keyed by {4-digit year}-{2-digit month} + [key: string]: number; + } | null; + crawlExecSeconds: { + // Keyed by {4-digit year}-{2-digit month} + [key: string]: number; + } | null; users?: { [id: string]: { role: (typeof AccessCode)[UserRole];