diff --git a/frontend/src/components/heaps/HeapsPanel.tsx b/frontend/src/components/heaps/HeapsPanel.tsx index 75fd9cb..c7e4ca1 100644 --- a/frontend/src/components/heaps/HeapsPanel.tsx +++ b/frontend/src/components/heaps/HeapsPanel.tsx @@ -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() { @@ -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" /> ) : ( - - {heap.name} - + <> + + {heap.name} + + {isActive && ( + + Active + + )} + + )} {/* Right cluster. Count is the rightmost element in the diff --git a/frontend/src/components/layout/TopBar.tsx b/frontend/src/components/layout/TopBar.tsx index 4038321..7c7ebad 100644 --- a/frontend/src/components/layout/TopBar.tsx +++ b/frontend/src/components/layout/TopBar.tsx @@ -1,33 +1,17 @@ -import { ShoppingBasket } from 'lucide-react' -import { useHeapsQuery } from '../../hooks/useHeapsQuery' import muliLogo from '../../assets/muli-logo.png' /** - * Slim top bar — just the logo and the active-heap pill. The search input - * lives in the FilterBar now (next to the rest of the filter controls). + * Slim top bar — just the logo. The active heap badge moved into the + * Heaps panel in the left sidebar (where it actually relates to the + * heap rows the user navigates to). */ export function TopBar() { - const { data: heapsList = [] } = useHeapsQuery() - const activeHeap = heapsList.find((h) => h.is_active) - return (
-
-
- Mulimago -

Mulimago

-
- {activeHeap && ( - - - {activeHeap.name} - - )} +
+ Mulimago +

Mulimago

-
) diff --git a/frontend/src/components/timeline/PhotoThumbnail.tsx b/frontend/src/components/timeline/PhotoThumbnail.tsx index aaa85d5..2d20026 100644 --- a/frontend/src/components/timeline/PhotoThumbnail.tsx +++ b/frontend/src/components/timeline/PhotoThumbnail.tsx @@ -18,6 +18,9 @@ interface PhotoThumbnailProps { isSelected: boolean /** True when the photo belongs to the currently active heap. */ isInActiveHeap?: boolean + /** Name of the active heap. When set + isInActiveHeap, the basket + * badge expands into a name chip so the user knows which heap. */ + activeHeapName?: string | null onClick: (e: React.MouseEvent) => void onDoubleClick?: (e: React.MouseEvent) => void } @@ -27,6 +30,7 @@ export function PhotoThumbnail({ size, isSelected, isInActiveHeap = false, + activeHeapName = null, onClick, onDoubleClick, }: PhotoThumbnailProps) { @@ -210,10 +214,15 @@ export function PhotoThumbnail({
{isInActiveHeap && (
- + + {activeHeapName && ( + + {activeHeapName} + + )}
)} {photo.is_duplicate && ( diff --git a/frontend/src/components/timeline/Timeline.tsx b/frontend/src/components/timeline/Timeline.tsx index 5e7c5b1..39eb1a5 100644 --- a/frontend/src/components/timeline/Timeline.tsx +++ b/frontend/src/components/timeline/Timeline.tsx @@ -196,7 +196,8 @@ export function Timeline() { // Membership in the active heap (for the basket affordance). Subscribed // once at this level so we don't have hundreds of thumbnails each // subscribing to the same query. - const { memberIds: activeHeapMembers } = useActiveHeapMembers() + const { memberIds: activeHeapMembers, activeHeap } = useActiveHeapMembers() + const activeHeapName = activeHeap?.name ?? null // Build the flat virtualizer items: a mix of group headers and rows of // photos. Date headers appear when sorted by a date field; tag headers @@ -510,6 +511,7 @@ export function Timeline() { size={THUMBNAIL_SIZE} isSelected={selectedPhotos.includes(photo.id)} isInActiveHeap={activeHeapMembers.has(photo.id)} + activeHeapName={activeHeapName} onClick={(e) => { if (e.shiftKey) { selectRange(photo.id)