import BashExecModal from '../BashExecModal'; import { PolicyBlockDialog } from '../stack/PolicyBlockDialog'; import { PreDeployScanDialog } from '../stack/PreDeployScanDialog'; import { UpdateReadinessDialog } from '../stack/UpdateReadinessDialog'; import { SelfStackProtectedDialog } from '../stack/SelfStackProtectedDialog'; import { DeleteStackDialog } from './DeleteStackDialog'; import { UnsavedChangesDialog } from './UnsavedChangesDialog'; import { StackAlertSheet } from '../StackAlertSheet'; import { GitSourcePanel } from '../stack/GitSourcePanel'; import { LogViewer } from '../LogViewer'; import { VulnerabilityScanSheet } from '../VulnerabilityScanSheet'; import { ComposeDiffPreviewDialog } from '@/components/ComposeDiffPreviewDialog'; import type { OverlayState } from './hooks/useOverlayState'; import type { StackActionsHook } from './hooks/useStackActions'; import type { PermissionAction } from '@/context/AuthContext'; interface ShellOverlaysProps { overlayState: OverlayState; stackActions: StackActionsHook; isDarkMode: boolean; isAdmin: boolean; can: (action: PermissionAction, resourceType?: string, resourceId?: string) => boolean; selectedFile: string | null; stackName: string; gitSourceOpen: boolean; setGitSourceOpen: (open: boolean) => void; canSelfUpdate: boolean; onOpenFleetNodeUpdates: () => void; } export function ShellOverlays({ overlayState, stackActions, isDarkMode, isAdmin, can, selectedFile, stackName, gitSourceOpen, setGitSourceOpen, canSelfUpdate, onOpenFleetNodeUpdates, }: ShellOverlaysProps) { const { deleteDialogOpen, closeDeleteDialog, stackToDelete, pendingUnsavedLoad, pendingLeaveAction, bashModalOpen, selectedContainer, logViewerOpen, logContainer, stackMonitor, closeStackMonitor, policyBlock, setPolicyBlock, policyBypassing, updateReadiness, setUpdateReadiness, preDeployAdvisory, selfStackProtectedOpen, setSelfStackProtectedOpen, stackMisconfigScanId, setStackMisconfigScanId, diffPreview, setDiffPreview, diffPreviewConfirming, setDiffPreviewConfirming, } = overlayState; return ( <> { if (!open) closeDeleteDialog(); }} stackName={stackToDelete} onConfirm={stackActions.deleteStack} /> {/* Bash Exec Modal */} {selectedContainer && ( )} {/* LogViewer Modal */} {logContainer && ( )} {/* Stack monitor (alerts + auto-heal as tabs) */} { if (!open) closeStackMonitor(); }} stackName={stackMonitor?.stackName ?? ''} initialTab={stackMonitor?.tab ?? 'alerts'} /> {/* Pre-update readiness check */} setUpdateReadiness(null)} onProceed={() => updateReadiness?.proceed()} /> {/* Pre-deploy scan advisory (visibility only; never blocks) */} preDeployAdvisory?.cancel()} onDeploy={() => preDeployAdvisory?.proceed()} /> {/* Pre-deploy policy block */} setPolicyBlock(null)} onBypass={stackActions.bypassPolicyAndRetry} /> {/* Git Source Panel */} {stackName && ( )} {/* Stack config misconfig scan results */} setStackMisconfigScanId(null)} canManageSuppressions={isAdmin} /> {/* Compose diff preview */} { if (!open && !diffPreviewConfirming) setDiffPreview(null); }} stackName={selectedFile ? selectedFile.replace(/\.(yml|yaml)$/, '') : ''} fileName={diffPreview?.fileName ?? ''} language={diffPreview?.language ?? 'yaml'} original={diffPreview?.original ?? ''} modified={diffPreview?.modified ?? ''} actionLabel={diffPreview?.mode === 'save-and-deploy' ? 'Save & deploy' : 'Save'} confirming={diffPreviewConfirming} isDarkMode={isDarkMode} onConfirm={async () => { const snapshot = diffPreview; setDiffPreviewConfirming(true); try { if (snapshot?.mode === 'save-and-deploy') { const saved = await stackActions.saveFile(); if (saved) await stackActions.deployStack(); } else { await stackActions.saveFile(); } } finally { setDiffPreviewConfirming(false); setDiffPreview(null); } }} /> ); }