80 lines
2.6 KiB
Vue
80 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import type { SubtitleTask } from '../lib/types'
|
|
|
|
defineProps<{
|
|
tasks: SubtitleTask[]
|
|
selectedTaskId: string
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
select: [taskId: string]
|
|
retry: [taskId: string]
|
|
retryTranslate: [taskId: string]
|
|
delete: [taskId: string]
|
|
}>()
|
|
</script>
|
|
|
|
<template>
|
|
<aside class="panel sidebar-panel">
|
|
<div class="panel-title">
|
|
<div>
|
|
<strong>{{ $t('taskQueue.title') }}</strong>
|
|
<p class="panel-subtitle">{{ $t('taskQueue.subtitle') }}</p>
|
|
</div>
|
|
<span class="badge">{{ tasks.length }}</span>
|
|
</div>
|
|
|
|
<div v-if="tasks.length === 0" class="empty-state">
|
|
{{ $t('taskQueue.empty') }}
|
|
</div>
|
|
|
|
<div v-else class="list-stack">
|
|
<button
|
|
v-for="task in tasks"
|
|
:key="task.id"
|
|
class="task-item"
|
|
:class="{
|
|
active: task.id === selectedTaskId,
|
|
completed: task.status === 'completed',
|
|
failed: task.status === 'failed',
|
|
}"
|
|
@click="emit('select', task.id)"
|
|
>
|
|
<div class="task-row">
|
|
<strong class="truncate">{{ task.fileName }}</strong>
|
|
<span
|
|
class="subtle"
|
|
:class="{ 'status-active': task.status !== 'completed' && task.status !== 'failed' && task.status !== 'queued' }"
|
|
>{{ $t(`taskQueue.status.${task.status}`) }}</span>
|
|
</div>
|
|
<div class="progress">
|
|
<div class="progress-bar" :style="{ width: `${task.progress}%` }" />
|
|
</div>
|
|
<div v-if="task.status === 'failed'" class="failed-footer">
|
|
<p class="error-text">{{ task.error }}</p>
|
|
<div class="retry-actions">
|
|
<button class="retry-button" type="button" @click.stop="emit('retry', task.id)">{{ $t('taskQueue.retry') }}</button>
|
|
<button
|
|
v-if="task.segments.length > 0"
|
|
class="retry-button secondary"
|
|
type="button"
|
|
@click.stop="emit('retryTranslate', task.id)"
|
|
>{{ $t('taskQueue.retryTranslate') }}</button>
|
|
</div>
|
|
</div>
|
|
<button
|
|
class="delete-button"
|
|
type="button"
|
|
:title="$t('taskQueue.delete')"
|
|
@click.stop="emit('delete', task.id)"
|
|
>
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<polyline points="3 6 5 6 21 6" />
|
|
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
|
</svg>
|
|
</button>
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
</template>
|