UI improvement: make edit and delete buttons visible for custom AI provider (#1535)
- Move edit and delete actions from hidden popover to visible buttons - Restructure card layout: status badge and action buttons at top, title below <img width="1029" height="414" alt="image" src="https://github.com/user-attachments/assets/60497f87-254e-4f4d-9f8c-ea73b8f2526e" /> closes #1358 <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Made edit and delete always visible on custom provider cards and restructured the card layout for clearer actions and status. Improves discoverability and aligns with #1358. - **Refactors** - Replaced popover menu with visible Edit and Delete icon buttons (data-testid: edit-custom-provider, delete-custom-provider). - Moved status badge and actions to the top; title now sits below; badges don’t wrap. - Updated e2e tests to use new buttons and adjusted selectors for the updated heading. <!-- End of auto-generated description by cubic. -->
This commit is contained in:
committed by
GitHub
parent
0c4aef6f2c
commit
d76f428447
@@ -3,10 +3,8 @@ import { test } from "./helpers/test_helper";
|
|||||||
test("delete custom provider should not freeze", async ({ po }) => {
|
test("delete custom provider should not freeze", async ({ po }) => {
|
||||||
await po.setUp();
|
await po.setUp();
|
||||||
await po.goToSettingsTab();
|
await po.goToSettingsTab();
|
||||||
await po.page.getByTestId("custom-provider-more-options").click();
|
await po.page.getByTestId("delete-custom-provider").click();
|
||||||
await po.page.getByRole("button", { name: "Delete Provider" }).click();
|
await po.page.getByRole("button", { name: "Delete Provider" }).click();
|
||||||
await po.page.getByRole("button", { name: "Delete Provider" }).click();
|
|
||||||
|
|
||||||
// Make sure UI hasn't freezed
|
// Make sure UI hasn't freezed
|
||||||
await po.goToAppsTab();
|
await po.goToAppsTab();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ test("can edit custom provider", async ({ po }) => {
|
|||||||
// Create a provider first
|
// Create a provider first
|
||||||
|
|
||||||
// Edit it
|
// Edit it
|
||||||
await po.page.getByTestId("custom-provider-more-options").click();
|
await po.page.getByTestId("edit-custom-provider").click();
|
||||||
await po.page.getByRole("button", { name: "Edit Provider" }).click();
|
|
||||||
|
|
||||||
await po.page.getByRole("textbox", { name: "Display Name" }).clear();
|
await po.page.getByRole("textbox", { name: "Display Name" }).clear();
|
||||||
await po.page
|
await po.page
|
||||||
.getByRole("textbox", { name: "Display Name" })
|
.getByRole("textbox", { name: "Display Name" })
|
||||||
|
|||||||
@@ -776,9 +776,7 @@ export class PageObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setUpTestModel() {
|
async setUpTestModel() {
|
||||||
await this.page
|
await this.page.getByRole("heading", { name: "test-provider" }).click();
|
||||||
.getByRole("heading", { name: "test-provider Needs Setup" })
|
|
||||||
.click();
|
|
||||||
await this.page.getByRole("button", { name: "Add Custom Model" }).click();
|
await this.page.getByRole("button", { name: "Add Custom Model" }).click();
|
||||||
await this.page
|
await this.page
|
||||||
.getByRole("textbox", { name: "Model ID*" })
|
.getByRole("textbox", { name: "Model ID*" })
|
||||||
|
|||||||
@@ -10,17 +10,12 @@ import type { LanguageModelProvider } from "@/ipc/ipc_types";
|
|||||||
|
|
||||||
import { useLanguageModelProviders } from "@/hooks/useLanguageModelProviders";
|
import { useLanguageModelProviders } from "@/hooks/useLanguageModelProviders";
|
||||||
import { useCustomLanguageModelProvider } from "@/hooks/useCustomLanguageModelProvider";
|
import { useCustomLanguageModelProvider } from "@/hooks/useCustomLanguageModelProvider";
|
||||||
import { GiftIcon, PlusIcon, MoreVertical, Trash2, Edit } from "lucide-react";
|
import { GiftIcon, PlusIcon, Trash2, Edit } from "lucide-react";
|
||||||
import { Skeleton } from "./ui/skeleton";
|
import { Skeleton } from "./ui/skeleton";
|
||||||
import { Alert, AlertDescription, AlertTitle } from "./ui/alert";
|
import { Alert, AlertDescription, AlertTitle } from "./ui/alert";
|
||||||
import { AlertTriangle } from "lucide-react";
|
import { AlertTriangle } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
@@ -32,6 +27,11 @@ import {
|
|||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@/components/ui/tooltip";
|
||||||
|
|
||||||
import { CreateCustomProviderDialog } from "./CreateCustomProviderDialog";
|
import { CreateCustomProviderDialog } from "./CreateCustomProviderDialog";
|
||||||
|
|
||||||
@@ -123,7 +123,42 @@ export function ProviderSettingsGrid() {
|
|||||||
className="p-4 cursor-pointer"
|
className="p-4 cursor-pointer"
|
||||||
onClick={() => handleProviderClick(provider.id)}
|
onClick={() => handleProviderClick(provider.id)}
|
||||||
>
|
>
|
||||||
<CardTitle className="text-lg font-medium flex items-center justify-between mr-5">
|
{isCustom && (
|
||||||
|
<div
|
||||||
|
className="flex items-center justify-end"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
data-testid="edit-custom-provider"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-8 w-8 p-0 hover:bg-muted rounded-md"
|
||||||
|
onClick={() => handleEditProvider(provider)}
|
||||||
|
>
|
||||||
|
<Edit className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Edit Provider</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
data-testid="delete-custom-provider"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
className="h-8 w-8 p-0 text-destructive hover:text-destructive hover:bg-destructive/10 rounded-md"
|
||||||
|
onClick={() => setProviderToDelete(provider.id)}
|
||||||
|
>
|
||||||
|
<Trash2 className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Delete Provider</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<CardTitle className="text-lg font-medium mb-2">
|
||||||
{provider.name}
|
{provider.name}
|
||||||
{isProviderSetup(provider.id) ? (
|
{isProviderSetup(provider.id) ? (
|
||||||
<span className="ml-3 text-sm font-medium text-green-500 bg-green-50 dark:bg-green-900/30 border border-green-500/50 dark:border-green-500/50 px-2 py-1 rounded-full">
|
<span className="ml-3 text-sm font-medium text-green-500 bg-green-50 dark:bg-green-900/30 border border-green-500/50 dark:border-green-500/50 px-2 py-1 rounded-full">
|
||||||
@@ -144,46 +179,6 @@ export function ProviderSettingsGrid() {
|
|||||||
)}
|
)}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
{isCustom && (
|
|
||||||
<div
|
|
||||||
className="absolute top-2 right-0"
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="p-1 hover:bg-muted rounded-full focus:outline-none"
|
|
||||||
data-testid="custom-provider-more-options"
|
|
||||||
>
|
|
||||||
<MoreVertical className="h-4 w-4 text-muted-foreground" />
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end" className="w-48 p-2">
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="w-full justify-start mb-1"
|
|
||||||
onClick={() => handleEditProvider(provider)}
|
|
||||||
>
|
|
||||||
<Edit className="h-4 w-4 mr-2" />
|
|
||||||
Edit Provider
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
className="w-full justify-start text-destructive hover:text-destructive hover:bg-destructive/10"
|
|
||||||
onClick={() => setProviderToDelete(provider.id)}
|
|
||||||
>
|
|
||||||
<Trash2 className="h-4 w-4 mr-2" />
|
|
||||||
Delete Provider
|
|
||||||
</Button>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user