Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Better deletion flow
Browse files- wait for chat deletion happens with the deletion modal being open still and the delete button having a loading spinner instead of closign an then nothing happening until the chat gets deleted
- create new chat when last chat gets deleted instead of bringing me back to login screen
frontend/src/components/SessionSidebar/SessionSidebar.tsx
CHANGED
|
@@ -59,6 +59,7 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 59 |
|
| 60 |
// -- Delete with dialog confirmation ------------------------------------
|
| 61 |
const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
|
|
|
|
| 62 |
|
| 63 |
const handleDeleteClick = useCallback(
|
| 64 |
(sessionId: string, e: React.MouseEvent) => {
|
|
@@ -69,9 +70,12 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 69 |
);
|
| 70 |
|
| 71 |
const handleDeleteConfirm = useCallback(async () => {
|
| 72 |
-
if (!confirmDeleteId) return;
|
| 73 |
const sessionId = confirmDeleteId;
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
| 75 |
useAgentStore.getState().clearSessionState(sessionId);
|
| 76 |
try {
|
| 77 |
await apiFetch(`/api/session/${sessionId}`, { method: 'DELETE' });
|
|
@@ -79,7 +83,25 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 79 |
} catch {
|
| 80 |
deleteSession(sessionId);
|
| 81 |
}
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
const handleSelect = useCallback(
|
| 85 |
(sessionId: string) => {
|
|
@@ -348,7 +370,7 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 348 |
{/* Delete confirmation dialog */}
|
| 349 |
<Dialog
|
| 350 |
open={!!confirmDeleteId}
|
| 351 |
-
onClose={() => setConfirmDeleteId(null)}
|
| 352 |
slotProps={{
|
| 353 |
backdrop: { sx: { backgroundColor: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(4px)' } },
|
| 354 |
}}
|
|
@@ -390,6 +412,7 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 390 |
<Button
|
| 391 |
onClick={() => setConfirmDeleteId(null)}
|
| 392 |
size="small"
|
|
|
|
| 393 |
sx={{
|
| 394 |
color: 'var(--muted-text)',
|
| 395 |
fontSize: '0.82rem',
|
|
@@ -403,6 +426,8 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 403 |
onClick={handleDeleteConfirm}
|
| 404 |
variant="contained"
|
| 405 |
size="small"
|
|
|
|
|
|
|
| 406 |
sx={{
|
| 407 |
fontSize: '0.82rem',
|
| 408 |
px: 2.5,
|
|
@@ -414,9 +439,14 @@ export default function SessionSidebar({ onClose }: SessionSidebarProps) {
|
|
| 414 |
filter: 'brightness(1.15)',
|
| 415 |
boxShadow: 'none',
|
| 416 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
}}
|
| 418 |
>
|
| 419 |
-
Delete
|
| 420 |
</Button>
|
| 421 |
</DialogActions>
|
| 422 |
</Dialog>
|
|
|
|
| 59 |
|
| 60 |
// -- Delete with dialog confirmation ------------------------------------
|
| 61 |
const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
|
| 62 |
+
const [isDeleting, setIsDeleting] = useState(false);
|
| 63 |
|
| 64 |
const handleDeleteClick = useCallback(
|
| 65 |
(sessionId: string, e: React.MouseEvent) => {
|
|
|
|
| 70 |
);
|
| 71 |
|
| 72 |
const handleDeleteConfirm = useCallback(async () => {
|
| 73 |
+
if (!confirmDeleteId || isDeleting) return;
|
| 74 |
const sessionId = confirmDeleteId;
|
| 75 |
+
setIsDeleting(true);
|
| 76 |
+
|
| 77 |
+
const isLastSession = sessions.length === 1;
|
| 78 |
+
|
| 79 |
useAgentStore.getState().clearSessionState(sessionId);
|
| 80 |
try {
|
| 81 |
await apiFetch(`/api/session/${sessionId}`, { method: 'DELETE' });
|
|
|
|
| 83 |
} catch {
|
| 84 |
deleteSession(sessionId);
|
| 85 |
}
|
| 86 |
+
|
| 87 |
+
// If this was the last session, create a new one
|
| 88 |
+
if (isLastSession) {
|
| 89 |
+
try {
|
| 90 |
+
const response = await apiFetch('/api/session', { method: 'POST' });
|
| 91 |
+
if (response.ok) {
|
| 92 |
+
const data = await response.json();
|
| 93 |
+
createSession(data.session_id);
|
| 94 |
+
setPlan([]);
|
| 95 |
+
clearPanel();
|
| 96 |
+
}
|
| 97 |
+
} catch (error) {
|
| 98 |
+
console.error('Failed to create new session after deleting last one:', error);
|
| 99 |
+
}
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
setIsDeleting(false);
|
| 103 |
+
setConfirmDeleteId(null);
|
| 104 |
+
}, [deleteSession, confirmDeleteId, isDeleting, sessions, createSession, setPlan, clearPanel]);
|
| 105 |
|
| 106 |
const handleSelect = useCallback(
|
| 107 |
(sessionId: string) => {
|
|
|
|
| 370 |
{/* Delete confirmation dialog */}
|
| 371 |
<Dialog
|
| 372 |
open={!!confirmDeleteId}
|
| 373 |
+
onClose={() => !isDeleting && setConfirmDeleteId(null)}
|
| 374 |
slotProps={{
|
| 375 |
backdrop: { sx: { backgroundColor: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(4px)' } },
|
| 376 |
}}
|
|
|
|
| 412 |
<Button
|
| 413 |
onClick={() => setConfirmDeleteId(null)}
|
| 414 |
size="small"
|
| 415 |
+
disabled={isDeleting}
|
| 416 |
sx={{
|
| 417 |
color: 'var(--muted-text)',
|
| 418 |
fontSize: '0.82rem',
|
|
|
|
| 426 |
onClick={handleDeleteConfirm}
|
| 427 |
variant="contained"
|
| 428 |
size="small"
|
| 429 |
+
disabled={isDeleting}
|
| 430 |
+
startIcon={isDeleting ? <CircularProgress size={16} sx={{ color: '#fff' }} /> : undefined}
|
| 431 |
sx={{
|
| 432 |
fontSize: '0.82rem',
|
| 433 |
px: 2.5,
|
|
|
|
| 439 |
filter: 'brightness(1.15)',
|
| 440 |
boxShadow: 'none',
|
| 441 |
},
|
| 442 |
+
'&.Mui-disabled': {
|
| 443 |
+
bgcolor: 'var(--accent-red)',
|
| 444 |
+
color: '#fff',
|
| 445 |
+
opacity: 0.7,
|
| 446 |
+
},
|
| 447 |
}}
|
| 448 |
>
|
| 449 |
+
{isDeleting ? 'Deleting...' : 'Delete'}
|
| 450 |
</Button>
|
| 451 |
</DialogActions>
|
| 452 |
</Dialog>
|