"use client";
// ONE FRAME FOR EVERY OPERATION on the video page: the section, the heading,
// the freshness pill, and — when the feature is switched off — the word that
// says so. The body inside it is chosen by the operation's `settingsBlock`.
//
// THE VISION TEST. The IA's claim for this registry is that a new operation is
// an entry in a table and nothing else: it should light every surface without a
// new page. The `undefined` arm below is what makes that true here — an
// operation registered with no settings block still gets a panel, a state and
// its output list, with nobody editing this file.
//
// TYPE-ONLY from lib/operations, always: that module imports the digest,
// diarization and attribution servers, all of which reach node:fs. A value
// import would pull the filesystem into this client bundle — the same lesson
// pauseControl.tsx paid for. Labels and hints reach here as PROPS.
import { DigestBody, type DigestBodyData } from "./DigestBody";
import {
AttributionBody,
DiarizationBody,
type AttributionBodyData,
type DiarizationBodyData,
} from "./SpeakerBodies";
import {
stateCopy,
stateTone,
type OperationPanelView,
} from "./operationState";
export type OperationPanelBody =
| { block: "digest"; data: DigestBodyData }
| { block: "diarization"; data: DiarizationBodyData }
| { block: "attribution"; data: AttributionBodyData }
// An operation with no settings block: the outputs list alone.
| { block: undefined };
const TONE_CLASS = {
success: "text-xs font-medium text-success",
warning: "text-xs font-medium text-warning",
muted: "text-xs text-muted-foreground",
} as const;
export function OperationPanel({
slug,
videoId,
view,
body,
}: {
slug: string;
videoId: string;
view: OperationPanelView;
body: OperationPanelBody;
}) {
return (
{view.label}
{o.name} — {o.present ? "present" : "absent"}