pipeline: uniform column headers, auto-process queue toggle, reopen → inbox
Build and Push Docker Image / build (push) Successful in 4m3s

column headers are now a fixed three-row layout (title / subtitle / button
row). every column always reserves all three rows so headers line up
regardless of contents; actions render disabled when their column is
empty instead of disappearing, which keeps the header height stable as
state changes.

the processing column gets a new "Auto-process Queue" checkbox that
mirrors the inbox's "Auto-process Inbox" toggle. backend adds an
auto_process_queue config, a maybeStartQueueProcessor() helper, a
POST /api/settings/auto-process-queue endpoint, and a hook in
enqueueAudioJob so approvals drain the queue hands-off when the toggle
is on.

reopen-all and per-item reopen now send items to the Inbox (sorted=0)
instead of back to Review. the done column's label and tooltip become
"← Back to inbox" to match, and the clear button moves to the right
slot so the header pattern (left=backward, right=forward) stays
consistent across columns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-19 21:57:13 +02:00
parent a21bcefb54
commit 0fd3624d9f
14 changed files with 186 additions and 81 deletions
+17 -1
View File
@@ -1,7 +1,7 @@
import { accessSync, constants } from "node:fs";
import { Hono } from "hono";
import { stream } from "hono/streaming";
import { getDb } from "../db/index";
import { getConfig, getDb } from "../db/index";
import { log, error as logError, warn } from "../lib/log";
import { parseId } from "../lib/validate";
import { predictExtractedFiles } from "../services/ffmpeg";
@@ -154,6 +154,22 @@ export function emitInboxSortProgress(processed: number, total: number): void {
for (const l of jobListeners) l(line);
}
/**
* If the queue runner is idle and the auto_process_queue config is on, kick
* off a sequential pass over whatever's currently pending. Used by the
* enqueue path (so a fresh approval immediately starts draining) and by the
* settings toggle (so flipping the checkbox drains existing queue items).
* Returns true when a new run was started.
*/
export function maybeStartQueueProcessor(): boolean {
if (queueRunning) return false;
if (getConfig("auto_process_queue") !== "1") return false;
const pending = getDb().prepare("SELECT * FROM jobs WHERE status = 'pending' ORDER BY created_at").all() as Job[];
if (pending.length === 0) return false;
runSequential(pending).catch((err) => logError("Queue failed:", err));
return true;
}
/** Parse "Duration: HH:MM:SS.MS" from ffmpeg startup output. */
function parseFFmpegDuration(line: string): number | null {
const match = line.match(/Duration:\s*(\d+):(\d+):(\d+)\.(\d+)/);