Polish QA and export workspaces
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-17 21:05:15 +02:00
parent a3df753732
commit e4b09c4e45
8 changed files with 391 additions and 68 deletions
@@ -13,27 +13,84 @@ export function QualityResultsPanel({
qualityChecksError,
onRefresh,
}: QualityResultsPanelProps): JSX.Element {
const completedChecks = qualityChecks.filter((check) => check.status === 'ok' || check.status === 'completed').length
const latestCheck = qualityChecks[0] ?? null
return (
<section data-testid="quality-results-panel">
<h2>QA/QC Results</h2>
<button type="button" onClick={onRefresh} disabled={!selectedProjectId} data-testid="refresh-quality-results">
Refresh QA/QC results
</button>
<section className="quality-results-panel" data-testid="quality-results-panel">
<div className="panel-title-row">
<div>
<h2>QA/QC Results</h2>
<p className="muted">Persisted quality checks from dataset, detection and segmentation comparisons.</p>
</div>
<span className="count-pill">{qualityChecks.length} checks</span>
</div>
<div className="quality-summary-grid">
<div>
<span>Completed</span>
<strong>{completedChecks}</strong>
</div>
<div>
<span>Latest score</span>
<strong>{latestCheck?.score ?? 'n/a'}</strong>
</div>
<div>
<span>Latest status</span>
<strong>{latestCheck?.status ?? 'waiting'}</strong>
</div>
</div>
<div className="button-row">
<button
type="button"
className="secondary-action"
onClick={onRefresh}
disabled={!selectedProjectId}
data-testid="refresh-quality-results"
>
Refresh QA/QC results
</button>
</div>
{qualityChecksError ? <p className="error">{qualityChecksError}</p> : null}
{qualityChecks.length === 0 ? <p>No persisted QA/QC results yet</p> : null}
<ul>
{qualityChecks.length === 0 ? (
<div className="empty-state">
<strong>No persisted QA/QC results yet</strong>
<p>Run dataset, detection or segmentation QA against a reference layer to populate this workspace.</p>
</div>
) : null}
<ul className="quality-check-list">
{qualityChecks.map((check) => (
<li key={check.id}>
<strong>{check.check_type}</strong>
<div>status: {check.status}</div>
<div>score: {check.score ?? 'n/a'}</div>
<div>candidate: {check.candidate_dataset_id ?? 'n/a'}</div>
<div>reference: {check.reference_dataset_id}</div>
<div>quality check: {check.id}</div>
<ul>
<li className="quality-check-card" key={check.id}>
<div className="quality-check-header">
<div>
<strong>{check.check_type}</strong>
<div className="entity-meta">
<span>candidate: {check.candidate_dataset_id ?? 'n/a'}</span>
<span>reference: {check.reference_dataset_id}</span>
</div>
</div>
<span className={check.status === 'ok' || check.status === 'completed' ? 'status-badge status-badge-ready' : 'status-badge'}>
{check.status}
</span>
</div>
<div className="quality-score-row">
<div>
<span>Score</span>
<strong>{check.score ?? 'n/a'}</strong>
</div>
<div>
<span>Metrics</span>
<strong>{check.metrics.length}</strong>
</div>
<div>
<span>Quality check</span>
<strong>{check.id}</strong>
</div>
</div>
<ul className="metric-list">
{check.metrics.map((metric) => (
<li key={metric.id}>
{metric.metric_key}: {metric.metric_value ?? 'n/a'}
<span>{metric.metric_key}</span>
<strong>{metric.metric_value ?? 'n/a'}</strong>
</li>
))}
</ul>