From 923c04e3e3678408fa75e36cd3ec2296c4addf63 Mon Sep 17 00:00:00 2001 From: Marcin Tojek Date: Tue, 23 Dec 2025 16:00:36 +0100 Subject: [PATCH] fix(site): add defensive access to entitlement features (#21381) Fixes #14784 --- .../LicensesSettingsPage.stories.tsx | 27 +++++++++++++++++++ .../LicensesSettingsPage.tsx | 4 +-- .../TemplateInsightsPage.tsx | 18 ------------- 3 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.stories.tsx diff --git a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.stories.tsx b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.stories.tsx new file mode 100644 index 0000000000..c70c7a77bd --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.stories.tsx @@ -0,0 +1,27 @@ +import { MockLicenseResponse } from "testHelpers/entities"; +import type { Meta, StoryObj } from "@storybook/react-vite"; +import LicensesSettingsPage from "./LicensesSettingsPage"; + +const meta: Meta = { + title: "pages/DeploymentSettingsPage/LicensesSettingsPage", + component: LicensesSettingsPage, + parameters: { + queries: [ + { key: ["licenses"], data: MockLicenseResponse }, + { key: ["insights", "userStatusCounts"], data: { active: [] } }, + ], + }, +}; + +export default meta; +type Story = StoryObj; + +export const WithoutUserLimitFeature: Story = { + parameters: { + queries: [ + { key: ["entitlements"], data: { features: {} } }, + { key: ["licenses"], data: MockLicenseResponse }, + { key: ["insights", "userStatusCounts"], data: { active: [] } }, + ], + }, +}; diff --git a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.tsx b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.tsx index 7f8ee4d7d0..3b9b58212e 100644 --- a/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/LicensesSettingsPage/LicensesSettingsPage.tsx @@ -77,8 +77,8 @@ const LicensesSettingsPage: FC = () => { showConfetti={confettiOn} isLoading={isLoading} isRefreshing={refreshEntitlementsMutation.isPending} - userLimitActual={entitlementsQuery.data?.features.user_limit.actual} - userLimitLimit={entitlementsQuery.data?.features.user_limit.limit} + userLimitActual={entitlementsQuery.data?.features.user_limit?.actual} + userLimitLimit={entitlementsQuery.data?.features.user_limit?.limit} licenses={licenses} isRemovingLicense={isRemovingLicense} removeLicense={(licenseId: number) => removeLicenseApi(licenseId)} diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index c9f91e3392..d4ea79a79c 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -2,14 +2,12 @@ import { useTheme } from "@emotion/react"; import LinearProgress from "@mui/material/LinearProgress"; import Link from "@mui/material/Link"; import { getErrorDetail, getErrorMessage } from "api/errors"; -import { entitlements } from "api/queries/entitlements"; import { insightsTemplate, insightsUserActivity, insightsUserLatency, } from "api/queries/insights"; import type { - Entitlements, Template, TemplateAppUsage, TemplateInsightsResponse, @@ -39,7 +37,6 @@ import { TooltipContent, TooltipTrigger, } from "components/Tooltip/Tooltip"; -import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata"; import { CircleCheck as CircleCheckIcon, CircleXIcon, @@ -100,11 +97,6 @@ export default function TemplateInsightsPage() { const userLatency = useQuery(insightsUserLatency(commonFilters)); const userActivity = useQuery(insightsUserActivity(commonFilters)); - const { metadata } = useEmbeddedMetadata(); - const { data: entitlementsQuery } = useQuery( - entitlements(metadata.entitlements), - ); - return ( <> {getTemplatePageTitle("Insights", template)} @@ -123,7 +115,6 @@ export default function TemplateInsightsPage() { userLatency={userLatency} userActivity={userActivity} interval={interval} - entitlements={entitlementsQuery} /> ); @@ -215,7 +206,6 @@ interface TemplateInsightsPageViewProps { data: UserActivityInsightsResponse | undefined; error: unknown; }; - entitlements: Entitlements | undefined; controls: ReactNode; interval: InsightsInterval; } @@ -224,7 +214,6 @@ export const TemplateInsightsPageView: FC = ({ templateInsights, userLatency, userActivity, - entitlements, controls, interval, }) => { @@ -251,11 +240,6 @@ export const TemplateInsightsPageView: FC = ({ @@ -283,14 +267,12 @@ interface ActiveUsersPanelProps extends PanelProps { data: TemplateInsightsResponse["interval_reports"] | undefined; error: unknown; interval: InsightsInterval; - userLimit: number | undefined; } const ActiveUsersPanel: FC = ({ data, error, interval, - userLimit, ...panelProps }) => { return (