- Ajout migrations DB: index_job_errors, library_monitoring, full_rebuild_type - API: endpoints progression temps reel (/jobs/:id/stream), active jobs, details - API: support full_rebuild avec suppression donnees existantes - Indexer: logs detailles avec timing [SCAN][META][PARSER][BDD] - Indexer: optimisation parsing PDF (lopdf -> pdfinfo) 235x plus rapide - Indexer: corrections chemins LIBRARIES_ROOT_PATH pour dev local - Backoffice: composants JobProgress, JobsIndicator (header), JobsList - Backoffice: SSE streaming pour progression temps reel - Backoffice: boutons Index/Index Full sur page libraries - Backoffice: highlight job apres creation avec redirection - Fix: parsing volume type i32, sync meilisearch cleanup Perf: parsing PDF passe de 8.7s a 37ms Perf: indexation 45 fichiers en ~15s vs plusieurs minutes avant
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { JobProgress } from "./JobProgress";
|
|
|
|
interface JobRowProps {
|
|
job: {
|
|
id: string;
|
|
library_id: string | null;
|
|
type: string;
|
|
status: string;
|
|
created_at: string;
|
|
error_opt: string | null;
|
|
};
|
|
libraryName: string | undefined;
|
|
highlighted?: boolean;
|
|
onCancel: (id: string) => void;
|
|
}
|
|
|
|
export function JobRow({ job, libraryName, highlighted, onCancel }: JobRowProps) {
|
|
const [showProgress, setShowProgress] = useState(
|
|
highlighted || job.status === "running" || job.status === "pending"
|
|
);
|
|
|
|
const handleComplete = () => {
|
|
setShowProgress(false);
|
|
// Trigger a page refresh to update the job status
|
|
window.location.reload();
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<tr className={highlighted ? "job-highlighted" : undefined}>
|
|
<td>
|
|
<code>{job.id.slice(0, 8)}</code>
|
|
</td>
|
|
<td>{job.library_id ? libraryName || job.library_id.slice(0, 8) : "—"}</td>
|
|
<td>{job.type}</td>
|
|
<td>
|
|
<span className={`status-${job.status}`}>{job.status}</span>
|
|
{job.error_opt && <span className="error-hint" title={job.error_opt}>!</span>}
|
|
{job.status === "running" && (
|
|
<button
|
|
className="toggle-progress-btn"
|
|
onClick={() => setShowProgress(!showProgress)}
|
|
>
|
|
{showProgress ? "Hide" : "Show"} progress
|
|
</button>
|
|
)}
|
|
</td>
|
|
<td>{new Date(job.created_at).toLocaleString()}</td>
|
|
<td>
|
|
{job.status === "pending" || job.status === "running" ? (
|
|
<button
|
|
className="cancel-btn"
|
|
onClick={() => onCancel(job.id)}
|
|
>
|
|
Cancel
|
|
</button>
|
|
) : null}
|
|
</td>
|
|
</tr>
|
|
{showProgress && (job.status === "running" || job.status === "pending") && (
|
|
<tr className="progress-row">
|
|
<td colSpan={6}>
|
|
<JobProgress
|
|
jobId={job.id}
|
|
onComplete={handleComplete}
|
|
/>
|
|
</td>
|
|
</tr>
|
|
)}
|
|
</>
|
|
);
|
|
}
|