From bcb5b43aa77a8203115bd181c31edd0de9466296 Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Sat, 28 Feb 2026 03:25:04 +1100 Subject: [PATCH] fix: resolve entitlement check on ai bridge settings/view (#22385) Resolves cases where the user is entitled to AI Governance but we don't show them the page because its not enabled. If for some reason the user doesn't have AI Bridge enabled anymore but still wants to access the old logs page they now can. Furthermore, we link to the docs regardless of if they have AI Bridge enabled, this is inline with our other settings pages. --- .../RequestLogsPage/RequestLogsPage.tsx | 10 +++-- .../RequestLogsPageView.stories.tsx | 8 ++-- .../RequestLogsPage/RequestLogsPageView.tsx | 6 +-- .../AIGovernanceSettingsPage.tsx | 5 ++- .../AIGovernanceSettingsPageView.stories.tsx | 4 +- .../AIGovernanceSettingsPageView.tsx | 40 +++++++++---------- 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPage.tsx b/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPage.tsx index bdb944e66c..7d53ee6ea2 100644 --- a/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPage.tsx +++ b/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPage.tsx @@ -3,7 +3,7 @@ import { useFilter } from "components/Filter/Filter"; import { useUserFilterMenu } from "components/Filter/UserFilter"; import { useAuthenticated } from "hooks"; import { usePaginatedQuery } from "hooks/usePaginatedQuery"; -import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; +import { useDashboard } from "modules/dashboard/useDashboard"; import { RequirePermission } from "modules/permissions/RequirePermission"; import type { FC } from "react"; import { useSearchParams } from "react-router"; @@ -13,14 +13,16 @@ import { useProviderFilterMenu } from "./RequestLogsFilter/ProviderFilter"; import { RequestLogsPageView } from "./RequestLogsPageView"; const RequestLogsPage: FC = () => { - const feats = useFeatureVisibility(); const { permissions } = useAuthenticated(); + const { entitlements } = useDashboard(); // Users are allowed to view their own request logs via the API, // but this page is only visible if the feature is enabled and the user // has the `viewAnyAIBridgeInterception` permission. // (as its defined in the Admin settings dropdown). - const isEntitled = Boolean(feats.aibridge); + const isEntitled = + entitlements.features.aibridge.entitlement === "entitled" || + entitlements.features.aibridge.entitlement === "grace_period"; const hasPermission = permissions.viewAnyAIBridgeInterception; const canViewRequestLogs = isEntitled && hasPermission; @@ -68,7 +70,7 @@ const RequestLogsPage: FC = () => { ; export const Paywall: Story = { args: { - isRequestLogsVisible: false, + isRequestLogsEntitled: false, }, }; export const Loaded: Story = { args: { - isRequestLogsVisible: true, + isRequestLogsEntitled: true, interceptions, filterProps: { ...defaultFilterProps, @@ -64,7 +64,7 @@ export const Loaded: Story = { export const Empty: Story = { args: { - isRequestLogsVisible: true, + isRequestLogsEntitled: true, interceptions: [], filterProps: { ...defaultFilterProps, @@ -76,7 +76,7 @@ export const Empty: Story = { export const Loading: Story = { args: { isLoading: true, - isRequestLogsVisible: true, + isRequestLogsEntitled: true, interceptions: [], filterProps: { ...defaultFilterProps, diff --git a/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPageView.tsx b/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPageView.tsx index 25baec869e..17ec8e58c3 100644 --- a/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPageView.tsx +++ b/site/src/pages/AIBridgePage/RequestLogsPage/RequestLogsPageView.tsx @@ -19,7 +19,7 @@ import { RequestLogsRow } from "./RequestLogsRow/RequestLogsRow"; interface RequestLogsPageViewProps { isLoading: boolean; - isRequestLogsVisible: boolean; + isRequestLogsEntitled: boolean; interceptions?: readonly AIBridgeInterception[]; interceptionsQuery: PaginationResult; filterProps: ComponentProps; @@ -27,12 +27,12 @@ interface RequestLogsPageViewProps { export const RequestLogsPageView: FC = ({ isLoading, - isRequestLogsVisible, + isRequestLogsEntitled, interceptions, interceptionsQuery, filterProps, }) => { - if (!isRequestLogsVisible) { + if (!isRequestLogsEntitled) { return ; } diff --git a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPage.tsx b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPage.tsx index 25610d289d..cf832890c4 100644 --- a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPage.tsx @@ -14,7 +14,10 @@ const AIGovernanceSettingsPage: FC = () => { ); diff --git a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.stories.tsx b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.stories.tsx index eb7b7cfbc1..59a6398402 100644 --- a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.stories.tsx +++ b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.stories.tsx @@ -23,7 +23,7 @@ const meta: Meta = { hidden: false, }, ], - featureAIBridgeEnabled: true, + featureAIBridgeEntitled: true, }, }; @@ -34,7 +34,7 @@ export const Page: Story = {}; export const Paywall: Story = { args: { - featureAIBridgeEnabled: false, + featureAIBridgeEntitled: false, options: [], }, }; diff --git a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx index e36678f6d5..7b7247b479 100644 --- a/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/AIGovernanceSettingsPage/AIGovernanceSettingsPageView.tsx @@ -14,42 +14,42 @@ import OptionsTable from "../OptionsTable"; type AIGovernanceSettingsPageViewProps = { options: SerpentOption[]; - featureAIBridgeEnabled: boolean; + featureAIBridgeEntitled: boolean; }; export const AIGovernanceSettingsPageView: FC< AIGovernanceSettingsPageViewProps -> = ({ options, featureAIBridgeEnabled }) => { +> = ({ options, featureAIBridgeEntitled }) => { return ( AI Governance - {featureAIBridgeEnabled ? ( -
- - } - > - - AI Bridge - - - Monitor and manage AI requests across your deployment. - - +
+ + } + > + + AI Bridge + + + Monitor and manage AI requests across your deployment. + + + {featureAIBridgeEntitled ? ( deploymentGroupHasParent(o.group, "AI Bridge")) .filter((o) => !o.annotations?.secret === true)} /> -
- ) : ( - - )} + ) : ( + + )} +
); };