"use client"; import Link from "next/link"; import type { ActiveLaneView } from "yt-dlp-transcript-common/views/activeJobs"; import type { JobRowView } from "yt-dlp-transcript-common/views/jobRowView"; import { LANE_DOT, LANE_TEXT, LANE_WORD } from "yt-dlp-transcript-common/views/laneState"; import { JobRowActions } from "./JobRow"; // THE LANE STRIP. One line per pipeline, in place of one card per runner. // // Each lane keeps its
and its

, so a // runner is still addressable exactly as it was — what changed is that it costs // a line instead of a card, and that it now says WHY it is not working. Four // bordered cards saying "running" above the work with the progress bars is the // layout this replaces. // // A LANE IS NOT A JOB, so this is not a JobRow: it keeps its own line (the // suite pins the section, the heading and the Drain/Cancel on it). What it // shares with every job row is the actions — its runner job's buttons are // JobRowActions, the same status rules as /jobs and the card list. export function LaneStrip({ lanes, jobs, }: { lanes: ActiveLaneView[]; // kind -> the channel-less jobs of that kind. A lane has at most one (its own // long-lived runner or sweep job); its controls ride on the lane's line. jobs: Map; }) { if (lanes.length === 0) return null; return (

Lanes

{lanes.map((lane) => ( ))}
); } function LaneRow({ lane, job, }: { lane: ActiveLaneView; job: JobRowView | undefined; }) { return (
); }