Files
trueref/src/lib/components/IndexingProgress.svelte
Giancarmine Salucci 7994254e23 fix(svelte) fix svelte
2026-03-24 18:41:28 +01:00

65 lines
1.5 KiB
Svelte

<script lang="ts">
import type { IndexingJob } from '$lib/types';
let { jobId }: { jobId: string } = $props();
let job = $state<IndexingJob | null>(null);
$effect(() => {
// Reset and restart polling whenever jobId changes.
job = null;
let stopped = false;
async function poll() {
if (stopped) return;
try {
const res = await fetch(`/api/v1/jobs/${jobId}`);
if (res.ok) {
const data = await res.json();
job = data.job;
}
} catch {
// ignore transient errors
}
}
poll();
const interval = setInterval(() => {
if (job?.status === 'done' || job?.status === 'failed') {
clearInterval(interval);
return;
}
poll();
}, 2000);
return () => {
stopped = true;
clearInterval(interval);
};
});
const progress = $derived(job?.progress ?? 0);
const processedFiles = $derived(job?.processedFiles ?? 0);
const totalFiles = $derived(job?.totalFiles ?? 0);
</script>
{#if job}
<div class="mt-2">
<div class="flex justify-between text-xs text-gray-500">
<span>{processedFiles.toLocaleString()} / {totalFiles.toLocaleString()} files</span>
<span>{progress}%</span>
</div>
<div class="mt-1 h-1.5 w-full rounded-full bg-gray-200">
<div
class="h-1.5 rounded-full bg-blue-600 transition-all duration-300"
style="width: {progress}%"
></div>
</div>
{#if job.status === 'done'}
<p class="mt-1 text-xs text-green-600">Indexing complete.</p>
{:else if job.status === 'failed'}
<p class="mt-1 text-xs text-red-600">{job.error ?? 'Indexing failed.'}</p>
{/if}
</div>
{/if}