135 lines
3.2 KiB
Svelte
135 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import type { ScoringRunStatus } from '../api/types';
|
|
|
|
interface Props {
|
|
status: ScoringRunStatus | string;
|
|
degraded?: boolean | null;
|
|
}
|
|
|
|
let { status, degraded = false }: Props = $props();
|
|
|
|
const statusConfig: Record<string, { bg: string; text: string; border: string; label: string; pulse?: boolean }> = {
|
|
pending: {
|
|
bg: 'var(--status-warning-bg)',
|
|
text: 'var(--status-warning-text)',
|
|
border: 'var(--status-warning-border)',
|
|
label: 'ĐANG CHỜ',
|
|
pulse: true,
|
|
},
|
|
running: {
|
|
bg: 'var(--status-info-bg)',
|
|
text: 'var(--status-info)',
|
|
border: 'var(--status-info-border)',
|
|
label: 'ĐANG XỬ LÝ',
|
|
pulse: true,
|
|
},
|
|
completed: {
|
|
bg: 'var(--status-good-bg)',
|
|
text: 'var(--status-good-text)',
|
|
border: 'var(--status-good-border)',
|
|
label: 'HOÀN THÀNH',
|
|
},
|
|
review_required: {
|
|
bg: 'var(--status-warning-bg)',
|
|
text: 'var(--status-warning-text)',
|
|
border: 'var(--status-warning-border)',
|
|
label: 'CẦN KIỂM TRA',
|
|
},
|
|
failed: {
|
|
bg: 'var(--status-critical-bg)',
|
|
text: 'var(--status-critical-text)',
|
|
border: 'var(--status-critical-border)',
|
|
label: 'THẤT BẠI',
|
|
},
|
|
superseded: {
|
|
bg: 'var(--bg-surface-raised)',
|
|
text: 'var(--text-muted)',
|
|
border: 'var(--border-subtle)',
|
|
label: 'ĐÃ THAY THẾ',
|
|
},
|
|
};
|
|
|
|
let badge = $derived(
|
|
statusConfig[status] ?? {
|
|
bg: 'var(--bg-surface-raised)',
|
|
text: 'var(--text-secondary)',
|
|
border: 'var(--border-subtle)',
|
|
label: status.toUpperCase(),
|
|
}
|
|
);
|
|
</script>
|
|
|
|
<div class="status-wrapper">
|
|
<span
|
|
class="badge"
|
|
style="background: {badge.bg}; color: {badge.text}; border: 1px solid {badge.border};"
|
|
>
|
|
<span class="dot {badge.pulse ? 'pulsing' : ''}" style="background: {badge.text};"></span>
|
|
<span>{badge.label}</span>
|
|
</span>
|
|
|
|
{#if degraded}
|
|
<span class="degraded-badge" title="Chế độ dự phòng: AIHub gặp sự cố, hệ thống chuyển về tính điểm quy tắc">
|
|
DỰ PHÒNG
|
|
</span>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.status-wrapper {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 3px 9px;
|
|
border-radius: var(--radius-full);
|
|
font-size: 0.7rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.05em;
|
|
font-family: var(--font-mono);
|
|
line-height: 1;
|
|
}
|
|
|
|
.dot {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: var(--radius-full);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.dot.pulsing {
|
|
animation: pulse-glow 1.5s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes pulse-glow {
|
|
0%, 100% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
transform: scale(1.3);
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
.degraded-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 3px 8px;
|
|
border-radius: var(--radius-xs);
|
|
background: var(--status-warning-bg);
|
|
color: var(--status-warning-text);
|
|
border: 1px solid var(--status-warning-border);
|
|
font-size: 0.66rem;
|
|
font-weight: 700;
|
|
font-family: var(--font-mono);
|
|
letter-spacing: 0.04em;
|
|
}
|
|
</style>
|