Move project remove confirmation from inline buttons to modal popup
All checks were successful
Build App / build-macos (push) Successful in 2m29s
Build App / build-windows (push) Successful in 3m56s
Build App / build-linux (push) Successful in 4m31s
Build App / sync-to-github (push) Successful in 10s

Replaces the inline Yes/No confirmation with a proper ConfirmRemoveModal
dialog, consistent with other modal patterns in the app (EnvVarsModal, etc.).
Supports Escape key and overlay click to dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 08:14:44 -08:00
parent ab16ac11e7
commit 418afe00ed
2 changed files with 74 additions and 29 deletions

View File

@@ -11,6 +11,7 @@ import PortMappingsModal from "./PortMappingsModal";
import ClaudeInstructionsModal from "./ClaudeInstructionsModal";
import ContainerProgressModal from "./ContainerProgressModal";
import FileManagerModal from "./FileManagerModal";
import ConfirmRemoveModal from "./ConfirmRemoveModal";
interface Props {
project: Project;
@@ -32,7 +33,7 @@ export default function ProjectCard({ project }: Props) {
const [progressMsg, setProgressMsg] = useState<string | null>(null);
const [activeOperation, setActiveOperation] = useState<"starting" | "stopping" | "resetting" | null>(null);
const [operationCompleted, setOperationCompleted] = useState(false);
const [showRemoveConfirm, setShowRemoveConfirm] = useState(false);
const [showRemoveModal, setShowRemoveModal] = useState(false);
const [isEditingName, setIsEditingName] = useState(false);
const [editName, setEditName] = useState(project.name);
const isSelected = selectedProjectId === project.id;
@@ -435,34 +436,12 @@ export default function ProjectCard({ project }: Props) {
disabled={false}
label={showConfig ? "Hide" : "Config"}
/>
{showRemoveConfirm ? (
<span className="inline-flex items-center gap-1 text-xs">
<span className="text-[var(--text-secondary)]">Remove?</span>
<button
onClick={async (e) => {
e.stopPropagation();
setShowRemoveConfirm(false);
await remove(project.id);
}}
className="px-1.5 py-0.5 rounded text-white bg-[var(--error)] hover:opacity-80 transition-colors"
>
Yes
</button>
<button
onClick={(e) => { e.stopPropagation(); setShowRemoveConfirm(false); }}
className="px-1.5 py-0.5 rounded text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-primary)] transition-colors"
>
No
</button>
</span>
) : (
<ActionButton
onClick={() => setShowRemoveConfirm(true)}
disabled={loading}
label="Remove"
danger
/>
)}
<ActionButton
onClick={() => setShowRemoveModal(true)}
disabled={loading}
label="Remove"
danger
/>
</div>
{/* Config panel */}
@@ -925,6 +904,17 @@ export default function ProjectCard({ project }: Props) {
/>
)}
{showRemoveModal && (
<ConfirmRemoveModal
projectName={project.name}
onConfirm={async () => {
setShowRemoveModal(false);
await remove(project.id);
}}
onCancel={() => setShowRemoveModal(false)}
/>
)}
{activeOperation && (
<ContainerProgressModal
projectName={project.name}