Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ const ProvidersPageView: React.FC<ProvidersPageViewProps> = ({
<TableRow>
<TableHead className="w-1/3">Name</TableHead>
<TableHead className="w-1/3">Base URL</TableHead>
<TableHead className="w-22">Status</TableHead>
<TableHead className="w-22">
<span className="sr-only">Status</span>
</TableHead>
</TableRow>
</TableHeader>
<TableBody size="lg">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ const meta: Meta<typeof ProviderRow> = {
},
decorators: [
(Story) => (
<Table aria-label="AI providers">
<Table className="table-fixed" aria-label="AI providers">
<TableHeader>
<TableRow>
<TableHead className="w-1/3">Name</TableHead>
<TableHead className="w-1/3">Base URL</TableHead>
<TableHead className="w-22">Status</TableHead>
<TableHead className="w-[42%]">Name</TableHead>
<TableHead className="w-[38%]">Base URL</TableHead>
<TableHead className="w-20 text-center">
<span className="sr-only">Status</span>
</TableHead>
<TableHead className="w-12">
<span className="sr-only">Open provider</span>
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
Expand Down Expand Up @@ -77,19 +82,36 @@ export const NotSupportedInAgents: Story = {
args: {
provider: MockAIProviderCopilot,
},
play: async ({ canvasElement }) => {
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
const badge = canvas.getByRole("button", {
name: "Not supported in Agents",
});
await expect(badge).toBeInTheDocument();

await userEvent.hover(badge);
const tooltip = await within(canvasElement.ownerDocument.body).findByRole(
"tooltip",
);
const tooltip = await within(document.body).findByRole("tooltip");
await expect(tooltip).toHaveTextContent(
"This provider works with the AI Gateway Proxy but Coder Agents can't use it.",
);

// Activation must not navigate the row.
badge.focus();
await userEvent.keyboard("{Enter}");
await userEvent.keyboard(" ");
await userEvent.click(badge);
await expect(args.onClick).not.toHaveBeenCalled();
},
};

export const Disabled: Story = {
args: {
provider: { ...MockAIProviderOpenAI, enabled: false },
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await expect(canvas.getByText("Disabled")).toBeInTheDocument();
await expect(canvas.getByText("OpenAI")).toBeInTheDocument();
},
};

Expand All @@ -103,6 +125,7 @@ export const SupportedHasNoAgentsLabel: Story = {
await expect(
canvas.queryByText("Not supported in Agents"),
).not.toBeInTheDocument();
await expect(canvas.queryByText("Disabled")).not.toBeInTheDocument();
},
};

Expand All @@ -120,19 +143,15 @@ export const WithHostnameCollisionWarning: Story = {
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
const badge = canvas.getByLabelText(/^Warning: Hostname/);
const badge = canvas.getByRole("button", { name: /^Warning:/ });
await expect(badge).toBeInTheDocument();
await expect(badge).toHaveAttribute(
"aria-label",
await expect(badge).toHaveAccessibleName(
expect.stringContaining("api.openai.com"),
);
await expect(badge).toHaveAttribute("tabIndex", "0");

// Hover shows the tooltip with the warning text.
await userEvent.hover(badge);
const tooltip = await within(canvasElement.ownerDocument.body).findByRole(
"tooltip",
);
const tooltip = await within(document.body).findByRole("tooltip");
await expect(tooltip).toHaveTextContent("api.openai.com");

// Keyboard and mouse activation must not navigate the row.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TooltipTrigger,
} from "#/components/Tooltip/Tooltip";
import { useClickableTableRow } from "#/hooks/useClickableTableRow";
import { cn } from "#/utils/cn";
import { ProviderIcon } from "./ProviderIcon";
import { getProviderDisplayType } from "./providerFormApiMap";

Expand All @@ -29,6 +30,7 @@ export const ProviderRow: React.FC<ProviderRowProps> = ({
onClick: () => onClick?.(),
});
const displayName = provider.display_name || provider.name;
const disabled = !provider.enabled;

// Stop activation from bubbling to a parent `useClickableTableRow`
// row, which navigates on click, Enter (onKeyDown), and Space
Expand All @@ -42,11 +44,27 @@ export const ProviderRow: React.FC<ProviderRowProps> = ({
<TableRow key={provider.name} {...clickableProps}>
<TableCell className="min-w-0 px-4 py-3">
<AvatarData
title={displayName}
title={
<span className="flex items-center gap-2">
<span
className={cn("truncate", disabled && "text-content-secondary")}
>
{displayName}
</span>
{disabled && (
<Badge asChild size="sm" variant="default">
<span>Disabled</span>
</Badge>
)}
</span>
}
avatar={
<Avatar
size="lg"
className="flex shrink-0 items-center justify-center"
className={cn(
"flex shrink-0 items-center justify-center",
disabled && "opacity-50 grayscale",
)}
>
<ProviderIcon
provider={getProviderDisplayType(provider)}
Expand All @@ -58,27 +76,28 @@ export const ProviderRow: React.FC<ProviderRowProps> = ({
</TableCell>
<TableCell className="min-w-0">
<span
className="block truncate text-content-secondary"
className={cn(
"block truncate",
disabled ? "text-content-disabled" : "text-content-secondary",
)}
title={provider.base_url}
>
{provider.base_url}
</span>
</TableCell>
<TableCell>
<div className="flex flex-wrap items-center gap-1">
{provider.enabled && <Badge variant="default">Enabled</Badge>}
{AgentsUnsupportedProviderTypes.some((t) => t === provider.type) && (
<Tooltip>
<TooltipTrigger asChild>
<Badge
asChild
variant="info"
role="button"
tabIndex={0}
onClick={stopPropagation}
onKeyDown={stopPropagation}
onKeyUp={stopPropagation}
>
Not supported in Agents
<button type="button">Not supported in Agents</button>
</Badge>
</TooltipTrigger>
<TooltipContent className="max-w-xs">
Expand All @@ -91,20 +110,25 @@ export const ProviderRow: React.FC<ProviderRowProps> = ({
<Tooltip>
<TooltipTrigger asChild>
<Badge
asChild
variant="warning"
role="button"
tabIndex={0}
aria-label={`Warning: ${provider.status.warnings.join("; ")}`}
onClick={stopPropagation}
onKeyDown={stopPropagation}
onKeyUp={stopPropagation}
>
Warning
<button
type="button"
aria-label={`Warning: ${provider.status.warnings.join("; ")}`}
>
Warning
</button>
</Badge>
</TooltipTrigger>
<TooltipContent className="max-w-xs">
{provider.status.warnings.map((warning) => (
<p key={warning}>{warning}</p>
<p key={warning} className="break-words">
{warning}
</p>
))}
</TooltipContent>
</Tooltip>
Expand Down
Loading