feat: surface active heap on photos + sidebar row, drop topbar pill

- PhotoThumbnail: the bottom-right basket badge now expands into a
  name chip when the active heap name is supplied. Truncated to a
  120px max-width so it doesn't eat the thumbnail.
- Timeline: read activeHeap.name from useActiveHeapMembersQuery and
  pipe it down to PhotoThumbnail.
- TopBar: drop the leftover heap pill next to "Mulimago" — the active
  state now lives where the user navigates to it (the heaps row).
- HeapsPanel: the active heap row gets a soft bg-pick/10 wash when
  not also filtered, the basket icon turns text-pick, and a small
  "ACTIVE" pill renders next to the name. Together they make it
  obvious which heap Pick / T target without needing the topbar pill.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-08 22:27:22 +02:00
parent 9317730885
commit e49f64659e
4 changed files with 47 additions and 33 deletions

View File

@@ -266,6 +266,10 @@ export function HeapsPanel() {
className={clsx(
'group relative flex cursor-pointer items-center gap-1 rounded px-2 py-1 text-[13px]',
isFiltered ? 'bg-primary/20 text-primary' : 'text-text hover:bg-surface-2',
// Active-heap row gets a left accent stripe so the
// user always knows where Pick / T will land, even
// when navigating to a different section.
isActive && !isFiltered && 'bg-pick/10 text-text',
isDropTarget && 'ring-2 ring-primary bg-primary/10'
)}
style={{ paddingLeft: '32px' }}
@@ -308,7 +312,11 @@ export function HeapsPanel() {
<ShoppingBasket
className={clsx(
'h-4 w-4 flex-shrink-0',
isFiltered ? 'text-primary' : 'text-text-muted'
isActive
? 'text-pick'
: isFiltered
? 'text-primary'
: 'text-text-muted'
)}
/>
@@ -330,12 +338,23 @@ export function HeapsPanel() {
className="flex-1 rounded border border-border bg-bg px-1 py-0 text-[13px] text-text focus:border-primary focus:outline-none"
/>
) : (
<span
className={clsx('flex-1 truncate', isActive && 'font-semibold')}
title={heap.name}
>
{heap.name}
</span>
<>
<span
className={clsx('truncate', isActive && 'font-semibold')}
title={heap.name}
>
{heap.name}
</span>
{isActive && (
<span
className="ml-1 flex-shrink-0 rounded-full bg-pick/25 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-pick"
title="Active heap — Pick (P) and the basket badge on photos point here"
>
Active
</span>
)}
<span className="flex-1" />
</>
)}
{/* Right cluster. Count is the rightmost element in the