feat: <RequestLogsPage /> not enabled message (#22546)

This pull-request implements a message that alerts when the user has AI
Governance entitled in their license but not necessarily enabled, this
is an improvement to #22385 where the content simply didn't render (due
to a failed request).

<img width="1403" height="400" alt="image"
src="https://github.com/user-attachments/assets/54685ce1-5cc1-421f-b290-de9b3d160c03"
/>

<img width="1411" height="824" alt="image"
src="https://github.com/user-attachments/assets/4d44fa18-0914-4e51-a415-c511e5b13e98"
/>
This commit is contained in:
Jake Howell
2026-03-04 00:25:38 +11:00
committed by GitHub
parent 17f5fa452e
commit 02328605a9
5 changed files with 68 additions and 10 deletions
@@ -23,6 +23,7 @@ const RequestLogsPage: FC = () => {
const isEntitled =
entitlements.features.aibridge.entitlement === "entitled" ||
entitlements.features.aibridge.entitlement === "grace_period";
const isEnabled = entitlements.features.aibridge.enabled;
const hasPermission = permissions.viewAnyAIBridgeInterception;
const canViewRequestLogs = isEntitled && hasPermission;
@@ -71,6 +72,7 @@ const RequestLogsPage: FC = () => {
<RequestLogsPageView
isLoading={interceptionsQuery.isLoading}
isRequestLogsEntitled={isEntitled}
isRequestLogsEnabled={isEnabled}
interceptions={interceptionsQuery.data?.results}
interceptionsQuery={interceptionsQuery}
filterProps={{
@@ -48,12 +48,21 @@ type Story = StoryObj<typeof RequestLogsPageView>;
export const Paywall: Story = {
args: {
isRequestLogsEntitled: false,
isRequestLogsEnabled: false,
},
};
export const NotEnabled: Story = {
args: {
isRequestLogsEntitled: true,
isRequestLogsEnabled: false,
},
};
export const Loaded: Story = {
args: {
isRequestLogsEntitled: true,
isRequestLogsEnabled: true,
interceptions,
filterProps: {
...defaultFilterProps,
@@ -65,6 +74,7 @@ export const Loaded: Story = {
export const Empty: Story = {
args: {
isRequestLogsEntitled: true,
isRequestLogsEnabled: true,
interceptions: [],
filterProps: {
...defaultFilterProps,
@@ -77,6 +87,7 @@ export const Loading: Story = {
args: {
isLoading: true,
isRequestLogsEntitled: true,
isRequestLogsEnabled: true,
interceptions: [],
filterProps: {
...defaultFilterProps,
@@ -1,4 +1,6 @@
import type { AIBridgeInterception } from "api/typesGenerated";
import { Alert, AlertDetail, AlertTitle } from "components/Alert/Alert";
import { Link } from "components/Link/Link";
import {
PaginationContainer,
type PaginationResult,
@@ -14,12 +16,14 @@ import {
import { TableEmpty } from "components/TableEmpty/TableEmpty";
import { TableLoader } from "components/TableLoader/TableLoader";
import type { ComponentProps, FC } from "react";
import { docs } from "utils/docs";
import { RequestLogsFilter } from "./RequestLogsFilter/RequestLogsFilter";
import { RequestLogsRow } from "./RequestLogsRow/RequestLogsRow";
interface RequestLogsPageViewProps {
isLoading: boolean;
isRequestLogsEntitled: boolean;
isRequestLogsEnabled: boolean;
interceptions?: readonly AIBridgeInterception[];
interceptionsQuery: PaginationResult;
filterProps: ComponentProps<typeof RequestLogsFilter>;
@@ -28,6 +32,7 @@ interface RequestLogsPageViewProps {
export const RequestLogsPageView: FC<RequestLogsPageViewProps> = ({
isLoading,
isRequestLogsEntitled,
isRequestLogsEnabled,
interceptions,
interceptionsQuery,
filterProps,
@@ -36,6 +41,24 @@ export const RequestLogsPageView: FC<RequestLogsPageViewProps> = ({
return <PaywallAIGovernance />;
}
if (!isRequestLogsEnabled) {
return (
<Alert className="mb-12" severity="warning" prominent>
<AlertTitle>
AI Bridge is included in your license, but not set up yet.
</AlertTitle>
<AlertDetail>
You have access to AI Governance, but it still needs to be setup.
Check out the{" "}
<Link href={docs("/ai-coder/ai-bridge")} target="_blank">
AI Bridge
</Link>{" "}
documentation to get started.
</AlertDetail>
</Alert>
);
}
return (
<>
<RequestLogsFilter {...filterProps} />
@@ -7,6 +7,10 @@ import { AIGovernanceSettingsPageView } from "./AIGovernanceSettingsPageView";
const AIGovernanceSettingsPage: FC = () => {
const { deploymentConfig } = useDeploymentConfig();
const { entitlements } = useDashboard();
const isAiBridgeEntitled =
entitlements.features.aibridge.entitlement === "entitled" ||
entitlements.features.aibridge.entitlement === "grace_period";
const isAIBridgeEnabled = entitlements.features.aibridge.enabled;
return (
<>
@@ -14,10 +18,8 @@ const AIGovernanceSettingsPage: FC = () => {
<AIGovernanceSettingsPageView
options={deploymentConfig.options}
featureAIBridgeEntitled={
entitlements.features.aibridge.entitlement === "entitled" ||
entitlements.features.aibridge.entitlement === "grace_period"
}
featureAIBridgeEntitled={isAiBridgeEntitled}
featureAIBridgeEnabled={isAIBridgeEnabled}
/>
</>
);
@@ -1,4 +1,6 @@
import type { SerpentOption } from "api/typesGenerated";
import { Alert, AlertDetail, AlertTitle } from "components/Alert/Alert";
import { Link } from "components/Link/Link";
import { PaywallAIGovernance } from "components/Paywall/PaywallAIGovernance";
import {
SettingsHeader,
@@ -15,11 +17,12 @@ import OptionsTable from "../OptionsTable";
type AIGovernanceSettingsPageViewProps = {
options: SerpentOption[];
featureAIBridgeEntitled: boolean;
featureAIBridgeEnabled: boolean;
};
export const AIGovernanceSettingsPageView: FC<
AIGovernanceSettingsPageViewProps
> = ({ options, featureAIBridgeEntitled }) => {
> = ({ options, featureAIBridgeEntitled, featureAIBridgeEnabled }) => {
return (
<Stack direction="column" spacing={6}>
<SettingsHeader>
@@ -41,11 +44,28 @@ export const AIGovernanceSettingsPageView: FC<
</SettingsHeader>
{featureAIBridgeEntitled ? (
<OptionsTable
options={options
.filter((o) => deploymentGroupHasParent(o.group, "AI Bridge"))
.filter((o) => !o.annotations?.secret === true)}
/>
<>
{!featureAIBridgeEnabled && (
<Alert className="mb-12" severity="warning" prominent>
<AlertTitle>
AI Bridge is included in your license, but not set up yet.
</AlertTitle>
<AlertDetail>
You have access to AI Governance, but it still needs to be
setup. Check out the{" "}
<Link href={docs("/ai-coder/ai-bridge")} target="_blank">
AI Bridge
</Link>{" "}
documentation to get started.
</AlertDetail>
</Alert>
)}
<OptionsTable
options={options
.filter((o) => deploymentGroupHasParent(o.group, "AI Bridge"))
.filter((o) => !o.annotations?.secret === true)}
/>
</>
) : (
<PaywallAIGovernance />
)}