feat(web): tabbed On-the-Press view + kebab menu for press actions
The press page interleaved active downloads, queued items, and errors in one long list — hard to see what's actually pressing. Split the non-imported rows into three tabs (Active / In queue / Errors) with live counts; the default tab follows the work (Active if anything's running, else Queue, else Errors) until the user picks one. Move the press-level actions (Pause/Resume, Clear queue, Stop now) off the toolbar into a vertical "⋮" kebab menu on the right of the header — Clear queue disables when the queue is empty, Stop now only shows while downloading. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState, type ReactNode } from "react";
|
||||
|
||||
/** A vertical "⋮" trigger that opens a small popup menu. Closes on outside click, Escape, or any
|
||||
* click inside the popup (so menu items don't each need to manage it). Children are the items —
|
||||
* use <button className="menu-item">…</button>. */
|
||||
export function KebabMenu({ label = "Actions", children }: { label?: string; children: ReactNode }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
function onDoc(e: MouseEvent) {
|
||||
if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);
|
||||
}
|
||||
function onKey(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") setOpen(false);
|
||||
}
|
||||
document.addEventListener("mousedown", onDoc);
|
||||
document.addEventListener("keydown", onKey);
|
||||
return () => {
|
||||
document.removeEventListener("mousedown", onDoc);
|
||||
document.removeEventListener("keydown", onKey);
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<div className="menu" ref={ref}>
|
||||
<button
|
||||
type="button"
|
||||
className="menu-trigger"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={open}
|
||||
aria-label={label}
|
||||
onClick={() => setOpen((o) => !o)}
|
||||
>
|
||||
⋮
|
||||
</button>
|
||||
{open ? (
|
||||
<div className="menu-pop" role="menu" onClick={() => setOpen(false)}>
|
||||
{children}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user