fix: standardize button order, add confirmation dialogs for destructive actions
- Fix Cancel|Save order and add primary/loading props (AppConfigDetailPage) - Add AlertDialog before stopping deployments (AppsTab) - Add ConfirmDialog before deleting taps (TapConfigModal) - Add AlertDialog before killing queries with toast feedback (DatabaseAdminPage) - Add AlertDialog before removing roles from users (UsersTab) - Standardize Cancel button to variant="ghost" (TapConfigModal, RouteDetail) - Add loading prop to ConfirmDialogs (OidcConfigPage, RouteDetail) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
|
||||
import { useParams, useNavigate, useLocation } from 'react-router';
|
||||
import {
|
||||
AlertDialog,
|
||||
Badge,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
@@ -506,6 +507,7 @@ function AppDetailView({ appId: appSlug, environments, selectedEnv }: { appId: s
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [subTab, setSubTab] = useState<'overview' | 'config'>('config');
|
||||
const [deleteConfirm, setDeleteConfirm] = useState(false);
|
||||
const [stopTarget, setStopTarget] = useState<{ id: string; name: string } | null>(null);
|
||||
|
||||
const envMap = useMemo(() => new Map(environments.map((e) => [e.id, e])), [environments]);
|
||||
const sortedVersions = useMemo(() => [...versions].sort((a, b) => b.version - a.version), [versions]);
|
||||
@@ -531,11 +533,17 @@ function AppDetailView({ appId: appSlug, environments, selectedEnv }: { appId: s
|
||||
} catch { toast({ title: 'Deploy failed', variant: 'error', duration: 86_400_000 }); }
|
||||
}
|
||||
|
||||
async function handleStop(deploymentId: string) {
|
||||
function handleStop(deploymentId: string) {
|
||||
setStopTarget({ id: deploymentId, name: app?.displayName ?? appSlug });
|
||||
}
|
||||
|
||||
async function confirmStop() {
|
||||
if (!stopTarget) return;
|
||||
try {
|
||||
await stopDeployment.mutateAsync({ appId: appSlug, deploymentId });
|
||||
await stopDeployment.mutateAsync({ appId: appSlug, deploymentId: stopTarget.id });
|
||||
toast({ title: 'Deployment stopped', variant: 'warning' });
|
||||
} catch { toast({ title: 'Stop failed', variant: 'error', duration: 86_400_000 }); }
|
||||
setStopTarget(null);
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
@@ -602,6 +610,15 @@ function AppDetailView({ appId: appSlug, environments, selectedEnv }: { appId: s
|
||||
confirmText={app.slug}
|
||||
loading={deleteApp.isPending}
|
||||
/>
|
||||
<AlertDialog
|
||||
open={!!stopTarget}
|
||||
onClose={() => setStopTarget(null)}
|
||||
onConfirm={confirmStop}
|
||||
title="Stop deployment?"
|
||||
description={`Stop deployment for "${stopTarget?.name}"? This will take the service offline.`}
|
||||
confirmLabel="Stop"
|
||||
variant="warning"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user