From b26392a2ca7cd1126c2da10b5f4120820e3d62c0 Mon Sep 17 00:00:00 2001 From: Yusuf Suleman Date: Wed, 1 Apr 2026 17:49:53 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20brain=20tag=20filtering=20=E2=80=94=20c?= =?UTF-8?q?lick=20any=20tag=20to=20filter,=20clear=20pill,=20auto-poll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tags are now clickable buttons on cards and detail sheet - Active tag filter shows as a pill with clear button - Items filtered by tag via API query param - Auto-polling every 3s for pending/processing items - Detail sheet shows raw_content for notes with "Note" label Co-Authored-By: Claude Opus 4.6 (1M context) --- .../lib/pages/brain/AtelierBrainPage.svelte | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/frontend-v2/src/lib/pages/brain/AtelierBrainPage.svelte b/frontend-v2/src/lib/pages/brain/AtelierBrainPage.svelte index b8dfacc..c753898 100644 --- a/frontend-v2/src/lib/pages/brain/AtelierBrainPage.svelte +++ b/frontend-v2/src/lib/pages/brain/AtelierBrainPage.svelte @@ -31,6 +31,9 @@ let folders = $state([]); let tags = $state([]); + // Filter + let activeTag = $state(null); + // Capture let captureInput = $state(''); let capturing = $state(false); @@ -60,6 +63,7 @@ try { const params = new URLSearchParams({ limit: '50' }); if (activeFolder) params.set('folder', activeFolder); + if (activeTag) params.set('tag', activeTag); const data = await api(`/items?${params}`); items = data.items || []; total = data.total || 0; @@ -256,6 +260,18 @@ {/each} + + {#if activeTag} +
+ Filtered by tag: + {activeTag} + +
+ {/if} +
@@ -330,7 +346,7 @@ {#if item.tags && item.tags.length > 0}
{#each item.tags.slice(0, 3) as tag} - {tag} + {/each}
{/if} @@ -403,7 +419,7 @@ {#if selectedItem.tags && selectedItem.tags.length > 0}
{#each selectedItem.tags as tag} - {tag} + {/each}
{/if} @@ -487,6 +503,27 @@ .signal-value { font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 0.95; letter-spacing: -0.05em; color: #1e1812; } .signal-note { color: #4f463d; line-height: 1.6; font-size: 0.85rem; } + /* ═══ Active filter ═══ */ + .active-filter { + display: flex; + align-items: center; + gap: 8px; + padding: 10px 16px; + margin-bottom: 12px; + border-radius: 999px; + background: rgba(179,92,50,0.08); + border: 1px solid rgba(179,92,50,0.15); + width: fit-content; + } + .filter-label { font-size: 0.82rem; color: #7d6f61; } + .filter-tag { font-size: 0.82rem; font-weight: 700; color: #1e1812; } + .filter-clear { + display: flex; align-items: center; gap: 3px; + font-size: 0.78rem; color: #8c7b69; background: none; border: none; + font-family: var(--font); transition: color 160ms; + } + .filter-clear:hover { color: #1e1812; } + /* ═══ Search ═══ */ .search-section { margin-bottom: 18px; } .search-wrap { position: relative; } @@ -619,6 +656,14 @@ font-size: 0.72rem; color: #5d5248; font-weight: 500; + border: none; + font-family: var(--font); + cursor: pointer; + transition: background 160ms, color 160ms; + } + .card-tag:hover { + background: rgba(179,92,50,0.12); + color: #1e1812; } .card-meta { @@ -715,7 +760,10 @@ .detail-tag { background: rgba(35,26,17,0.06); padding: 4px 12px; border-radius: 999px; font-size: 0.85rem; color: #5d5248; + border: none; font-family: var(--font); cursor: pointer; + transition: background 160ms; } + .detail-tag:hover { background: rgba(179,92,50,0.12); color: #1e1812; } .detail-actions { display: flex; gap: 8px; flex-wrap: wrap; } .action-btn {