mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
@@ -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} />
|
||||
|
||||
+6
-4
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
+26
-6
@@ -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 />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user