From 37b2b82ae566d62eb7a3c32e2c434dbae52bc431 Mon Sep 17 00:00:00 2001 From: DexterFromLab Date: Sun, 15 Mar 2026 17:24:40 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20add=20Clear=20All=20button=20to=20Comms?= =?UTF-8?q?Tab=20=E2=80=94=20purge=20all=20messages=20from=20DB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src-tauri/src/btmsg.rs | 29 ++++++++++ src-tauri/src/commands/btmsg.rs | 5 ++ src-tauri/src/lib.rs | 1 + src/lib/adapters/btmsg-bridge.ts | 7 +++ src/lib/components/Workspace/CommsTab.svelte | 58 ++++++++++++++++++++ 5 files changed, 100 insertions(+) diff --git a/src-tauri/src/btmsg.rs b/src-tauri/src/btmsg.rs index 1cb1b16..55fdf91 100644 --- a/src-tauri/src/btmsg.rs +++ b/src-tauri/src/btmsg.rs @@ -877,6 +877,35 @@ pub fn clear_dead_letters(group_id: &str) -> Result<(), String> { 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 ---- #[derive(Debug, Serialize, Deserialize)] diff --git a/src-tauri/src/commands/btmsg.rs b/src-tauri/src/commands/btmsg.rs index 687dd6a..d2cfa3b 100644 --- a/src-tauri/src/commands/btmsg.rs +++ b/src-tauri/src/commands/btmsg.rs @@ -124,6 +124,11 @@ pub fn btmsg_clear_dead_letters(group_id: String) -> Result<(), String> { 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] pub fn btmsg_queue_dead_letter( from_agent: String, diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 8e00846..e313df7 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -277,6 +277,7 @@ pub fn run() { commands::btmsg::btmsg_get_agent_heartbeats, commands::btmsg::btmsg_get_dead_letters, commands::btmsg::btmsg_clear_dead_letters, + commands::btmsg::btmsg_clear_all_comms, commands::btmsg::btmsg_queue_dead_letter, // Audit log commands::btmsg::audit_log_event, diff --git a/src/lib/adapters/btmsg-bridge.ts b/src/lib/adapters/btmsg-bridge.ts index 579cb8d..931ab53 100644 --- a/src/lib/adapters/btmsg-bridge.ts +++ b/src/lib/adapters/btmsg-bridge.ts @@ -232,3 +232,10 @@ export async function getDeadLetters(groupId: GroupId, limit: number = 50): Prom export async function clearDeadLetters(groupId: GroupId): Promise { 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 { + return invoke('btmsg_clear_all_comms', { groupId }); +} diff --git a/src/lib/components/Workspace/CommsTab.svelte b/src/lib/components/Workspace/CommsTab.svelte index 2202134..bb58f1c 100644 --- a/src/lib/components/Workspace/CommsTab.svelte +++ b/src/lib/components/Workspace/CommsTab.svelte @@ -1,5 +1,6 @@
@@ -199,6 +225,14 @@
Messages +
@@ -383,6 +417,30 @@ .conv-header { padding: 0.5rem 0.75rem; 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 {