feat: enrich activity job display with manga/chapter context
- Add mangaTitle to ScrapingJob context at creation time - Fix job.js constructor to map failureReason, attempts, maxAttempts, context from API - JobItem: show readable type label, manga name, chapter number, source and attempts counter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
19395b4869
commit
95f224d69a
@@ -7,8 +7,12 @@ export class Job {
|
||||
payload = {},
|
||||
result = null,
|
||||
error = null,
|
||||
failureReason = null,
|
||||
createdAt = new Date().toISOString(),
|
||||
updatedAt = new Date().toISOString()
|
||||
updatedAt = new Date().toISOString(),
|
||||
attempts = 0,
|
||||
maxAttempts = 1,
|
||||
context = {}
|
||||
}) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
@@ -16,9 +20,12 @@ export class Job {
|
||||
this.progress = progress;
|
||||
this.payload = payload;
|
||||
this.result = result;
|
||||
this.error = error;
|
||||
this.error = failureReason ?? error;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
this.attempts = attempts;
|
||||
this.maxAttempts = maxAttempts;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
static create(data) {
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
<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 font-medium">
|
||||
<div>{{ jobTypeLabel }}</div>
|
||||
<div v-if="job.context?.mangaTitle" class="text-xs text-gray-500 mt-0.5">
|
||||
{{ job.context.mangaTitle }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-4">
|
||||
<span
|
||||
class="px-2 py-1 text-xs rounded-full"
|
||||
@@ -27,6 +32,18 @@
|
||||
<div v-if="job.error" class="text-sm text-red-600">
|
||||
{{ job.error }}
|
||||
</div>
|
||||
<div v-else-if="job.context?.mangaTitle || job.context?.chapterNumber !== undefined || job.context?.sourceId"
|
||||
class="text-sm text-gray-700 space-y-0.5">
|
||||
<div v-if="job.context.mangaTitle" class="font-medium">
|
||||
{{ job.context.mangaTitle }}
|
||||
</div>
|
||||
<div v-if="job.context.chapterNumber !== undefined" class="text-gray-500">
|
||||
Chapitre {{ job.context.chapterNumber }}
|
||||
</div>
|
||||
<div v-if="job.context.sourceId" class="text-xs text-gray-400">
|
||||
Source : {{ job.context.sourceId }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-sm text-gray-600">
|
||||
{{ formatDate(job.createdAt) }}
|
||||
</div>
|
||||
@@ -66,6 +83,11 @@
|
||||
En attente
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="job.maxAttempts > 1 || job.attempts > 0"
|
||||
class="text-xs text-gray-400 mt-1 text-center">
|
||||
{{ job.attempts }} / {{ job.maxAttempts }} tentative{{ job.maxAttempts > 1 ? 's' : '' }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4 px-4">
|
||||
<button
|
||||
@@ -79,24 +101,33 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { TrashIcon } from '@heroicons/vue/24/outline';
|
||||
import { defineEmits, defineProps } from 'vue';
|
||||
import { TrashIcon } from '@heroicons/vue/24/outline';
|
||||
import { computed, defineEmits, defineProps } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
const props = defineProps({
|
||||
job: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const emit = defineEmits(['delete']);
|
||||
const emit = defineEmits(['delete']);
|
||||
|
||||
function formatDate(dateString) {
|
||||
const JOB_TYPE_LABELS = {
|
||||
scraping_job: 'Scraping',
|
||||
conversion_job: 'Conversion',
|
||||
};
|
||||
|
||||
const jobTypeLabel = computed(() =>
|
||||
JOB_TYPE_LABELS[props.job.type] ?? props.job.type
|
||||
);
|
||||
|
||||
function formatDate(dateString) {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
function onDelete() {
|
||||
function onDelete() {
|
||||
emit('delete', props.job.id);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -78,6 +78,7 @@ readonly class ScrapeChapterHandler
|
||||
// Ajout de l'ID du chapitre et du slug dans le contexte du job
|
||||
$job->context['chapterId'] = $command->chapterId;
|
||||
$job->context['slug'] = $slug;
|
||||
$job->context['mangaTitle'] = $manga->getTitle();
|
||||
|
||||
$job->start();
|
||||
$this->jobRepository->save($job);
|
||||
|
||||
Reference in New Issue
Block a user