import { Component, computed, input } from '@angular/core'; import { CaseTestResult } from '../../core/models/session.model'; export const TEST_RESULT_LABELS: Record = { passed: '测试通过', failed: '测试不通过', inconclusive: '未验证', blocked: '测试阻塞' }; export function testResultSourceLabel(result: CaseTestResult | null | undefined): string { return result?.source === 'human' ? '人工确认' : result?.verification_skipped ? 'AI 判定已关闭' : 'AI确认'; } @Component({ selector: 'app-test-result-badge', standalone: true, template: `{{label()}}`, styles: [` :host{display:inline-flex;vertical-align:middle;max-width:100%} .test-result-badge{display:inline-flex;align-items:center;gap:4px;white-space:nowrap;border-radius:6px;border:1px solid var(--app-border-control, #cbd5e1);padding:3px 8px;font-size:12px;font-weight:700;line-height:1.5;background:var(--app-surface-soft, #f1f5f9);color:var(--app-text-secondary, #475569)} .material-symbols-outlined{font-size:16px;line-height:1} .passed{background:#15803d;color:#fff;border-color:#15803d} .failed{background:#b91c1c;color:#fff;border-color:#b91c1c} .inconclusive{background:var(--app-warning-soft, #fff7ed);color:var(--app-warning-text, #9a3412);border-color:var(--app-warning-border, #fdba74)} .blocked{background:var(--app-warning-soft, #fef3c7);color:var(--app-warning-text, #92400e);border-color:#fbbf24} .compact{box-sizing:border-box;height:20px;padding:0 6px;font-size:11px;line-height:14px;gap:3px;border-radius:5px} .compact .material-symbols-outlined{font-size:13px} .prominent{padding:4px 9px;font-size:14px;gap:5px} .prominent .material-symbols-outlined{font-size:18px} `] }) export class TestResultBadgeComponent { result = input(); executionStatus = input(''); compact = input(false); prominent = input(false); status = computed(() => this.result()?.status || (['completed', 'success', 'failed', 'cancelled', 'interrupted', 'skipped'].includes(this.executionStatus()) ? 'inconclusive' : 'pending')); sourceLabel = computed(() => testResultSourceLabel(this.result())); label = computed(() => this.result()?.source === 'human' ? (this.status() === 'passed' ? '人工通过' : '人工不通过') : this.status() === 'inconclusive' && this.result()?.verification_skipped ? '未做 AI 判定' : this.status() === 'pending' ? '待判定' : TEST_RESULT_LABELS[this.status() as CaseTestResult['status']]); icon = computed(() => ({passed: 'check_circle', failed: 'cancel', blocked: 'block', inconclusive: 'help', pending: 'hourglass_empty'})[this.status()]); }