feat: add Clear All button to CommsTab — purge all messages from DB
Adds trash icon button in Messages header that clears all communications for the active group: DMs, channel messages, activity feed, seen tracking, and dead letters. Shows Tauri warning dialog with confirmation before delete. - Rust: clear_all_communications() in btmsg.rs (4 DELETE queries) - Tauri command: btmsg_clear_all_comms - Bridge: clearAllComms(groupId) - UI: trash button with hover-red styling, resets all local state after clear
This commit is contained in:
parent
6504a79bfe
commit
37b2b82ae5
5 changed files with 100 additions and 0 deletions
|
|
@ -877,6 +877,35 @@ pub fn clear_dead_letters(group_id: &str) -> Result<(), String> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clear all communications for a group: messages, channel messages, seen tracking, dead letters
|
||||||
|
pub fn clear_all_communications(group_id: &str) -> Result<(), String> {
|
||||||
|
let db = open_db()?;
|
||||||
|
let agent_ids_clause = "(SELECT id FROM agents WHERE group_id = ?1)";
|
||||||
|
|
||||||
|
// Order matters: seen_messages references messages, so delete seen first
|
||||||
|
db.execute(
|
||||||
|
&format!("DELETE FROM seen_messages WHERE message_id IN (SELECT id FROM messages WHERE group_id = ?1 OR from_agent IN {agent_ids_clause} OR to_agent IN {agent_ids_clause})"),
|
||||||
|
params![group_id],
|
||||||
|
).map_err(|e| format!("Clear seen_messages error: {e}"))?;
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
&format!("DELETE FROM messages WHERE group_id = ?1 OR from_agent IN {agent_ids_clause} OR to_agent IN {agent_ids_clause}"),
|
||||||
|
params![group_id],
|
||||||
|
).map_err(|e| format!("Clear messages error: {e}"))?;
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
&format!("DELETE FROM channel_messages WHERE channel_id IN (SELECT id FROM channels WHERE group_id = ?1) OR from_agent IN {agent_ids_clause}"),
|
||||||
|
params![group_id],
|
||||||
|
).map_err(|e| format!("Clear channel_messages error: {e}"))?;
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
&format!("DELETE FROM dead_letter_queue WHERE from_agent IN {agent_ids_clause} OR to_agent IN {agent_ids_clause}"),
|
||||||
|
params![group_id],
|
||||||
|
).map_err(|e| format!("Clear dead_letter_queue error: {e}"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Audit log ----
|
// ---- Audit log ----
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,11 @@ pub fn btmsg_clear_dead_letters(group_id: String) -> Result<(), String> {
|
||||||
btmsg::clear_dead_letters(&group_id)
|
btmsg::clear_dead_letters(&group_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn btmsg_clear_all_comms(group_id: String) -> Result<(), String> {
|
||||||
|
btmsg::clear_all_communications(&group_id)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn btmsg_queue_dead_letter(
|
pub fn btmsg_queue_dead_letter(
|
||||||
from_agent: String,
|
from_agent: String,
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,7 @@ pub fn run() {
|
||||||
commands::btmsg::btmsg_get_agent_heartbeats,
|
commands::btmsg::btmsg_get_agent_heartbeats,
|
||||||
commands::btmsg::btmsg_get_dead_letters,
|
commands::btmsg::btmsg_get_dead_letters,
|
||||||
commands::btmsg::btmsg_clear_dead_letters,
|
commands::btmsg::btmsg_clear_dead_letters,
|
||||||
|
commands::btmsg::btmsg_clear_all_comms,
|
||||||
commands::btmsg::btmsg_queue_dead_letter,
|
commands::btmsg::btmsg_queue_dead_letter,
|
||||||
// Audit log
|
// Audit log
|
||||||
commands::btmsg::audit_log_event,
|
commands::btmsg::audit_log_event,
|
||||||
|
|
|
||||||
|
|
@ -232,3 +232,10 @@ export async function getDeadLetters(groupId: GroupId, limit: number = 50): Prom
|
||||||
export async function clearDeadLetters(groupId: GroupId): Promise<void> {
|
export async function clearDeadLetters(groupId: GroupId): Promise<void> {
|
||||||
return invoke('btmsg_clear_dead_letters', { groupId });
|
return invoke('btmsg_clear_dead_letters', { groupId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear ALL communications for a group: messages, channel messages, seen tracking, dead letters.
|
||||||
|
*/
|
||||||
|
export async function clearAllComms(groupId: GroupId): Promise<void> {
|
||||||
|
return invoke('btmsg_clear_all_comms', { groupId });
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
|
import { confirm } from '@tauri-apps/plugin-dialog';
|
||||||
import { getActiveGroup, emitAgentStart } from '../../stores/workspace.svelte';
|
import { getActiveGroup, emitAgentStart } from '../../stores/workspace.svelte';
|
||||||
import {
|
import {
|
||||||
type BtmsgAgent,
|
type BtmsgAgent,
|
||||||
|
|
@ -18,6 +19,7 @@
|
||||||
sendChannelMessage,
|
sendChannelMessage,
|
||||||
createChannel,
|
createChannel,
|
||||||
setAgentStatus,
|
setAgentStatus,
|
||||||
|
clearAllComms,
|
||||||
} from '../../adapters/btmsg-bridge';
|
} from '../../adapters/btmsg-bridge';
|
||||||
|
|
||||||
const ADMIN_ID = 'admin';
|
const ADMIN_ID = 'admin';
|
||||||
|
|
@ -192,6 +194,30 @@
|
||||||
if (view.type === 'channel' && currentView.type === 'channel') return view.channelId === currentView.channelId;
|
if (view.type === 'channel' && currentView.type === 'channel') return view.channelId === currentView.channelId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let clearing = $state(false);
|
||||||
|
|
||||||
|
async function handleClearAll() {
|
||||||
|
if (!groupId || clearing) return;
|
||||||
|
const confirmed = await confirm(
|
||||||
|
'All messages, channel history, activity feed, and unread indicators will be permanently deleted.\n\nThis action cannot be undone.',
|
||||||
|
{ title: 'Clear all communications?', kind: 'warning' },
|
||||||
|
);
|
||||||
|
if (!confirmed) return;
|
||||||
|
clearing = true;
|
||||||
|
try {
|
||||||
|
await clearAllComms(groupId);
|
||||||
|
feedMessages = [];
|
||||||
|
dmMessages = [];
|
||||||
|
channelMessages = [];
|
||||||
|
currentView = { type: 'feed' };
|
||||||
|
await loadData();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[CommsTab] clearAllComms failed:', e);
|
||||||
|
} finally {
|
||||||
|
clearing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="comms-tab">
|
<div class="comms-tab">
|
||||||
|
|
@ -199,6 +225,14 @@
|
||||||
<div class="conv-list">
|
<div class="conv-list">
|
||||||
<div class="conv-header">
|
<div class="conv-header">
|
||||||
<span class="conv-header-title">Messages</span>
|
<span class="conv-header-title">Messages</span>
|
||||||
|
<button
|
||||||
|
class="clear-all-btn"
|
||||||
|
onclick={handleClearAll}
|
||||||
|
disabled={clearing}
|
||||||
|
title="Clear all messages and activity feed"
|
||||||
|
>
|
||||||
|
{clearing ? '...' : '🗑'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Activity Feed -->
|
<!-- Activity Feed -->
|
||||||
|
|
@ -383,6 +417,30 @@
|
||||||
.conv-header {
|
.conv-header {
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
border-bottom: 1px solid var(--ctp-surface0);
|
border-bottom: 1px solid var(--ctp-surface0);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-all-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--ctp-overlay0);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.125rem 0.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-all-btn:hover {
|
||||||
|
color: var(--ctp-red);
|
||||||
|
background: color-mix(in srgb, var(--ctp-red) 10%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-all-btn:disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.conv-header-title {
|
.conv-header-title {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue