feat: ajout de la gestion des jobs avec création, récupération, suppression et filtrage via l'API, incluant des entités, des composants Vue.js et des mises à jour de la documentation API

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-03-30 16:14:17 +02:00
parent 4d1d5b9f21
commit fd2d3cd640
21 changed files with 1538 additions and 184 deletions

View File

@@ -0,0 +1,102 @@
<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 === 'ERROR'
}">
<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 === 'ERROR'" 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 { defineProps, defineEmits } from 'vue';
import { TrashIcon } from '@heroicons/vue/24/outline';
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>