feat(system): ajouter filtre par statut dans la page Logs
All checks were successful
Deploy / deploy (push) Successful in 2m30s
All checks were successful
Deploy / deploy (push) Successful in 2m30s
- Filtre toolbar : Échecs / Terminés / Tous (défaut : Échecs) - Badge statut sur chaque LogItem (vert Terminé / rouge Échec) - deleteAllLogs respecte le filtre actif
This commit is contained in:
parent
8443120c2f
commit
ec4a8be934
@@ -3,6 +3,13 @@ import { ApiJobRepository } from '../../../activity/infrastructure/api/ApiJobRep
|
||||
|
||||
const jobRepository = new ApiJobRepository();
|
||||
|
||||
// Statuts disponibles par filtre
|
||||
const STATUS_MAP = {
|
||||
failed: ['failed'],
|
||||
completed: ['completed'],
|
||||
all: ['failed', 'completed'],
|
||||
};
|
||||
|
||||
export const useLogsStore = defineStore('logs', {
|
||||
state: () => ({
|
||||
logs: [],
|
||||
@@ -16,6 +23,7 @@ export const useLogsStore = defineStore('logs', {
|
||||
hasPreviousPage: false,
|
||||
sortBy: 'createdAt',
|
||||
sortOrder: 'DESC',
|
||||
statusFilter: 'failed', // 'failed' | 'completed' | 'all'
|
||||
}),
|
||||
|
||||
getters: {
|
||||
@@ -34,7 +42,7 @@ export const useLogsStore = defineStore('logs', {
|
||||
limit: this.limit,
|
||||
sortBy: this.sortBy,
|
||||
sortOrder: this.sortOrder,
|
||||
status: ['failed'],
|
||||
status: STATUS_MAP[this.statusFilter],
|
||||
type: 'scraping_job',
|
||||
});
|
||||
|
||||
@@ -65,6 +73,12 @@ export const useLogsStore = defineStore('logs', {
|
||||
await this.loadLogs(1);
|
||||
},
|
||||
|
||||
async setStatusFilter(filter) {
|
||||
this.statusFilter = filter;
|
||||
this.currentPage = 1;
|
||||
await this.loadLogs(1);
|
||||
},
|
||||
|
||||
async deleteLog(id) {
|
||||
try {
|
||||
await jobRepository.deleteJob(id);
|
||||
@@ -81,7 +95,10 @@ export const useLogsStore = defineStore('logs', {
|
||||
this.error = null;
|
||||
|
||||
try {
|
||||
await jobRepository.deleteJobs({ status: 'failed', type: 'scraping_job' });
|
||||
await jobRepository.deleteJobs({
|
||||
status: STATUS_MAP[this.statusFilter].join(','),
|
||||
type: 'scraping_job',
|
||||
});
|
||||
await this.loadLogs(1);
|
||||
} catch (error) {
|
||||
this.error = error.message;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="border-t border-gray-200 dark:border-gray-700 py-4 px-6">
|
||||
<!-- Ligne 1 : Titre manga + chapitre + date + bouton supprimer -->
|
||||
<!-- Ligne 1 : Titre manga + chapitre + badge statut + date + bouton supprimer -->
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex items-baseline gap-2 min-w-0">
|
||||
<span class="font-semibold text-gray-900 dark:text-gray-100 truncate">
|
||||
@@ -10,6 +10,15 @@
|
||||
<span class="text-sm text-gray-600 dark:text-gray-400 shrink-0">
|
||||
Chapitre {{ log.context?.chapterNumber ?? '?' }}
|
||||
</span>
|
||||
<span
|
||||
:class="[
|
||||
'px-1.5 py-0.5 text-xs font-medium shrink-0',
|
||||
log.status === 'completed'
|
||||
? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400'
|
||||
: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400'
|
||||
]">
|
||||
{{ log.status === 'completed' ? 'Terminé' : 'Échec' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 shrink-0">
|
||||
<span class="text-xs text-gray-400 dark:text-gray-500">{{ formattedDate }}</span>
|
||||
|
||||
@@ -82,6 +82,7 @@ const {
|
||||
hasPreviousPage,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
statusFilter,
|
||||
} = storeToRefs(logsStore);
|
||||
|
||||
const hasError = computed(() => !!error.value);
|
||||
@@ -100,12 +101,25 @@ function getSource(log) {
|
||||
|
||||
const isSortSelected = (by, order) => sortBy.value === by && sortOrder.value === order;
|
||||
|
||||
const STATUS_FILTERS = [
|
||||
{ key: 'failed', label: 'Échecs' },
|
||||
{ key: 'completed', label: 'Terminés' },
|
||||
{ key: 'all', label: 'Tous' },
|
||||
];
|
||||
|
||||
const toolbarConfig = computed(() => ({
|
||||
leftSection: [
|
||||
{ type: 'label', text: 'Logs', class: 'text-sm font-medium' },
|
||||
{ type: 'label', text: `(${total.value})`, class: 'text-sm text-gray-400' },
|
||||
],
|
||||
rightSection: [
|
||||
...STATUS_FILTERS.map(f => ({
|
||||
type: 'button',
|
||||
label: f.label,
|
||||
active: statusFilter.value === f.key,
|
||||
onClick: () => logsStore.setStatusFilter(f.key),
|
||||
})),
|
||||
{ type: 'divider' },
|
||||
{
|
||||
type: 'dropdown',
|
||||
icon: BarsArrowDownIcon,
|
||||
|
||||
Reference in New Issue
Block a user