Files
sencho/frontend/src/components/EditorLayout/DeleteStackDialog.tsx
T
Anso b3382d07a1 refactor(frontend): extract dialog cluster from EditorLayout (#898)
Extract the two remaining inline ConfirmModal blocks at the bottom of
EditorLayout into their own modules under components/EditorLayout/,
matching the pattern established by CreateStackDialog (B4-2):

- DeleteStackDialog: takes open/onOpenChange/stackName/onConfirm; owns
  the prune-volumes checkbox state internally and resets it on close.
  EditorLayout's deleteStack handler now accepts pruneVolumes as a
  parameter instead of reading parent state.
- UnsavedChangesDialog: takes open/onCancel/onConfirm. The discard
  body is hoisted to a named handler in EditorLayout
  (discardAndLoadPending) so the dialog stays a thin presentational
  wrapper.

Also removes a dead label-bulk-action surface that had no live entry
point: bulkActionLabel and bulkAction were declared without setters,
and setBulkActionOpen(true) was never called from anywhere. The
multi-select bulk-stack-actions live elsewhere via useBulkStackActions
and SidebarBulkBar; this removed code was unrelated and unreachable.
Drops the BulkActionResult interface, four useState lines, the
bulkAffected useMemo, the runLabelBulkAction handler, and the inline
ConfirmModal.

EditorLayout.tsx: 2,852 -> 2,747 LOC (-105). useState count: 66 -> 61.
2026-05-03 14:56:55 -04:00

54 lines
1.9 KiB
TypeScript

import { useState } from 'react';
import { ConfirmModal } from '../ui/modal';
import { Checkbox } from '../ui/checkbox';
export interface DeleteStackDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
stackName: string | null;
onConfirm: (pruneVolumes: boolean) => void | Promise<void>;
}
export function DeleteStackDialog({ open, onOpenChange, stackName, onConfirm }: DeleteStackDialogProps) {
const [pruneVolumes, setPruneVolumes] = useState(false);
const handleOpenChange = (next: boolean) => {
if (!next) setPruneVolumes(false);
onOpenChange(next);
};
return (
<ConfirmModal
open={open}
onOpenChange={handleOpenChange}
variant="destructive"
kicker={`${(stackName ?? 'STACK').toUpperCase()} · REMOVE · IRREVERSIBLE`}
title={
stackName ? (
<>
Delete <em className="font-display italic text-destructive">{stackName}</em>?
</>
) : (
'Delete stack?'
)
}
description={`Confirm deletion of ${stackName ?? 'stack'}.`}
hint={pruneVolumes ? 'VOLUMES PRUNED' : 'VOLUMES KEPT'}
confirmLabel="Delete"
onConfirm={() => onConfirm(pruneVolumes)}
>
<p className="text-sm text-muted-foreground">This action cannot be undone.</p>
<div className="flex items-center gap-2">
<Checkbox
id="prune-volumes"
checked={pruneVolumes}
onCheckedChange={(v) => setPruneVolumes(v === true)}
/>
<label htmlFor="prune-volumes" className="text-sm text-muted-foreground cursor-pointer select-none">
Also remove associated volumes
</label>
</div>
</ConfirmModal>
);
}