web(review): expandable Review group in sidebar, tabs become subitems
Mirrors the Tags affordance: chevron-only toggle, no /review landing entry, navigation only via subitems (cause buckets + Stacks + Cross-folder linked as /review?tab=<id>). Cause list reuses the review-groups query so empty buckets stay hidden. The /review toolbar drops the pill row and shows the active tab as a breadcrumb segment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
approve). The previous section is restored on unmount.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import { createQuery } from '@tanstack/svelte-query';
|
||||
import {
|
||||
@@ -138,49 +137,18 @@
|
||||
});
|
||||
|
||||
const activeGroup = $derived(groups.find((g) => g.cause === activeTab));
|
||||
|
||||
function setTab(id: Tab) {
|
||||
const params = new URLSearchParams();
|
||||
// First cause tab (if any) is the default — same convention as
|
||||
// the old /review behaviour, so back-from-cross-folder lands on
|
||||
// the user's review queue rather than the empty Stacks panel.
|
||||
const defaultId = tabs[0]?.id;
|
||||
if (defaultId !== undefined && id !== defaultId) params.set('tab', id);
|
||||
void goto(`/review${params.size ? '?' + params : ''}`, {
|
||||
keepFocus: true,
|
||||
noScroll: true
|
||||
});
|
||||
}
|
||||
const activeTabSpec = $derived(tabs.find((t) => t.id === activeTab));
|
||||
</script>
|
||||
|
||||
<Toolbar>
|
||||
<span class="rounded-md border border-border px-2 py-0.5 text-[11px] text-muted-foreground">
|
||||
Review
|
||||
</span>
|
||||
{#if tabs.length > 0}
|
||||
<div class="flex items-center gap-1">
|
||||
{#each tabs as t (t.id)}
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-1 rounded border px-2 py-0.5 text-[11px] {activeTab === t.id
|
||||
? 'border-primary/40 bg-primary/10 text-primary'
|
||||
: 'border-border text-muted-foreground hover:bg-accent hover:text-foreground'}"
|
||||
onclick={() => setTab(t.id)}
|
||||
>
|
||||
<span>{t.label}</span>
|
||||
{#if t.count !== undefined}
|
||||
<span
|
||||
class="flex h-4 min-w-4.5 items-center justify-center rounded px-1 text-[10px] tabular-nums {activeTab ===
|
||||
t.id
|
||||
? 'bg-primary/15 text-primary'
|
||||
: 'bg-secondary text-muted-foreground'}"
|
||||
>
|
||||
{t.count}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{#if activeTabSpec}
|
||||
<span class="text-[11px] font-medium">{activeTabSpec.label}</span>
|
||||
{#if activeTabSpec.count !== undefined}
|
||||
<span class="text-[11px] text-muted-foreground">{activeTabSpec.count}</span>
|
||||
{/if}
|
||||
{/if}
|
||||
{#snippet trailing()}
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user