Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions site/src/modules/dashboard/entitlements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,3 @@ export const selectFeatureVisibility = (
): Record<FeatureName, boolean> => {
return getFeatureVisibility(entitlements.has_license, entitlements.features);
};

/**
* Keep the AI seats column visible while in grace period so admins can
* identify who is consuming seats while remediating overages.
*/
export const shouldShowAISeatColumn = (entitlements: Entitlements): boolean => {
const aiGovernanceUserLimit = entitlements.features.ai_governance_user_limit;
return (
entitlements.has_license &&
aiGovernanceUserLimit.enabled &&
(aiGovernanceUserLimit.entitlement === "entitled" ||
aiGovernanceUserLimit.entitlement === "grace_period")
);
};
28 changes: 0 additions & 28 deletions site/src/modules/users/AISeatCell.tsx

This file was deleted.

15 changes: 0 additions & 15 deletions site/src/modules/users/UserHelpPopovers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,3 @@ export const GroupsHelpPopover: FC = () => {
</HelpPopover>
);
};

export const AiAddonHelpPopover: FC = () => {
return (
<HelpPopover>
<HelpPopoverIconTrigger size="small" />
<HelpPopoverContent>
<HelpPopoverTitle>What is the AI add-on?</HelpPopoverTitle>
<HelpPopoverText>
Users with access to AI features like AI Gateway or Tasks who are
actively consuming a seat.
</HelpPopoverText>
</HelpPopoverContent>
</HelpPopover>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { InfoIcon } from "lucide-react";
import type { FC } from "react";
import { Badge } from "#/components/Badge/Badge";
import {
Tooltip,
TooltipContent,
Expand Down Expand Up @@ -32,29 +31,24 @@ export const AIGovernanceAddOnCard: FC<AIGovernanceAddOnCardProps> = ({
>
<div className="flex items-center gap-1 px-6 py-1.5">
<div className="flex flex-1 items-center gap-1">
<div className="flex items-center gap-6">
<div className="flex items-center gap-1">
<span className="overflow-hidden text-ellipsis whitespace-nowrap text-sm font-medium text-content-primary">
{title}
</span>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
aria-label="AI Governance seat information"
className="m-0 inline-flex appearance-none border-0 bg-transparent p-0 text-content-secondary"
>
<InfoIcon className="size-3" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
Seats consumed by users using AI Governance features.
</TooltipContent>
</Tooltip>
</div>
<Badge variant="magenta" size="sm">
AI add-on
</Badge>
<div className="flex items-center gap-1">
<span className="overflow-hidden text-ellipsis whitespace-nowrap text-sm font-medium text-content-primary">
{title}
</span>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
aria-label="AI Governance seat information"
className="m-0 inline-flex appearance-none border-0 bg-transparent p-0 text-content-secondary"
>
<InfoIcon className="size-3" />
</button>
</TooltipTrigger>
<TooltipContent side="top">
Seats consumed by users using AI Governance features.
</TooltipContent>
</Tooltip>
</div>

<div className="min-w-[100px] flex-1 pl-8 pr-3">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,5 @@ export const EnterpriseDoesNotShowAIGovernanceAddOn: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.queryByText("Add-ons")).not.toBeInTheDocument();
await expect(canvas.queryByText("AI add-on")).not.toBeInTheDocument();
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Story = StoryObj<typeof GroupSettingsPageView>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// Without the AI add-on, the AI budget section is hidden.
// Without the aibridge feature, the AI budget section is hidden.
await expect(canvas.queryByText("AI budget")).not.toBeInTheDocument();
},
};
Expand Down
14 changes: 4 additions & 10 deletions site/src/pages/GroupsPage/GroupSettingsPageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { FC, ReactNode } from "react";
import * as Yup from "yup";
import type { Group } from "#/api/typesGenerated";
import { Alert } from "#/components/Alert/Alert";
import { Badge } from "#/components/Badge/Badge";
import { Button } from "#/components/Button/Button";
import { IconField } from "#/components/IconField/IconField";
import { Input } from "#/components/Input/Input";
Expand Down Expand Up @@ -111,7 +110,7 @@ const AIBudgetFeedback: FC<AIBudgetFeedbackProps> = ({

interface UpdateGroupFormProps {
group: Group;
/** Whether the AI add-on settings are shown (gated by the aibridge feature). */
/** Whether the AI budget settings are shown (gated by the aibridge feature). */
showAISettings: boolean;
/** Per-member AI budget in dollars, or null for unlimited spend. */
initialBudgetDollars: number | null;
Expand Down Expand Up @@ -227,14 +226,9 @@ const UpdateGroupForm: FC<UpdateGroupFormProps> = ({

{showAISettings && (
<section className="flex flex-col gap-8 max-w-md">
<div className="flex items-center gap-2">
<h2 className="m-0 text-xl font-semibold text-content-primary">
AI budget
</h2>
<Badge variant="purple" size="sm">
AI add-on
</Badge>
</div>
<h2 className="m-0 text-xl font-semibold text-content-primary">
AI budget
</h2>
<div className="flex flex-col gap-6">
<div className="flex flex-col items-start gap-2">
<Label htmlFor={budgetField.id}>Monthly limit per member</Label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { EmptyState } from "#/components/EmptyState/EmptyState";
import { useFilter } from "#/components/Filter/Filter";
import { useAuthenticated } from "#/hooks/useAuthenticated";
import { usePaginatedQuery } from "#/hooks/usePaginatedQuery";
import { shouldShowAISeatColumn } from "#/modules/dashboard/entitlements";
import { useDashboard } from "#/modules/dashboard/useDashboard";
import { useOrganizationSettings } from "#/modules/management/OrganizationSettingsLayout";
import { RequirePermission } from "#/modules/permissions/RequirePermission";
Expand All @@ -38,7 +37,6 @@ const OrganizationMembersPage: FC = () => {
const { organization, organizationPermissions } = useOrganizationSettings();
const { entitlements } = useDashboard();
const searchParamsResult = useSearchParams();
const showAISeatColumn = shouldShowAISeatColumn(entitlements);

const organizationRolesQuery = useQuery(organizationRoles(organizationName));
const groupsByUserIdQuery = useQuery(
Expand Down Expand Up @@ -123,7 +121,6 @@ const OrganizationMembersPage: FC = () => {
organizationName={organizationName}
membersQuery={membersQuery}
members={members}
showAISeatColumn={showAISeatColumn}
addMembers={async (users: User[]) => {
// TODO: Replace with a batch endpoint (POST /organizations/{org}/members)
// to add all users in a single request instead of N individual calls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,6 @@ type Story = StoryObj<typeof OrganizationMembersPageView>;

export const Default: Story = {};

export const WithAIAddonColumn: Story = {
args: {
showAISeatColumn: true,
},
};

export const Loading: Story = {
args: {
members: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ import {
} from "#/components/Table/Table";
import { TableEmpty } from "#/components/TableEmpty/TableEmpty";
import { TableLoader } from "#/components/TableLoader/TableLoader";
import { AISeatCell } from "#/modules/users/AISeatCell";
import { UserGroupsCell } from "#/modules/users/UserGroupsCell";
import {
AiAddonHelpPopover,
GroupsHelpPopover,
RolesHelpPopover,
} from "#/modules/users/UserHelpPopovers";
Expand All @@ -38,7 +36,6 @@ export type OrganizationMembersTableProps = {
// State
organizationName: string;
members: Array<OrganizationMemberTableEntry> | undefined;
showAISeatColumn?: boolean;

// Actions
onEditMemberRoles: (member: OrganizationMemberWithUserData) => void;
Expand All @@ -62,8 +59,6 @@ type OrganizationMemberTableEntry = OrganizationMemberWithUserData & {
export const OrganizationMembersTable: React.FC<
OrganizationMembersTableProps
> = (props) => {
const { showAISeatColumn } = props;

return (
<Table>
<TableHeader>
Expand All @@ -81,14 +76,6 @@ export const OrganizationMembersTable: React.FC<
<GroupsHelpPopover />
</div>
</TableHead>
{showAISeatColumn && (
<TableHead className="w-1/6">
<div className="flex flex-row items-center gap-2">
<span>AI add-on</span>
<AiAddonHelpPopover />
</div>
</TableHead>
)}
</TableRow>
</TableHeader>
<TableBody>
Expand All @@ -101,7 +88,6 @@ export const OrganizationMembersTable: React.FC<
const OrganizationMembersTableBody: React.FC<OrganizationMembersTableProps> = ({
organizationName,
members,
showAISeatColumn,

isUpdatingMemberRoles,
removeMember,
Expand Down Expand Up @@ -141,7 +127,6 @@ const OrganizationMembersTableBody: React.FC<OrganizationMembersTableProps> = ({
roles={member.roles}
/>
<UserGroupsCell userGroups={member.groups} />
{showAISeatColumn && <AISeatCell hasAISeat={member.has_ai_seat} />}
<TableCell className="w-px whitespace-nowrap text-right">
<div className="flex justify-end">
{member.user_id !== me && canEditMembers && (
Expand Down
30 changes: 1 addition & 29 deletions site/src/pages/UsersPage/UsersPage.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import { expect, screen, spyOn, userEvent, within } from "storybook/test";
import { screen, spyOn, userEvent, within } from "storybook/test";
import { API } from "#/api/api";
import { deploymentConfigQueryKey } from "#/api/queries/deployment";
import { groupsQueryKey } from "#/api/queries/groups";
Expand Down Expand Up @@ -79,34 +79,6 @@ type Story = StoryObj<typeof UsersPage>;

export const Loaded: Story = {};

export const WithAIAddonColumn: Story = {
parameters: {
features: ["ai_governance_user_limit"],
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const header = await canvas.findByRole("columnheader", {
name: /AI add-on/i,
});

await expect(header).toBeVisible();
},
};

export const WithoutAIAddonColumn: Story = {
parameters: {
features: ["audit_log"],
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByRole("columnheader", { name: "User" });

await expect(
canvas.queryByRole("columnheader", { name: /AI add-on/i }),
).not.toBeInTheDocument();
},
};

export const SuspendUserSuccess: Story = {
play: async ({ canvasElement }) => {
const user = userEvent.setup();
Expand Down
3 changes: 0 additions & 3 deletions site/src/pages/UsersPage/UsersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { useFilter } from "#/components/Filter/Filter";
import { useStatusFilterMenu } from "#/components/Filter/UsersFilter";
import { useAuthenticated } from "#/hooks/useAuthenticated";
import { usePaginatedQuery } from "#/hooks/usePaginatedQuery";
import { shouldShowAISeatColumn } from "#/modules/dashboard/entitlements";
import { useDashboard } from "#/modules/dashboard/useDashboard";
import { RoleSelectorDialog } from "#/modules/roles/RoleSelectorDialog";
import { pageTitle } from "#/utils/page";
Expand All @@ -33,7 +32,6 @@ const UsersPage: React.FC = () => {
const queryClient = useQueryClient();
const [searchParams, setSearchParams] = useSearchParams();
const { entitlements } = useDashboard();
const showAISeatColumn = shouldShowAISeatColumn(entitlements);

const groupsByUserIdQuery = useQuery(groupsByUserId());

Expand Down Expand Up @@ -113,7 +111,6 @@ const UsersPage: React.FC = () => {
}}
usersQuery={usersQuery}
groupsByUserId={groupsByUserIdQuery.data}
showAISeatColumn={showAISeatColumn}
onEditUserRoles={setUserToEditRoles}
isUpdatingUserRoles={updateUserRolesMutation.isPending}
onResetUserPassword={(user) => {
Expand Down
5 changes: 1 addition & 4 deletions site/src/pages/UsersPage/UsersPageView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ const meta: Meta<typeof UsersPageView> = {
totalRecords: 2,
data: {
count: 2,
users: [
{ ...MockUserOwner, has_ai_seat: false },
{ ...MockUserMember, has_ai_seat: false },
],
users: [MockUserOwner, MockUserMember],
},
},
},
Expand Down
Loading
Loading