Files
Artemis-Eapil/apps/showcase_ui/src/app/components/test-result-badge/test-result-badge.component.ts
T
chenmingxuan fac4ccb760 feat: prepare 2.2.0 with UI and execution fixes
Add dark theme, richer Markdown and readable plugin results.
Improve Android input evidence, response integrity and diagnostics.
Unify lifecycle, guidance receipts and evidence sources across clients.
Keep direct action dispatch without an added AI quota approval layer.
Align version metadata at 2.2.0 and bundle Helper 1.2.2.

Validation: 3063 backend tests before the version bump; 44 after.
Frontend: 317 tests and production build passed.
2026-10-26 00:44:13 +08:00

43 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Component, computed, input } from '@angular/core';
import { CaseTestResult } from '../../core/models/session.model';
export const TEST_RESULT_LABELS: Record<CaseTestResult['status'], string> = {
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: `<span [class]="'test-result-badge ' + status()" [class.compact]="compact()" [class.prominent]="prominent()" [title]="sourceLabel() + ':' + (result()?.reason || '执行状态与测试结论分别记录')"><span class="material-symbols-outlined" aria-hidden="true">{{icon()}}</span>{{label()}}</span>`,
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<CaseTestResult | null | undefined>();
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()]);
}