Skip to content

Commit fb75e78

Browse files
committed
webui: add "delete all conversations" button to import/export tab
- Add 'Delete all conversations' functionality with confirmation dialog - Add Trash icon and destructive styling for clear visual indication - Redirects to "?new_chat=true#/" by using conversationsStore.deleteAll()
1 parent 5266379 commit fb75e78

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsImportExportTab.svelte

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<script lang="ts">
2-
import { Download, Upload } from '@lucide/svelte';
2+
import { Download, Upload, Trash2 } from '@lucide/svelte';
33
import { Button } from '$lib/components/ui/button';
44
import { DialogConversationSelection } from '$lib/components/app';
55
import { createMessageCountMap } from '$lib/utils';
66
import { conversationsStore, conversations } from '$lib/stores/conversations.svelte';
7+
import { toast } from 'svelte-sonner';
8+
import DialogConfirmation from '$lib/components/app/dialogs/DialogConfirmation.svelte';
79
810
let exportedConversations = $state<DatabaseConversation[]>([]);
911
let importedConversations = $state<DatabaseConversation[]>([]);
@@ -18,11 +20,14 @@
1820
[]
1921
);
2022
23+
// Delete functionality state
24+
let showDeleteDialog = $state(false);
25+
2126
async function handleExportClick() {
2227
try {
2328
const allConversations = conversations();
2429
if (allConversations.length === 0) {
25-
alert('No conversations to export');
30+
toast.info('No conversations to export');
2631
return;
2732
}
2833
@@ -145,6 +150,36 @@
145150
alert('Failed to import conversations. Please check the file format.');
146151
}
147152
}
153+
154+
async function handleDeleteAllClick() {
155+
try {
156+
const allConversations = conversations();
157+
158+
if (allConversations.length === 0) {
159+
toast.info('No conversations to delete');
160+
return;
161+
}
162+
163+
showDeleteDialog = true;
164+
} catch (err) {
165+
console.error('Failed to load conversations for deletion:', err);
166+
toast.error('Failed to load conversations');
167+
}
168+
}
169+
170+
async function handleDeleteAllConfirm() {
171+
try {
172+
await conversationsStore.deleteAll();
173+
174+
showDeleteDialog = false;
175+
} catch (err) {
176+
console.error('Failed to delete conversations:', err);
177+
}
178+
}
179+
180+
function handleDeleteAllCancel() {
181+
showDeleteDialog = false;
182+
}
148183
</script>
149184

150185
<div class="space-y-6">
@@ -229,6 +264,25 @@
229264
</div>
230265
{/if}
231266
</div>
267+
268+
<div class="grid border-t border-border/30 pt-4">
269+
<h4 class="mb-2 text-sm font-medium text-destructive">Delete All Conversations</h4>
270+
271+
<p class="mb-4 text-sm text-muted-foreground">
272+
Permanently delete all conversations and their messages. This action cannot be undone.
273+
Consider exporting your conversations first if you want to keep a backup.
274+
</p>
275+
276+
<Button
277+
class="text-destructive-foreground w-full justify-start justify-self-start bg-destructive hover:bg-destructive/80 md:w-auto"
278+
onclick={handleDeleteAllClick}
279+
variant="destructive"
280+
>
281+
<Trash2 class="mr-2 h-4 w-4" />
282+
283+
Delete all conversations
284+
</Button>
285+
</div>
232286
</div>
233287
</div>
234288

@@ -249,3 +303,15 @@
249303
onCancel={() => (showImportDialog = false)}
250304
onConfirm={handleImportConfirm}
251305
/>
306+
307+
<DialogConfirmation
308+
bind:open={showDeleteDialog}
309+
title="Delete all conversations"
310+
description="Are you sure you want to delete all conversations? This action cannot be undone and will permanently remove all your conversations and messages."
311+
confirmText="Delete All"
312+
cancelText="Cancel"
313+
variant="destructive"
314+
icon={Trash2}
315+
onConfirm={handleDeleteAllConfirm}
316+
onCancel={handleDeleteAllCancel}
317+
/>

tools/server/webui/src/lib/stores/conversations.svelte.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,15 +385,37 @@ class ConversationsStore {
385385
this.conversations = this.conversations.filter((c) => c.id !== convId);
386386

387387
if (this.activeConversation?.id === convId) {
388-
this.activeConversation = null;
389-
this.activeMessages = [];
388+
this.clearActiveConversation();
390389
await goto(`?new_chat=true#/`);
391390
}
392391
} catch (error) {
393392
console.error('Failed to delete conversation:', error);
394393
}
395394
}
396395

396+
/**
397+
* Deletes all conversations and their messages
398+
*/
399+
async deleteAll(): Promise<void> {
400+
try {
401+
const allConversations = await DatabaseService.getAllConversations();
402+
403+
for (const conv of allConversations) {
404+
await DatabaseService.deleteConversation(conv.id);
405+
}
406+
407+
this.clearActiveConversation();
408+
this.conversations = [];
409+
410+
toast.success('All conversations deleted');
411+
412+
await goto(`?new_chat=true#/`);
413+
} catch (error) {
414+
console.error('Failed to delete all conversations:', error);
415+
toast.error('Failed to delete conversations');
416+
}
417+
}
418+
397419
// ─────────────────────────────────────────────────────────────────────────────
398420
// Import/Export
399421
// ─────────────────────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)