From 7e1ac2e22b6989d6939a7b4749b142fc574294bf Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Mon, 2 Dec 2024 21:27:43 +0200 Subject: [PATCH] feat(site): show license utilization in general settings (#15683) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR is the first iteration towards #15297 We cannot yet show license utilization over time, so we show current license utilization. This is because we don't track user states over time. We only track the current user state. A graph over time filtering by active users would therefore not account for day to day changes in user state and be inaccurate. DB schema migrations and related updates will follow that allow us to show license utilization over time. ![image](https://github.com/user-attachments/assets/91bd6e8c-e74c-4ef5-aa6b-271fd245da37) --------- Co-authored-by: ケイラ --- .../GeneralSettingsPageView.stories.tsx | 72 +++++++++++++++++++ .../GeneralSettingsPageView.tsx | 38 ++++++++++ 2 files changed, 110 insertions(+) diff --git a/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.stories.tsx index 9147a1a5be..05ed426d5d 100644 --- a/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.stories.tsx @@ -42,6 +42,7 @@ const meta: Meta = { deploymentDAUs: MockDeploymentDAUResponse, invalidExperiments: [], safeExperiments: [], + entitlements: undefined, }, }; @@ -136,3 +137,74 @@ export const invalidExperimentsEnabled: Story = { invalidExperiments: ["invalid"], }, }; + +export const WithLicenseUtilization: Story = { + args: { + entitlements: { + ...MockEntitlementsWithUserLimit, + features: { + ...MockEntitlementsWithUserLimit.features, + user_limit: { + ...MockEntitlementsWithUserLimit.features.user_limit, + enabled: true, + actual: 75, + limit: 100, + entitlement: "entitled", + }, + }, + }, + }, +}; + +export const HighLicenseUtilization: Story = { + args: { + entitlements: { + ...MockEntitlementsWithUserLimit, + features: { + ...MockEntitlementsWithUserLimit.features, + user_limit: { + ...MockEntitlementsWithUserLimit.features.user_limit, + enabled: true, + actual: 95, + limit: 100, + entitlement: "entitled", + }, + }, + }, + }, +}; + +export const ExceedsLicenseUtilization: Story = { + args: { + entitlements: { + ...MockEntitlementsWithUserLimit, + features: { + ...MockEntitlementsWithUserLimit.features, + user_limit: { + ...MockEntitlementsWithUserLimit.features.user_limit, + enabled: true, + actual: 100, + limit: 95, + entitlement: "entitled", + }, + }, + }, + }, +}; +export const NoLicenseLimit: Story = { + args: { + entitlements: { + ...MockEntitlementsWithUserLimit, + features: { + ...MockEntitlementsWithUserLimit.features, + user_limit: { + ...MockEntitlementsWithUserLimit.features.user_limit, + enabled: false, + actual: 0, + limit: 0, + entitlement: "entitled", + }, + }, + }, + }, +}; diff --git a/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.tsx index 29edacd08d..df5550d70e 100644 --- a/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/GeneralSettingsPage/GeneralSettingsPageView.tsx @@ -1,4 +1,5 @@ import AlertTitle from "@mui/material/AlertTitle"; +import LinearProgress from "@mui/material/LinearProgress"; import type { DAUsResponse, Entitlements, @@ -36,6 +37,12 @@ export const GeneralSettingsPageView: FC = ({ safeExperiments, invalidExperiments, }) => { + const licenseUtilizationPercentage = + entitlements?.features?.user_limit?.actual && + entitlements?.features?.user_limit?.limit + ? entitlements.features.user_limit.actual / + entitlements.features.user_limit.limit + : undefined; return ( <> = ({ )} + {licenseUtilizationPercentage && ( + + + + {Math.round(licenseUtilizationPercentage * 100)}% used ( + {entitlements!.features.user_limit.actual}/ + {entitlements!.features.user_limit.limit} users) + + + )} {invalidExperiments.length > 0 && ( Invalid experiments in use: