mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-19 13:33:35 +08:00
The sidebar had only single-session deletion, which made stale or noisy session lists expensive to maintain. This adds a batch-management lane in the desktop UI and a server endpoint that deletes multiple sessions while preserving per-session failure reporting and cleanup behavior. Constraint: Session deletion must preserve existing transcript and adapter cleanup semantics Constraint: Desktop UI should reuse the shared confirmation dialog instead of introducing a second modal surface Rejected: Delete all selected sessions through repeated client DELETE calls | weaker partial-failure handling and duplicated cleanup orchestration Rejected: Use a generic checkmark entry icon | it did not communicate batch deletion clearly enough Confidence: high Scope-risk: moderate Directive: Keep batch deletion routed through the server batch endpoint so rollback and adapter cleanup stay centralized Tested: bun test src/server/__tests__/sessions.test.ts -t batch-delete Tested: bun run check:server Tested: cd desktop && bun run check:desktop Tested: browser UI smoke for group select, shift range select, delete confirmation, 7/30 day cleanup, Cmd+A filtered selection, and Escape exit Not-tested: Live provider-backed session generation; this change covers session list management after sessions already exist
53 lines
1.1 KiB
TypeScript
53 lines
1.1 KiB
TypeScript
import { Modal } from './Modal'
|
|
import { Button } from './Button'
|
|
import type { ReactNode } from 'react'
|
|
|
|
type ConfirmDialogProps = {
|
|
open: boolean
|
|
onClose: () => void
|
|
onConfirm: () => void | Promise<void>
|
|
title: string
|
|
body: ReactNode
|
|
confirmLabel: string
|
|
cancelLabel: string
|
|
confirmVariant?: 'primary' | 'danger'
|
|
loading?: boolean
|
|
}
|
|
|
|
export function ConfirmDialog({
|
|
open,
|
|
onClose,
|
|
onConfirm,
|
|
title,
|
|
body,
|
|
confirmLabel,
|
|
cancelLabel,
|
|
confirmVariant = 'danger',
|
|
loading = false,
|
|
}: ConfirmDialogProps) {
|
|
return (
|
|
<Modal
|
|
open={open}
|
|
onClose={loading ? () => {} : onClose}
|
|
title={title}
|
|
width={460}
|
|
footer={(
|
|
<>
|
|
<Button variant="secondary" onClick={onClose} disabled={loading}>
|
|
{cancelLabel}
|
|
</Button>
|
|
<Button variant={confirmVariant} onClick={() => void onConfirm()} loading={loading}>
|
|
{confirmLabel}
|
|
</Button>
|
|
</>
|
|
)}
|
|
>
|
|
{typeof body === 'string' ? (
|
|
<p className="text-sm leading-6 text-[var(--color-text-secondary)]">
|
|
{body}
|
|
</p>
|
|
) : body}
|
|
</Modal>
|
|
)
|
|
}
|