feat(frontend): review-status filter, badge, and review toggles
deploy / deploy (push) Successful in 1m28s

FilterBar gains an Any/Needs review/Reviewed segment (r=1/r=0 token);
FileCard shows a "needs review" dot; FileViewer gets a header toggle that
propagates back to the grid; SelectionBar gains a bulk "Mark reviewed"
action. Adds a --color-success theme token.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 21:17:11 +03:00
parent 5bb53d7f9d
commit a864ca4f7b
7 changed files with 161 additions and 3 deletions
+19
View File
@@ -114,6 +114,22 @@
void tick().then(() => document.querySelector<HTMLInputElement>('.tag-sheet input')?.focus());
}
// Mark the current selection as review-done (tagging finished). Best-effort
// optimistic update of the local list so the "needs review" badges clear.
async function markSelectionReviewed() {
const ids = [...$selectionStore.ids];
if (ids.length === 0) return;
selectionStore.exit();
try {
await api.post('/files/bulk/review', { file_ids: ids, needs_review: false });
files = files.map((f) =>
ids.includes(f.id ?? '') ? { ...f, needs_review: false } : f
);
} catch {
// ignore — list already reflects the intended state optimistically
}
}
function openFilterAndFocus() {
filterOpen = true;
void tick().then(() => document.querySelector<HTMLInputElement>('.bar .search')?.focus());
@@ -835,6 +851,8 @@
nextId={viewerNextId}
onNavigate={pageTo}
onClose={closeViewer}
onReviewChange={(id, nr) =>
(files = files.map((f) => (f.id === id ? { ...f, needs_review: nr } : f)))}
/>
</div>
{/if}
@@ -843,6 +861,7 @@
<SelectionBar
onEditTags={openTagEditor}
onAddToPool={openPoolPicker}
onMarkReviewed={markSelectionReviewed}
onDelete={() => (confirmDeleteFiles = true)}
/>
{/if}