crosssubtitle-ai/src/components/TaskQueue.vue
2026-03-19 11:54:44 +08:00

62 lines
1.6 KiB
Vue

<script setup lang="ts">
import type { SubtitleTask } from '../lib/types'
defineProps<{
tasks: SubtitleTask[]
selectedTaskId: string
}>()
const emit = defineEmits<{
select: [taskId: string]
}>()
const statusLabel: Record<SubtitleTask['status'], string> = {
queued: '排队中',
extracting: '抽取',
vad_processing: 'VAD',
transcribing: '识别',
translating: '翻译',
completed: '完成',
failed: '失败',
}
</script>
<template>
<aside class="panel sidebar-panel">
<div class="panel-title">
<div>
<strong>任务队列</strong>
<p class="panel-subtitle">选择任务查看字幕和日志</p>
</div>
<span class="badge">{{ tasks.length }}</span>
</div>
<div v-if="tasks.length === 0" class="empty-state">
暂无任务
</div>
<div v-else class="list-stack">
<button
v-for="task in tasks"
:key="task.id"
class="task-item"
:class="{ active: task.id === selectedTaskId }"
@click="emit('select', task.id)"
>
<div class="task-row">
<strong class="truncate">{{ task.fileName }}</strong>
<span>{{ Math.round(task.progress) }}%</span>
</div>
<div class="task-row subtle">
<span>{{ statusLabel[task.status] }}</span>
<span>{{ task.segments.length }} 条</span>
</div>
<div class="progress">
<div class="progress-bar" :style="{ width: `${task.progress}%` }" />
</div>
<p v-if="task.error" class="error-text">{{ task.error }}</p>
</button>
</div>
</aside>
</template>