+ ${color ? renderLegendColor(color) : null}${title} + ${humanizeExecutionSeconds(value, { + round: "down", + displaySeconds: true, + })} +
+`; diff --git a/frontend/src/features/meters/has-quotas.ts b/frontend/src/features/meters/has-quotas.ts new file mode 100644 index 0000000000..360fad883b --- /dev/null +++ b/frontend/src/features/meters/has-quotas.ts @@ -0,0 +1,14 @@ +import { type OrgData } from "@/types/org"; + +export function hasExecutionMinuteQuota(org: OrgData | null | undefined) { + if (!org) return; + + return ( + org.quotas.maxExecMinutesPerMonth > 0 || + org.quotas.extraExecMinutes > 0 || + org.quotas.giftedExecMinutes > 0 + ); +} +export function hasStorageQuota(org: OrgData | null | undefined) { + return !!org?.quotas.storageQuota; +} diff --git a/frontend/src/features/meters/index.ts b/frontend/src/features/meters/index.ts new file mode 100644 index 0000000000..104150f862 --- /dev/null +++ b/frontend/src/features/meters/index.ts @@ -0,0 +1,2 @@ +import "./execution-minutes/execution-minute-meter"; +import "./storage/storage-meter"; diff --git a/frontend/src/features/meters/storage/colors.ts b/frontend/src/features/meters/storage/colors.ts new file mode 100644 index 0000000000..0862fda7a2 --- /dev/null +++ b/frontend/src/features/meters/storage/colors.ts @@ -0,0 +1,32 @@ +import { type Color } from "../utils/colors"; + +import { tw } from "@/utils/tailwind"; + +export type StorageType = + | "default" + | "crawls" + | "uploads" + | "archivedItems" + | "browserProfiles" + | "runningTime" + | "misc"; + +export const storageColorClasses = { + default: tw`text-neutral-600`, + crawls: tw`text-lime-500`, + uploads: tw`text-sky-500`, + archivedItems: tw`text-primary-500`, + browserProfiles: tw`text-orange-500`, + runningTime: tw`text-blue-600`, + misc: tw`text-gray-400`, +}; + +export const storageColors = { + default: { primary: "neutral-600", border: "neutral-700" }, + crawls: { primary: "lime-500", border: "lime-700" }, + uploads: { primary: "sky-500", border: "sky-700" }, + archivedItems: { primary: "primary-500", border: "primary-700" }, + browserProfiles: { primary: "orange-500", border: "orange-700" }, + runningTime: { primary: "blue-600", border: "blue-700" }, + misc: { primary: "gray-400", border: "gray-600" }, +} as const satisfies Record+ ${color ? renderLegendColor(color) : null}${title} + ${localize.bytes(value)} +
+`; diff --git a/frontend/src/features/meters/utils/colors.ts b/frontend/src/features/meters/utils/colors.ts new file mode 100644 index 0000000000..f663285254 --- /dev/null +++ b/frontend/src/features/meters/utils/colors.ts @@ -0,0 +1,36 @@ +type ShoelaceColor = + | "neutral" + | "gray" + | "primary" + | "red" + | "orange" + | "amber" + | "yellow" + | "lime" + | "green" + | "emerald" + | "teal" + | "cyan" + | "sky" + | "blue" + | "indigo" + | "violet" + | "purple" + | "fuchsia" + | "pink" + | "rose"; + +type ShoelaceValue = + | "50" + | "100" + | "200" + | "300" + | "400" + | "500" + | "600" + | "700" + | "800" + | "900" + | "950"; + +export type Color = `${ShoelaceColor}-${ShoelaceValue}`; diff --git a/frontend/src/features/meters/utils/legend.ts b/frontend/src/features/meters/utils/legend.ts new file mode 100644 index 0000000000..81159b5cdd --- /dev/null +++ b/frontend/src/features/meters/utils/legend.ts @@ -0,0 +1,11 @@ +import { html } from "lit"; +import { styleMap } from "lit/directives/style-map.js"; + +export const renderLegendColor = (color: { primary: string; border: string }) => + html``; diff --git a/frontend/src/features/meters/utils/tooltip.ts b/frontend/src/features/meters/utils/tooltip.ts new file mode 100644 index 0000000000..a0edee2418 --- /dev/null +++ b/frontend/src/features/meters/utils/tooltip.ts @@ -0,0 +1,16 @@ +import { html, type TemplateResult } from "lit"; + +export const tooltipContent = ({ + title, + value, + content, +}: { + title: string | TemplateResult; + value: string | TemplateResult; + content: string | TemplateResult | undefined; +}) => + html`
- ${this.localize.bytes(value, {
- unitDisplay: "narrow",
- })}
-
- ${this.renderPercentage(value / metrics.storageUsedBytes)}
-
- ${this.renderPercentage( - (metrics.storageQuotaBytes - metrics.storageUsedBytes) / - metrics.storageQuotaBytes, - )} -
-
- ${humanizeExecutionSeconds(used, { displaySeconds: true })}
- ${msg("of")}
-
- ${humanizeExecutionSeconds(quota, { displaySeconds: true })}
-
- ${humanizeExecutionSeconds(used, { displaySeconds: true })}
-
- ${this.renderPercentage(used / quota)}
-