Let queued video, image, and music jobs open in an inspect modal.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+21
-25
@@ -11,7 +11,7 @@
|
||||
<div>
|
||||
<h2 class="font-display text-2xl font-bold">Queue</h2>
|
||||
<p class="mt-1 max-w-2xl text-sm text-zinc-400">
|
||||
Jobs you submitted from Studio or Music. A long shot script is one job; its shots are the list underneath. Run next inserts a waiting job after the current shot as its own clip.
|
||||
Click a job to inspect it, fix a waiting one, copy it, or save a template. A long shot script is one job; its shots are the list underneath.
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-2 sm:gap-3">
|
||||
@@ -57,7 +57,7 @@
|
||||
>
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-start gap-3">
|
||||
<button type="button" class="flex min-w-0 items-start gap-3 text-left" @click="inspectJobId = job.id">
|
||||
<img
|
||||
v-if="jobThumb(job)"
|
||||
:src="jobThumb(job)"
|
||||
@@ -65,18 +65,18 @@
|
||||
class="h-12 w-12 shrink-0 rounded-lg bg-black/40 object-cover"
|
||||
>
|
||||
<div class="min-w-0">
|
||||
<p class="text-[11px] uppercase tracking-[0.18em] text-zinc-500">{{ jobKindLabel(job) }}</p>
|
||||
<h3 class="truncate font-display text-lg font-semibold text-zinc-100">{{ job.name }}</h3>
|
||||
<p class="mt-1 text-sm text-zinc-300">{{ jobLine(job) }}</p>
|
||||
<p v-if="job.shots && liveMessage[job.shots.id]" class="mt-1 text-xs text-amber-100">{{ liveMessage[job.shots.id] }}</p>
|
||||
<p v-else-if="liveMessage[job.id]" class="mt-1 text-xs text-amber-100">{{ liveMessage[job.id] }}</p>
|
||||
<p v-if="job.lastError" class="mt-1 text-xs text-red-300">{{ job.lastError }}</p>
|
||||
<p class="text-[11px] uppercase tracking-[0.18em] text-zinc-500">{{ jobKindLabel(job) }}</p>
|
||||
<h3 class="truncate font-display text-lg font-semibold text-zinc-100 hover:text-white">{{ job.name }}</h3>
|
||||
<p class="mt-1 text-sm text-zinc-300">{{ jobLine(job) }}</p>
|
||||
<p v-if="job.shots && liveMessage[job.shots.id]" class="mt-1 text-xs text-amber-100">{{ liveMessage[job.shots.id] }}</p>
|
||||
<p v-else-if="liveMessage[job.id]" class="mt-1 text-xs text-amber-100">{{ liveMessage[job.id] }}</p>
|
||||
<p v-if="job.lastError" class="mt-1 text-xs text-red-300">{{ job.lastError }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button
|
||||
v-if="job.status === 'waiting'"
|
||||
v-if="job.status === 'waiting' && job.kind !== 'music'"
|
||||
type="button"
|
||||
class="rounded-full border border-sky-300/40 px-3 py-1.5 text-xs text-sky-100 hover:border-sky-200 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
:disabled="Boolean(busyId)"
|
||||
@@ -410,6 +410,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
<QueuedJobModal
|
||||
:job-id="inspectJobId"
|
||||
@close="inspectJobId = ''"
|
||||
@saved="loadQueues"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -477,6 +482,7 @@ type PendingRemove = {
|
||||
const videoLoras = ref<string[]>([])
|
||||
const loraTriggers = ref<Record<string, string>>({})
|
||||
const loraAliases = ref<Record<string, string>>({})
|
||||
const inspectJobId = ref('')
|
||||
const jobs = ref<StudioJobRow[]>([])
|
||||
const orphans = ref<Queue[]>([])
|
||||
const waitingCount = ref(0)
|
||||
@@ -573,20 +579,10 @@ function progressLine(queue: Queue) {
|
||||
|
||||
function jobLine(job: StudioJobRow) {
|
||||
if (job.kind === 'music') {
|
||||
if (job.status === 'waiting') {
|
||||
return job.cutIn
|
||||
? 'Next after the current shot · ACE-Step'
|
||||
: 'Waiting · ACE-Step'
|
||||
}
|
||||
if (job.status === 'held') {
|
||||
if (jobIsHeldPaused(job)) return 'Paused. This track will not continue until you resume.'
|
||||
return job.holdForCutIn ? 'Paused so another job can cut in' : 'Paused'
|
||||
}
|
||||
if (job.status === 'running') {
|
||||
if (jobIsLatched(job)) return 'Generating track · will pause after this'
|
||||
return 'Generating track'
|
||||
}
|
||||
return job.status
|
||||
if (job.status === 'waiting') return job.cutIn ? 'Next after the current shot · ACE-Step' : 'Waiting · ACE-Step'
|
||||
if (job.status === 'held') return 'Paused'
|
||||
if (job.status === 'error') return job.lastError || 'Failed'
|
||||
return 'Generating track'
|
||||
}
|
||||
if (job.kind === 'edit') {
|
||||
const passes = job.shotCount || 1
|
||||
@@ -822,7 +818,7 @@ function jobKindLabel(job: StudioJobRow) {
|
||||
if (job.imagePipeline === 'v2') return 'IMAGE V2'
|
||||
return (job.shotCount || 1) > 1 ? 'EDIT' : 'IMAGE'
|
||||
}
|
||||
return 'Job'
|
||||
return 'VIDEO'
|
||||
}
|
||||
|
||||
function jobThumb(job: StudioJobRow) {
|
||||
|
||||
Reference in New Issue
Block a user