Files
spaceshell/app/src/ConfirmDelete.tsx
T
vasyansk a55555983b feat(app): sidebar favorites, drag-reorder, and delete-with-confirm
- FAVORITES section at the top collects pinned workspaces (removed from their
  group listing); a star toggle on each row pins/unpins via setWorkspaceMeta.
- Drag-to-reorder within a section using raw pointer events (HTML5 DnD is
  unreliable in the macOS WKWebView), with a drop-line indicator; on drop the
  section's `order` is reassigned sequentially and persisted. Cross-section
  drops are ignored (group membership unchanged).
- Trash icon on row hover opens a ConfirmDelete modal that shows the live
  terminal count and warns before terminating them, then calls close_workspace
  and re-points the active workspace.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 08:56:20 +07:00

64 lines
2.6 KiB
TypeScript

import { useEffect, useRef } from "react";
import { COLORS, FONT } from "./theme";
/** Confirmation modal for deleting a workspace. Warns when live terminals
* would be killed, but still allows the delete (per product decision). */
export function ConfirmDelete({
name,
activeCount,
onConfirm,
onCancel,
}: {
name: string;
activeCount: number;
onConfirm: () => void;
onCancel: () => void;
}) {
const confirmRef = useRef<HTMLButtonElement>(null);
useEffect(() => { confirmRef.current?.focus(); }, []);
function onKeyDown(e: React.KeyboardEvent) {
e.stopPropagation();
if (e.key === "Escape") { e.preventDefault(); onCancel(); }
else if (e.key === "Enter") { e.preventDefault(); onConfirm(); }
}
return (
<div
onMouseDown={onCancel}
style={{ position: "fixed", inset: 0, zIndex: 2000, background: "#000A", display: "flex", alignItems: "center", justifyContent: "center" }}
>
<div
onMouseDown={(e) => e.stopPropagation()}
onKeyDown={onKeyDown}
style={{ width: 420, background: COLORS.bgApp, border: `1px solid ${COLORS.borderStrong}`, borderRadius: 14, padding: 24, color: COLORS.textPrimary, fontFamily: FONT.ui }}
>
<div style={{ fontWeight: 700, fontSize: 16, marginBottom: 12 }}>Delete workspace</div>
<div style={{ fontSize: 13, color: COLORS.textSecondary, lineHeight: 1.5 }}>
Delete <span style={{ color: COLORS.textPrimary, fontWeight: 600 }}>{name}</span>? This removes the workspace and its layout.
</div>
{activeCount > 0 && (
<div style={{ marginTop: 12, padding: "8px 10px", borderRadius: 8, background: "#2A1414", border: `1px solid ${COLORS.stError}`, color: COLORS.stError, fontSize: 12, fontWeight: 600 }}>
{activeCount} active terminal{activeCount === 1 ? "" : "s"} will be terminated.
</div>
)}
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 20 }}>
<button
onClick={onCancel}
style={{ padding: "7px 14px", background: COLORS.bgElevated, color: COLORS.textPrimary, border: `1px solid ${COLORS.borderStrong}`, borderRadius: 7, fontSize: 13, fontFamily: FONT.ui }}
>
Cancel
</button>
<button
ref={confirmRef}
onClick={onConfirm}
style={{ padding: "7px 14px", background: COLORS.stError, color: "#fff", border: "none", borderRadius: 7, fontSize: 13, fontWeight: 600, fontFamily: FONT.ui }}
>
Delete
</button>
</div>
</div>
</div>
);
}