103 lines
4.1 KiB
Vue
103 lines
4.1 KiB
Vue
<template>
|
|
<tr
|
|
class="border-b border-gray-200 hover:bg-gray-50 transition duration-150 ease-in-out"
|
|
:class="{
|
|
'bg-yellow-50': job.status === 'pending',
|
|
'bg-blue-50': job.status === 'in_progress',
|
|
'bg-green-50': job.status === 'completed',
|
|
'bg-red-50': job.status === 'failed'
|
|
}">
|
|
<td class="py-4 px-4 text-center">
|
|
<input type="checkbox" class="form-checkbox h-5 w-5 text-green-600" />
|
|
</td>
|
|
<td class="py-4 px-4 font-medium">{{ job.type }}</td>
|
|
<td class="py-4 px-4">
|
|
<span
|
|
class="px-2 py-1 text-xs rounded-full"
|
|
:class="{
|
|
'bg-yellow-100 text-yellow-800': job.status === 'pending',
|
|
'bg-blue-100 text-blue-800': job.status === 'in_progress',
|
|
'bg-green-100 text-green-800': job.status === 'completed',
|
|
'bg-red-100 text-red-800': job.status === 'failed'
|
|
}">
|
|
{{ job.status }}
|
|
</span>
|
|
</td>
|
|
<td class="py-4 px-4">
|
|
<div v-if="job.error" class="text-sm text-red-600">
|
|
{{ job.error }}
|
|
</div>
|
|
<div v-else class="text-sm text-gray-600">
|
|
{{ formatDate(job.createdAt) }}
|
|
</div>
|
|
</td>
|
|
<td class="py-4 px-4">
|
|
<div v-if="job.status === 'in_progress'" class="mt-2">
|
|
<div class="relative bg-gray-200 rounded-full h-6 overflow-hidden">
|
|
<div
|
|
class="absolute top-0 left-0 h-full bg-green-400 transition-all duration-300 ease-out"
|
|
:style="{ width: `${job.progress}%` }"></div>
|
|
<div class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-white">
|
|
{{ job.progress }}%
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-else-if="job.status === 'completed'" class="relative bg-gray-200 rounded-full h-6 overflow-hidden">
|
|
<div
|
|
class="absolute top-0 left-0 h-full bg-green-400 transition-all duration-300 ease-out"
|
|
style="width: 100%"></div>
|
|
<div class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-white">
|
|
100%
|
|
</div>
|
|
</div>
|
|
<div v-else-if="job.status === 'failed'" class="relative bg-gray-200 rounded-full h-6 overflow-hidden">
|
|
<div
|
|
class="absolute top-0 left-0 h-full bg-red-400 transition-all duration-300 ease-out"
|
|
style="width: 100%"></div>
|
|
<div class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-white">
|
|
Erreur
|
|
</div>
|
|
</div>
|
|
<div v-else class="relative bg-gray-200 rounded-full h-6 overflow-hidden">
|
|
<div
|
|
class="absolute top-0 left-0 h-full bg-yellow-400 transition-all duration-300 ease-out"
|
|
style="width: 0%"></div>
|
|
<div class="absolute inset-0 flex items-center justify-center text-xs font-semibold text-gray-600">
|
|
En attente
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td class="py-4 px-4">
|
|
<button
|
|
@click="onDelete"
|
|
class="text-red-500 hover:text-red-700 transition duration-150 ease-in-out"
|
|
title="Supprimer">
|
|
<TrashIcon class="h-5 w-5" />
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { TrashIcon } from '@heroicons/vue/24/outline';
|
|
import { defineEmits, defineProps } from 'vue';
|
|
|
|
const props = defineProps({
|
|
job: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const emit = defineEmits(['delete']);
|
|
|
|
function formatDate(dateString) {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleString();
|
|
}
|
|
|
|
function onDelete() {
|
|
emit('delete', props.job.id);
|
|
}
|
|
</script>
|