feat: implement ConfirmDialog component and add table truncation functionality to MainContent
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogActions,
|
||||
Button,
|
||||
Typography,
|
||||
Box,
|
||||
IconButton,
|
||||
Paper
|
||||
} from '@mui/material';
|
||||
import {
|
||||
Warning,
|
||||
Close,
|
||||
CleaningServices
|
||||
} from '@mui/icons-material';
|
||||
|
||||
interface ConfirmDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
title: string;
|
||||
message: string;
|
||||
confirmLabel?: string;
|
||||
cancelLabel?: string;
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const ConfirmDialog: React.FC<ConfirmDialogProps> = ({
|
||||
open,
|
||||
onClose,
|
||||
onConfirm,
|
||||
title,
|
||||
message,
|
||||
confirmLabel = 'Confirm',
|
||||
cancelLabel = 'Cancel',
|
||||
loading = false
|
||||
}) => {
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
PaperProps={{
|
||||
sx: {
|
||||
borderRadius: 4,
|
||||
p: 1,
|
||||
maxWidth: 400,
|
||||
border: 1,
|
||||
borderColor: 'divider',
|
||||
boxShadow: '0 24px 48px rgba(0,0,0,0.2)',
|
||||
bgcolor: 'background.paper',
|
||||
backgroundImage: 'none'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1.5, pb: 1 }}>
|
||||
<Box sx={{
|
||||
p: 1,
|
||||
borderRadius: 2,
|
||||
bgcolor: 'error.main',
|
||||
color: 'white',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
boxShadow: '0 4px 12px rgba(211, 47, 47, 0.4)'
|
||||
}}>
|
||||
<Warning fontSize="small" />
|
||||
</Box>
|
||||
<Typography variant="h6" sx={{ fontWeight: 800 }}>{title}</Typography>
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<IconButton size="small" onClick={onClose} disabled={loading}>
|
||||
<Close fontSize="small" />
|
||||
</IconButton>
|
||||
</DialogTitle>
|
||||
|
||||
<DialogContent sx={{ pb: 2 }}>
|
||||
<DialogContentText sx={{ color: 'text.secondary', fontWeight: 500, lineHeight: 1.6 }}>
|
||||
{message}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions sx={{ p: 2, pt: 0 }}>
|
||||
<Button
|
||||
onClick={onClose}
|
||||
color="inherit"
|
||||
disabled={loading}
|
||||
sx={{ borderRadius: 2, textTransform: 'none', fontWeight: 700, px: 3 }}
|
||||
>
|
||||
{cancelLabel}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
variant="contained"
|
||||
color="error"
|
||||
autoFocus
|
||||
disabled={loading}
|
||||
startIcon={<CleaningServices />}
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
textTransform: 'none',
|
||||
fontWeight: 700,
|
||||
px: 3,
|
||||
boxShadow: '0 8px 16px rgba(211, 47, 47, 0.25)',
|
||||
'&:hover': { boxShadow: '0 12px 20px rgba(211, 47, 47, 0.35)' }
|
||||
}}
|
||||
>
|
||||
{confirmLabel}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConfirmDialog;
|
||||
@@ -32,6 +32,7 @@ import Editor from '@monaco-editor/react';
|
||||
import { useAppStore } from '../store/useAppStore';
|
||||
import { SchemaService } from '../services/api';
|
||||
import TransferContent from './TransferContent';
|
||||
import ConfirmDialog from './ConfirmDialog';
|
||||
|
||||
const MainContent: React.FC = () => {
|
||||
const { activeTable, activeDatabase, darkMode, dbTab, setDbTab } = useAppStore();
|
||||
@@ -200,6 +201,7 @@ const MainContent: React.FC = () => {
|
||||
const [meta, setMeta] = useState<any>(null);
|
||||
const [loadingMeta, setLoadingMeta] = useState(true);
|
||||
const [truncating, setTruncating] = useState(false);
|
||||
const [showConfirm, setShowConfirm] = useState(false);
|
||||
|
||||
const fetchMeta = useCallback(async () => {
|
||||
setLoadingMeta(true);
|
||||
@@ -220,11 +222,10 @@ const MainContent: React.FC = () => {
|
||||
}, [fetchMeta]);
|
||||
|
||||
const handleTruncate = async () => {
|
||||
if (!table || !window.confirm(`Are you sure you want to truncate table "${table}"? This will delete all data!`)) return;
|
||||
|
||||
setTruncating(true);
|
||||
setShowConfirm(false);
|
||||
try {
|
||||
await SchemaService.truncateTable(table);
|
||||
await SchemaService.truncateTable(table!);
|
||||
setErrorInfo({
|
||||
open: true,
|
||||
title: 'Success',
|
||||
@@ -271,7 +272,7 @@ const MainContent: React.FC = () => {
|
||||
variant="outlined"
|
||||
color="error"
|
||||
startIcon={truncating ? <CircularProgress size={16} color="inherit" /> : <CleaningServices />}
|
||||
onClick={handleTruncate}
|
||||
onClick={() => setShowConfirm(true)}
|
||||
disabled={truncating}
|
||||
sx={{ borderRadius: 2, textTransform: 'none', fontWeight: 700 }}
|
||||
>
|
||||
@@ -279,6 +280,16 @@ const MainContent: React.FC = () => {
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<ConfirmDialog
|
||||
open={showConfirm}
|
||||
onClose={() => setShowConfirm(false)}
|
||||
onConfirm={handleTruncate}
|
||||
title="Truncate Table"
|
||||
message={`Are you sure you want to truncate table "${table}"? This action will permanently delete all ${meta?.rows || ''} records. This cannot be undone.`}
|
||||
confirmLabel="Truncate Now"
|
||||
loading={truncating}
|
||||
/>
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(240px, 1fr))', gap: 3 }}>
|
||||
{stats.map((stat, i) => (
|
||||
<Paper key={i} sx={{
|
||||
|
||||
Reference in New Issue
Block a user