Files
mediaproc/ui/timeline/src/JobPanel.tsx
2026-03-15 16:03:53 -03:00

82 lines
2.1 KiB
TypeScript

import { useState, useEffect } from "react";
import { getPresets, createJob } from "./api";
import type { MediaAsset, TranscodePreset } from "./types";
interface JobPanelProps {
asset: MediaAsset;
trimStart: number;
trimEnd: number;
onJobCreated: () => void;
}
export default function JobPanel({
asset,
trimStart,
trimEnd,
onJobCreated,
}: JobPanelProps) {
const [presets, setPresets] = useState<TranscodePreset[]>([]);
const [selectedPresetId, setSelectedPresetId] = useState<string>("");
const [submitting, setSubmitting] = useState(false);
useEffect(() => {
getPresets().then(setPresets).catch(console.error);
}, []);
const hasTrim =
trimStart > 0 || (asset.duration != null && trimEnd < asset.duration);
const hasPreset = selectedPresetId !== "";
const canSubmit = hasTrim || hasPreset;
const buttonLabel = hasPreset
? "Transcode"
: hasTrim
? "Trim (Copy)"
: "Select trim or preset";
async function handleSubmit() {
setSubmitting(true);
try {
await createJob({
source_asset_id: asset.id,
preset_id: selectedPresetId || null,
trim_start: hasTrim ? trimStart : null,
trim_end: hasTrim ? trimEnd : null,
output_filename: null,
priority: 0,
});
onJobCreated();
} catch (e) {
alert(e instanceof Error ? e.message : "Failed to create job");
} finally {
setSubmitting(false);
}
}
return (
<div className="job-panel">
<div className="job-controls">
<select
value={selectedPresetId}
onChange={(e) => setSelectedPresetId(e.target.value)}
className="preset-select"
>
<option value="">No preset (trim only)</option>
{presets.map((p) => (
<option key={p.id} value={p.id}>
{p.name}
</option>
))}
</select>
<button
onClick={handleSubmit}
disabled={!canSubmit || submitting}
className="enqueue-button"
>
{submitting ? "Submitting..." : buttonLabel}
</button>
</div>
</div>
);
}