mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 20:00:47 +00:00
feat: add bulk delete for provider connections
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
c22f11de38
commit
644bff4cdd
@@ -637,7 +637,7 @@ export default function ProviderDetailPage() {
|
|||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/providers/${id}`, { method: "DELETE" });
|
const res = await fetch(`/api/providers/${id}`, { method: "DELETE" });
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
setConnections(connections.filter(c => c.id !== id));
|
setConnections(prev => prev.filter(c => c.id !== id));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error deleting connection:", error);
|
console.log("Error deleting connection:", error);
|
||||||
@@ -646,6 +646,32 @@ export default function ProviderDetailPage() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBulkDelete = () => {
|
||||||
|
const count = selectedConnectionIds.length;
|
||||||
|
if (count === 0) return;
|
||||||
|
setConfirmState({
|
||||||
|
title: `Delete ${count} Connection${count > 1 ? "s" : ""}`,
|
||||||
|
message: `Delete ${count} connection${count > 1 ? "s" : ""}? This cannot be undone.`,
|
||||||
|
onConfirm: async () => {
|
||||||
|
setConfirmState(null);
|
||||||
|
let failed = 0;
|
||||||
|
const idsToDelete = [...selectedConnectionIds];
|
||||||
|
for (const id of idsToDelete) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`/api/providers/${id}`, { method: "DELETE" });
|
||||||
|
if (!res.ok) failed += 1;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error deleting connection:", error);
|
||||||
|
failed += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setConnections(prev => prev.filter(c => !idsToDelete.includes(c.id)));
|
||||||
|
setSelectedConnectionIds([]);
|
||||||
|
if (failed > 0) alert(`Deleted ${idsToDelete.length - failed} connection(s), ${failed} failed.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleOAuthSuccess = () => {
|
const handleOAuthSuccess = () => {
|
||||||
fetchConnections();
|
fetchConnections();
|
||||||
setShowOAuthModal(false);
|
setShowOAuthModal(false);
|
||||||
@@ -844,6 +870,14 @@ export default function ProviderDetailPage() {
|
|||||||
{connections
|
{connections
|
||||||
.map((conn, index) => (
|
.map((conn, index) => (
|
||||||
<div key={conn.id} className="flex min-w-0 items-stretch">
|
<div key={conn.id} className="flex min-w-0 items-stretch">
|
||||||
|
<div className="flex shrink-0 items-center pl-1 sm:pl-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isSelected(conn.id)}
|
||||||
|
onChange={() => toggleSelectConnection(conn.id)}
|
||||||
|
className="h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<ConnectionRow
|
<ConnectionRow
|
||||||
connection={conn}
|
connection={conn}
|
||||||
@@ -1319,6 +1353,16 @@ export default function ProviderDetailPage() {
|
|||||||
)}
|
)}
|
||||||
{connections.length > 0 && (
|
{connections.length > 0 && (
|
||||||
<>
|
<>
|
||||||
|
{selectedConnectionIds.length > 0 && (
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="danger"
|
||||||
|
icon="delete"
|
||||||
|
onClick={handleBulkDelete}
|
||||||
|
>
|
||||||
|
Delete Selected ({selectedConnectionIds.length})
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -1446,6 +1490,19 @@ export default function ProviderDetailPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{connections.length > 0 && (
|
||||||
|
<div className="mb-3 flex items-center gap-2 border-b border-black/[0.03] pb-2 dark:border-white/[0.03]">
|
||||||
|
<label className="flex cursor-pointer items-center gap-1.5 text-xs text-text-muted hover:text-primary">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={allSelected}
|
||||||
|
onChange={toggleSelectAllConnections}
|
||||||
|
className="h-3.5 w-3.5 rounded border-gray-300 text-primary focus:ring-primary"
|
||||||
|
/>
|
||||||
|
Select All
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{connectionsList}
|
{connectionsList}
|
||||||
{!isCompatible && (
|
{!isCompatible && (
|
||||||
<div className="mt-4 grid grid-cols-1 gap-2 sm:flex">
|
<div className="mt-4 grid grid-cols-1 gap-2 sm:flex">
|
||||||
|
|||||||
Reference in New Issue
Block a user