From b3d1a1a5eefe22b419d0c2578370edc0b41ae36b Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 20 Jun 2026 03:10:45 +0200 Subject: [PATCH] Polish workbench result states --- CHANGELOG.md | 8 +++ .../test_sprint81_result_state_polish.py | 47 +++++++++++++++++ docs/CODEX_EXECUTION_LOG.md | 27 ++++++++++ docs/TODO.md | 1 + frontend/README.md | 2 + .../src/components/detection/DetectionLab.tsx | 47 ++++++++++++++--- .../src/components/exports/ExportCenter.tsx | 17 ++++-- .../quality/QualityResultsPanel.tsx | 11 ++-- .../segmentation/SegmentationLab.tsx | 52 ++++++++++++++++--- frontend/src/styles/app.css | 50 +++++++++++++++++- 10 files changed, 239 insertions(+), 23 deletions(-) create mode 100644 backend/tests/test_sprint81_result_state_polish.py diff --git a/CHANGELOG.md b/CHANGELOG.md index e6e5b286..bfe21b62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ # Changelog +## Sprint 81 Result state consistency polish (2026-06-20) + +- Added shared result-state styling for compact loading, error, empty and ready states. +- Applied consistent state blocks to QA/QC results, export history and AI lab model/result panels. +- Replaced loose text/error rows in Detection and Segmentation Labs with scan-friendly state cards. +- Added static regression coverage for result-state CSS and panel usage contracts. +- No API contracts, migrations, backend behavior, provider fetching or AI model behavior changed. + ## Sprint 80 Operation form readability polish (2026-06-20) - Added structured headings, helper text, field wrappers and action rows to dense raster operation controls. diff --git a/backend/tests/test_sprint81_result_state_polish.py b/backend/tests/test_sprint81_result_state_polish.py new file mode 100644 index 00000000..743a0a31 --- /dev/null +++ b/backend/tests/test_sprint81_result_state_polish.py @@ -0,0 +1,47 @@ +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] + + +def test_result_state_css_contracts() -> None: + css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8") + + assert ".result-state" in css + assert ".result-state-error" in css + assert ".result-state-empty" in css + assert ".result-state-loading" in css + assert ".result-state-ready" in css + assert ".result-state strong" in css + assert ".result-state p" in css + assert "overflow-wrap: anywhere;" in css + + +def test_quality_and_export_panels_use_result_state_blocks() -> None: + quality_panel = (ROOT / "frontend" / "src" / "components" / "quality" / "QualityResultsPanel.tsx").read_text( + encoding="utf-8" + ) + export_center = (ROOT / "frontend" / "src" / "components" / "exports" / "ExportCenter.tsx").read_text( + encoding="utf-8" + ) + + assert 'className="result-state result-state-error"' in quality_panel + assert 'className="result-state result-state-empty"' in quality_panel + assert 'className="result-state result-state-error"' in export_center + assert 'className="result-state result-state-empty"' in export_center + assert 'className="result-state result-state-loading"' in export_center + + +def test_ai_labs_use_result_state_blocks() -> None: + detection_lab = (ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx").read_text( + encoding="utf-8" + ) + segmentation_lab = ( + ROOT / "frontend" / "src" / "components" / "segmentation" / "SegmentationLab.tsx" + ).read_text(encoding="utf-8") + + for content in (detection_lab, segmentation_lab): + assert 'className="result-state result-state-loading"' in content + assert 'className="result-state result-state-error"' in content + assert 'className="result-state result-state-empty"' in content + assert 'className="result-state result-state-ready"' in content diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index a79aec6f..7638c036 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -2956,3 +2956,30 @@ Limitations: Next recommended pass: - Continue with compact empty/error-state polish across QA, exports and AI lab result panels. + +## Sprint 81 Result state consistency polish (2026-06-20) + +Changed: +- Added shared `result-state` CSS variants for loading, error, empty and ready states. +- Applied result-state blocks to QA/QC error/empty/filter-empty states. +- Applied result-state blocks to export loading, error and empty/filter-empty states. +- Applied result-state blocks to Detection and Segmentation model loading/errors, empty registries, result counts and QA/run errors. +- Added `backend/tests/test_sprint81_result_state_polish.py`. +- Updated `frontend/README.md`, `docs/TODO.md` and `CHANGELOG.md`. + +Tested: +- Red step: `python -m pytest backend/tests/test_sprint81_result_state_polish.py -q` failed on missing result-state CSS and panel markup contracts. +- `python -m pytest backend/tests/test_sprint81_result_state_polish.py -q` (`3 passed`) +- `python -m pytest backend/tests/test_sprint81_result_state_polish.py backend/tests/test_sprint80_operation_form_readability.py backend/tests/test_sprint75_ai_labs_mobile_polish.py backend/tests/test_sprint76_export_system_mobile_polish.py backend/tests/test_sprint73_quality_result_filtering.py backend/tests/test_sprint70_quality_handoff_polish.py backend/tests/test_sprint8c_detection_visualization_qa.py backend/tests/test_sprint9_segmentation_foundation.py -q` (`34 passed`) +- `cd frontend && npm run typecheck` +- `cd frontend && npm run build` +- `bash scripts/run_readiness_check.sh` (`276 passed`; frontend typecheck/build passed; Alembic single head `202606120900`) + +Open: +- Run full readiness, redeploy Tower and verify live runtime smoke after deployment. + +Limitations: +- Frontend presentation/state polish only; no workflow behavior, API contract, persistence, migration, provider fetching or AI/model changes. + +Next recommended pass: +- Continue with visual density review for topbar/sidebar/responsive shell after another live browser pass. diff --git a/docs/TODO.md b/docs/TODO.md index 09b8c22f..14033407 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -70,6 +70,7 @@ This file now starts with the current implementation status. Older preparation/b - [x] Add export preview readability polish for large JSON/GeoJSON handoff artifacts. - [x] Add accessibility focus polish for primary workbench keyboard navigation. - [x] Add raster/vector operation form readability polish for dense tool panels. +- [x] Add compact loading/error/empty/result state polish across QA, exports and AI labs. ## Sprint 8 status diff --git a/frontend/README.md b/frontend/README.md index 1f1eced7..7c6db061 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -18,6 +18,8 @@ Primary workbench navigation, overview shortcuts, inspector tabs and dataset act Raster and vector operation panels use structured group headings, compact helper text, field grids, action rows and inline error blocks so dense GIS controls remain scannable in the inspector. +QA/QC, exports and AI lab result panels use shared loading, error, empty and ready state cards. This keeps model registry failures, empty histories and result counts visually consistent across the workbench. + ## Scope implemented - API client layer (`src/services/api`) - Project and area list/create flows diff --git a/frontend/src/components/detection/DetectionLab.tsx b/frontend/src/components/detection/DetectionLab.tsx index c4a90c53..a418831a 100644 --- a/frontend/src/components/detection/DetectionLab.tsx +++ b/frontend/src/components/detection/DetectionLab.tsx @@ -95,9 +95,24 @@ export function DetectionLab({ Refresh models - {loadingDetectionModels ?

Loading detection models...

: null} - {detectionModelError ?

{detectionModelError}

: null} - {detectionModels.length === 0 && !loadingDetectionModels ?

No detection models reported by backend

: null} + {loadingDetectionModels ? ( +
+ Loading detection models. +

Checking backend model registry availability.

+
+ ) : null} + {detectionModelError ? ( +
+ Detection model registry unavailable. +

{detectionModelError}

+
+ ) : null} + {detectionModels.length === 0 && !loadingDetectionModels ? ( +
+ No detection models reported by backend. +

Refresh models after the backend is reachable.

+
+ ) : null}