webui: add "delete all conversations" button to import/export tab (#17444)
* 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() * chore: update webui build output
This commit is contained in:
parent
b1f3a6e5db
commit
e73d548659
Binary file not shown.
|
|
@ -1,9 +1,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Download, Upload } from '@lucide/svelte';
|
import { Download, Upload, Trash2 } from '@lucide/svelte';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { DialogConversationSelection } from '$lib/components/app';
|
import { DialogConversationSelection } from '$lib/components/app';
|
||||||
import { createMessageCountMap } from '$lib/utils';
|
import { createMessageCountMap } from '$lib/utils';
|
||||||
import { conversationsStore, conversations } from '$lib/stores/conversations.svelte';
|
import { conversationsStore, conversations } from '$lib/stores/conversations.svelte';
|
||||||
|
import { toast } from 'svelte-sonner';
|
||||||
|
import DialogConfirmation from '$lib/components/app/dialogs/DialogConfirmation.svelte';
|
||||||
|
|
||||||
let exportedConversations = $state<DatabaseConversation[]>([]);
|
let exportedConversations = $state<DatabaseConversation[]>([]);
|
||||||
let importedConversations = $state<DatabaseConversation[]>([]);
|
let importedConversations = $state<DatabaseConversation[]>([]);
|
||||||
|
|
@ -18,11 +20,14 @@
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Delete functionality state
|
||||||
|
let showDeleteDialog = $state(false);
|
||||||
|
|
||||||
async function handleExportClick() {
|
async function handleExportClick() {
|
||||||
try {
|
try {
|
||||||
const allConversations = conversations();
|
const allConversations = conversations();
|
||||||
if (allConversations.length === 0) {
|
if (allConversations.length === 0) {
|
||||||
alert('No conversations to export');
|
toast.info('No conversations to export');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,6 +150,36 @@
|
||||||
alert('Failed to import conversations. Please check the file format.');
|
alert('Failed to import conversations. Please check the file format.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleDeleteAllClick() {
|
||||||
|
try {
|
||||||
|
const allConversations = conversations();
|
||||||
|
|
||||||
|
if (allConversations.length === 0) {
|
||||||
|
toast.info('No conversations to delete');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
showDeleteDialog = true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to load conversations for deletion:', err);
|
||||||
|
toast.error('Failed to load conversations');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleDeleteAllConfirm() {
|
||||||
|
try {
|
||||||
|
await conversationsStore.deleteAll();
|
||||||
|
|
||||||
|
showDeleteDialog = false;
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to delete conversations:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDeleteAllCancel() {
|
||||||
|
showDeleteDialog = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
|
|
@ -229,6 +264,25 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid border-t border-border/30 pt-4">
|
||||||
|
<h4 class="mb-2 text-sm font-medium text-destructive">Delete All Conversations</h4>
|
||||||
|
|
||||||
|
<p class="mb-4 text-sm text-muted-foreground">
|
||||||
|
Permanently delete all conversations and their messages. This action cannot be undone.
|
||||||
|
Consider exporting your conversations first if you want to keep a backup.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
class="text-destructive-foreground w-full justify-start justify-self-start bg-destructive hover:bg-destructive/80 md:w-auto"
|
||||||
|
onclick={handleDeleteAllClick}
|
||||||
|
variant="destructive"
|
||||||
|
>
|
||||||
|
<Trash2 class="mr-2 h-4 w-4" />
|
||||||
|
|
||||||
|
Delete all conversations
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -249,3 +303,15 @@
|
||||||
onCancel={() => (showImportDialog = false)}
|
onCancel={() => (showImportDialog = false)}
|
||||||
onConfirm={handleImportConfirm}
|
onConfirm={handleImportConfirm}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<DialogConfirmation
|
||||||
|
bind:open={showDeleteDialog}
|
||||||
|
title="Delete all conversations"
|
||||||
|
description="Are you sure you want to delete all conversations? This action cannot be undone and will permanently remove all your conversations and messages."
|
||||||
|
confirmText="Delete All"
|
||||||
|
cancelText="Cancel"
|
||||||
|
variant="destructive"
|
||||||
|
icon={Trash2}
|
||||||
|
onConfirm={handleDeleteAllConfirm}
|
||||||
|
onCancel={handleDeleteAllCancel}
|
||||||
|
/>
|
||||||
|
|
|
||||||
|
|
@ -385,8 +385,7 @@ class ConversationsStore {
|
||||||
this.conversations = this.conversations.filter((c) => c.id !== convId);
|
this.conversations = this.conversations.filter((c) => c.id !== convId);
|
||||||
|
|
||||||
if (this.activeConversation?.id === convId) {
|
if (this.activeConversation?.id === convId) {
|
||||||
this.activeConversation = null;
|
this.clearActiveConversation();
|
||||||
this.activeMessages = [];
|
|
||||||
await goto(`?new_chat=true#/`);
|
await goto(`?new_chat=true#/`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -394,6 +393,29 @@ class ConversationsStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all conversations and their messages
|
||||||
|
*/
|
||||||
|
async deleteAll(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const allConversations = await DatabaseService.getAllConversations();
|
||||||
|
|
||||||
|
for (const conv of allConversations) {
|
||||||
|
await DatabaseService.deleteConversation(conv.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearActiveConversation();
|
||||||
|
this.conversations = [];
|
||||||
|
|
||||||
|
toast.success('All conversations deleted');
|
||||||
|
|
||||||
|
await goto(`?new_chat=true#/`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to delete all conversations:', error);
|
||||||
|
toast.error('Failed to delete conversations');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
// Import/Export
|
// Import/Export
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue