ui(layout): move Date filter inputs to topbar, Active Heap to right sidebar

- FilterBar: new Date pill hosts from/to inputs; calendar stays in left
  sidebar (always visible, no collapse) with reduced padding and a
  taller MONTH_HEIGHT so 6-week months render fully.
- LeftSidebar: drop Library collapse; Heaps regains its chevron toggle
  to match Views/Folders.
- RightSidebar: render ActiveHeapCard above the Metadata header (with
  its own eyebrow); preview overlay reuses RightSidebar so the active
  heap stays visible there too.
- Toaster: top-right, more compact (smaller padding, font, gap).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-15 21:21:57 +02:00
parent c5582ffc65
commit e6ca78881f
8 changed files with 107 additions and 230 deletions

View File

@@ -44,27 +44,13 @@ import {
* - filter heapId: which heap is currently filtered to (visual)
* - heap.is_active: which heap T adds to (server-side, single per row)
*/
interface HeapsPanelProps {
/** Controlled expand state. When both props are supplied the panel
* defers to the parent for collapse/expand, so the sidebar's pane
* sizing layer can flex the Heaps pane only when it is open. */
expanded?: boolean
onExpandedChange?: (expanded: boolean) => void
}
export function HeapsPanel({ expanded: expandedProp, onExpandedChange }: HeapsPanelProps = {}) {
export function HeapsPanel() {
const { data: heaps = [] } = useHeapsQuery()
const navigateToSection = useFilterStore((s) => s.navigateToSection)
const currentSection = useFilterStore((s) => s.currentSection)
const queryClient = useQueryClient()
const [expandedInternal, setExpandedInternal] = useState(true)
const expanded = expandedProp ?? expandedInternal
const setExpanded = (next: boolean | ((prev: boolean) => boolean)) => {
const resolved = typeof next === 'function' ? (next as (p: boolean) => boolean)(expanded) : next
if (onExpandedChange) onExpandedChange(resolved)
else setExpandedInternal(resolved)
}
const [expanded, setExpanded] = useState(true)
const [creating, setCreating] = useState(false)
const [newName, setNewName] = useState('')
// Which heap row is currently being hovered with a drag — used to render
@@ -188,9 +174,9 @@ export function HeapsPanel({ expanded: expandedProp, onExpandedChange }: HeapsPa
return (
<div>
{/* Section header — mirrors the Folders section eyebrow in
* LeftSidebar so Heaps sits alongside it at the same visual
* tier, with heap rows indented the same as folder rows. */}
{/* Section header — mirrors the Views/Folders section eyebrows
* in LeftSidebar so Heaps sits alongside them at the same
* visual tier, including the click-to-collapse chevron. */}
<div
className="group mt-2 flex cursor-pointer items-center gap-1 px-3 py-1 text-[10px] font-semibold uppercase tracking-[0.14em] text-text-muted hover:text-text"
onClick={() => setExpanded((v) => !v)}
@@ -226,7 +212,7 @@ export function HeapsPanel({ expanded: expandedProp, onExpandedChange }: HeapsPa
</div>
{expanded && (
<div>
<div>
{/* Inline create form */}
{creating && (
<div
@@ -490,7 +476,7 @@ export function HeapsPanel({ expanded: expandedProp, onExpandedChange }: HeapsPa
</div>
)
})}
</div>
</div>
)}
{/* Shared with me */}