import { ref, onMounted } from 'vue'; const job = ref(null); const recentJobs = ref([]); const isLoading = ref(true); const error = ref(null); // Fetch latest job status from API const fetchLatestJob = async () => { try { // In a real app, this would fetch from /api/market/ingest/latest // For now, we'll show a loading state const response = await fetch('/api/market/ingest/latest', { headers: { 'X-KArtSell-User': 'ingestion-user', 'X-KArtSell-Role': 'DataAdmin', }, }); if (response.ok) { job.value = await response.json(); } else if (response.status === 404) { // No jobs yet - that's fine job.value = null; } else { throw new Error(`API error: ${response.status}`); } } catch (err) { console.error('Failed to fetch latest job:', err); // Don't fail the page, just show no data job.value = null; } }; // Fetch recent jobs history const fetchRecentJobs = async () => { try { const response = await fetch('/api/market/ingest/history?limit=10', { headers: { 'X-KArtSell-User': 'ingestion-user', 'X-KArtSell-Role': 'DataAdmin', }, }); if (response.ok) { recentJobs.value = await response.json(); } } catch (err) { console.error('Failed to fetch recent jobs:', err); error.value = 'Failed to load job history'; } finally { isLoading.value = false; } }; onMounted(() => { fetchLatestJob(); fetchRecentJobs(); // Auto-refresh every 10 seconds if there's an active job const interval = setInterval(() => { if (job.value?.status === 'Running' || job.value?.status === 'Queued') { fetchLatestJob(); } }, 10000); return () => clearInterval(interval); }); const calculateQualityScore = (job) => { const total = job.rowsProcessed + job.rowsFailed + (job.rowsSkipped || 0); if (total === 0) return 0; return Math.round((job.rowsProcessed / total) * 100); }; const __VLS_ctx = { ...{}, ...{}, }; let __VLS_components; let __VLS_intrinsics; let __VLS_directives; /** @type {__VLS_StyleScopedClasses['header']} */ ; /** @type {__VLS_StyleScopedClasses['status-header']} */ ; /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; /** @type {__VLS_StyleScopedClasses['stat']} */ ; /** @type {__VLS_StyleScopedClasses['stat']} */ ; /** @type {__VLS_StyleScopedClasses['stat']} */ ; /** @type {__VLS_StyleScopedClasses['value']} */ ; /** @type {__VLS_StyleScopedClasses['history-table']} */ ; /** @type {__VLS_StyleScopedClasses['history-table']} */ ; /** @type {__VLS_StyleScopedClasses['history-table']} */ ; /** @type {__VLS_StyleScopedClasses['history-table']} */ ; /** @type {__VLS_StyleScopedClasses['status-completed']} */ ; /** @type {__VLS_StyleScopedClasses['history-table']} */ ; /** @type {__VLS_StyleScopedClasses['status-failed']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "ingestion-status" }, }); /** @type {__VLS_StyleScopedClasses['ingestion-status']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "header" }, }); /** @type {__VLS_StyleScopedClasses['header']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.h1, __VLS_intrinsics.h1)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.p, __VLS_intrinsics.p)({ ...{ class: "subtitle" }, }); /** @type {__VLS_StyleScopedClasses['subtitle']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "content" }, }); /** @type {__VLS_StyleScopedClasses['content']} */ ; if (__VLS_ctx.job) { __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "status-card" }, }); /** @type {__VLS_StyleScopedClasses['status-card']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "status-header" }, }); /** @type {__VLS_StyleScopedClasses['status-header']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.h2, __VLS_intrinsics.h2)({}); (__VLS_ctx.job.jobId.substring(0, 8)); __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: (['status-badge', `status-${__VLS_ctx.job.status.toLowerCase()}`]) }, }); /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; (__VLS_ctx.job.status); __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "status-grid" }, }); /** @type {__VLS_StyleScopedClasses['status-grid']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "stat" }, }); /** @type {__VLS_StyleScopedClasses['stat']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "label" }, }); /** @type {__VLS_StyleScopedClasses['label']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "value" }, }); /** @type {__VLS_StyleScopedClasses['value']} */ ; (__VLS_ctx.job.rowsProcessed.toLocaleString()); __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "stat" }, }); /** @type {__VLS_StyleScopedClasses['stat']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "label" }, }); /** @type {__VLS_StyleScopedClasses['label']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "value error" }, }); /** @type {__VLS_StyleScopedClasses['value']} */ ; /** @type {__VLS_StyleScopedClasses['error']} */ ; (__VLS_ctx.job.rowsFailed); __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "stat" }, }); /** @type {__VLS_StyleScopedClasses['stat']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "label" }, }); /** @type {__VLS_StyleScopedClasses['label']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "value" }, }); /** @type {__VLS_StyleScopedClasses['value']} */ ; (__VLS_ctx.calculateQualityScore(__VLS_ctx.job)); if (__VLS_ctx.job.durationSeconds) { __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "stat" }, }); /** @type {__VLS_StyleScopedClasses['stat']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "label" }, }); /** @type {__VLS_StyleScopedClasses['label']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: "value" }, }); /** @type {__VLS_StyleScopedClasses['value']} */ ; (__VLS_ctx.job.durationSeconds); } if (__VLS_ctx.job.errorMessage) { __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "error-section" }, }); /** @type {__VLS_StyleScopedClasses['error-section']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.strong, __VLS_intrinsics.strong)({}); (__VLS_ctx.job.errorMessage); } } else { __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "loading" }, }); /** @type {__VLS_StyleScopedClasses['loading']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.p, __VLS_intrinsics.p)({}); } __VLS_asFunctionalElement1(__VLS_intrinsics.div, __VLS_intrinsics.div)({ ...{ class: "history-section" }, }); /** @type {__VLS_StyleScopedClasses['history-section']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.h3, __VLS_intrinsics.h3)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.table, __VLS_intrinsics.table)({ ...{ class: "history-table" }, }); /** @type {__VLS_StyleScopedClasses['history-table']} */ ; __VLS_asFunctionalElement1(__VLS_intrinsics.thead, __VLS_intrinsics.thead)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.tr, __VLS_intrinsics.tr)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.th, __VLS_intrinsics.th)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.th, __VLS_intrinsics.th)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.th, __VLS_intrinsics.th)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.th, __VLS_intrinsics.th)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.th, __VLS_intrinsics.th)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.tbody, __VLS_intrinsics.tbody)({}); for (const [item, idx] of __VLS_vFor((__VLS_ctx.recentJobs))) { __VLS_asFunctionalElement1(__VLS_intrinsics.tr, __VLS_intrinsics.tr)({ key: (idx), ...{ class: (`status-${item.status.toLowerCase()}`) }, }); __VLS_asFunctionalElement1(__VLS_intrinsics.td, __VLS_intrinsics.td)({}); (item.jobId.substring(0, 8)); __VLS_asFunctionalElement1(__VLS_intrinsics.td, __VLS_intrinsics.td)({}); __VLS_asFunctionalElement1(__VLS_intrinsics.span, __VLS_intrinsics.span)({ ...{ class: (['status-badge', `status-${item.status.toLowerCase()}`]) }, }); /** @type {__VLS_StyleScopedClasses['status-badge']} */ ; (item.status); __VLS_asFunctionalElement1(__VLS_intrinsics.td, __VLS_intrinsics.td)({}); (item.rowsProcessed); __VLS_asFunctionalElement1(__VLS_intrinsics.td, __VLS_intrinsics.td)({}); (item.durationSeconds ? `${item.durationSeconds}s` : '—'); __VLS_asFunctionalElement1(__VLS_intrinsics.td, __VLS_intrinsics.td)({}); (item.completedAt ? new Date(item.completedAt).toLocaleDateString() : '—'); // @ts-ignore [job, job, job, job, job, job, job, job, job, job, job, calculateQualityScore, recentJobs,]; } // @ts-ignore []; const __VLS_export = (await import('vue')).defineComponent({}); export default {};