Files
KArtSell.Aegis/frontend/src/features/marketData/pages/IngestionStatus.vue.js
T
kjh2064 dfa1680a19
ci / backend (push) Failing after 0s
ci / static (push) Failing after 11s
ci / backend (pull_request) Failing after 1s
ci / static (pull_request) Failing after 12s
Build & Test with Secrets / build (pull_request) Failing after 2s
ci / publish (push) Has been cancelled
ci / frontend (push) Has been cancelled
Build & Test with Secrets / security-scan (pull_request) Has been cancelled
Build & Test with Secrets / notification (pull_request) Has been cancelled
Build & Test with Secrets / frontend (pull_request) Has been cancelled
ci / publish (pull_request) Has been cancelled
ci / frontend (pull_request) Has been cancelled
feat: align UI routes and menu with implemented screens
2026-08-06 01:39:33 +09:00

247 lines
10 KiB
JavaScript

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 {};