From 031f6d3d5b0a476476840bdb75f20513899e2052 Mon Sep 17 00:00:00 2001 From: jlightner Date: Mon, 30 Mar 2026 19:36:47 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Pruned=20dead=20UI,=20renamed=20view=20?= =?UTF-8?q?toggle=20to=20Oldest/Newest=20first,=20added=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "frontend/src/pages/AdminPipeline.tsx" - "frontend/src/App.css" GSD-Task: S04/T02 --- frontend/src/App.css | 14 ++++++++ frontend/src/pages/AdminPipeline.tsx | 54 +++++++++++++++++----------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/frontend/src/App.css b/frontend/src/App.css index c641cf9..ccd3f53 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -2776,6 +2776,20 @@ a.app-footer__repo:hover { white-space: nowrap; } +.pipeline-video__review-link { + color: var(--color-accent); + font-size: 0.75rem; + text-decoration: none; + white-space: nowrap; + opacity: 0.7; + transition: opacity 0.15s; +} + +.pipeline-video__review-link:hover { + opacity: 1; + text-decoration: underline; +} + .pipeline-video__actions { display: flex; gap: 0.375rem; diff --git a/frontend/src/pages/AdminPipeline.tsx b/frontend/src/pages/AdminPipeline.tsx index f8f9c73..6f10b80 100644 --- a/frontend/src/pages/AdminPipeline.tsx +++ b/frontend/src/pages/AdminPipeline.tsx @@ -245,16 +245,15 @@ function EventLog({ videoId }: { videoId: string }) { className={`pipeline-events__view-btn${viewMode === "head" ? " pipeline-events__view-btn--active" : ""}`} onClick={() => { setViewMode("head"); setOffset(0); }} > - Head + Oldest first -
@@ -368,28 +367,21 @@ function WorkerStatus() { // ── Debug Mode Toggle ──────────────────────────────────────────────────────── -function DebugModeToggle() { - const [debugMode, setDebugModeState] = useState(null); +function DebugModeToggle({ + debugMode, + onDebugModeChange, +}: { + debugMode: boolean | null; + onDebugModeChange: (mode: boolean) => void; +}) { const [debugLoading, setDebugLoading] = useState(false); - useEffect(() => { - let cancelled = false; - fetchDebugMode() - .then((res) => { - if (!cancelled) setDebugModeState(res.debug_mode); - }) - .catch(() => { - // silently fail — toggle stays hidden - }); - return () => { cancelled = true; }; - }, []); - async function handleToggle() { if (debugMode === null || debugLoading) return; setDebugLoading(true); try { const res = await setDebugMode(!debugMode); - setDebugModeState(res.debug_mode); + onDebugModeChange(res.debug_mode); } catch { // swallow — leave previous state } finally { @@ -463,6 +455,7 @@ export default function AdminPipeline() { const [actionLoading, setActionLoading] = useState(null); const [actionMessage, setActionMessage] = useState<{ id: string; text: string; ok: boolean } | null>(null); const [activeFilter, setActiveFilter] = useState(null); + const [debugMode, setDebugModeState] = useState(null); const load = useCallback(async () => { setLoading(true); @@ -481,6 +474,18 @@ export default function AdminPipeline() { void load(); }, [load]); + useEffect(() => { + let cancelled = false; + fetchDebugMode() + .then((res) => { + if (!cancelled) setDebugModeState(res.debug_mode); + }) + .catch(() => { + // silently fail — toggle stays hidden + }); + return () => { cancelled = true; }; + }, []); + const handleTrigger = async (videoId: string) => { setActionLoading(videoId); setActionMessage(null); @@ -538,7 +543,7 @@ export default function AdminPipeline() {

- +
e.stopPropagation()}> @@ -597,7 +610,7 @@ export default function AdminPipeline() { disabled={actionLoading === video.id} title="Retrigger pipeline" > - {actionLoading === video.id ? "…" : "▶ Trigger"} + {actionLoading === video.id ? "…" : debugMode ? "▶ Trigger (debug)" : "▶ Trigger"}