mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 10:21:03 +00:00
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.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user