Files
ui/_docs/02_document/modules/src__features__dataset__DatasetPage.md
T
Oleksandr Bezdieniezhnykh 510df68bcf [AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs
Captures the full output of autodev existing-code Phase A through
Step 4 (Code Testability Revision) for the Azaion UI workspace:

- Step 1 Document: _docs/02_document/ (FINAL_report, architecture,
  glossary, components/, modules/, diagrams/, system-flows,
  module-layout) plus _docs/00_problem/ + _docs/01_solution/ +
  _docs/legacy/ + _docs/how_to_test + README.
- Step 2 Architecture Baseline: architecture_compliance_baseline.md.
- Step 3 Test Spec: _docs/02_document/tests/ (environment,
  test-data, blackbox/performance/resilience/security/
  resource-limit tests, traceability-matrix), enum_spec_snapshot,
  expected_results/results_report.md (98 rows), plus the
  run-tests.sh + run-performance-tests.sh runners.
- Step 4 Code Testability Revision: 01-testability-refactoring/
  run dir (list-of-changes C01-C07, deferred_to_refactor,
  analysis/research_findings + refactoring_roadmap) and the 7
  child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/
  plus _dependencies_table.md.
- _docs/_autodev_state.md pins the cursor at Step 4 / refactor
  Phase 4 entry so /autodev resumes cleanly.

Epic AZ-447 (UI testability gates) tracks the 7 child tasks that
will land in subsequent commits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:38:49 +03:00

6.2 KiB
Raw Blame History

Module: src/features/dataset/DatasetPage.tsx

Compact module doc. Spec: _docs/ui_design/README.md (Dataset Explorer Layout) and parent suite ../../../../_docs/09_dataset_explorer.md (API contract). Imports CanvasEditor from ../annotations/ — see cross-feature edge in 00_discovery.md §8.

Purpose

Owns the /dataset route. Read-side surface for the Annotations table: paginated thumbnail grid, date / class / status / objects-only / name filters, inline editing through the Annotations Tab's CanvasEditor, and a class-distribution chart. Mirrors the legacy Azaion.Dataset.DatasetExplorer window (_docs/legacy/wpf-era.md §5).

Public interface

Default-exported page component, no props. Mounts under /dataset in App.tsx.

Internal logic

  • Tabs: 'annotations' (grid, default) | 'editor' (hidden until a thumbnail is double-clicked) | 'distribution' (bar chart). State held in component.
  • Filters: fromDate, toDate, statusFilter (AnnotationStatus), selectedClassNum (from DetectionClasses), objectsOnly (boolean), search (400 ms debounced via useDebounce).
  • Pagination: client page state, server pageSize fixed at 20, totalPages = ceil(totalCount / pageSize).
  • Selection: Set<annotationId>. Plain click replaces; Ctrl+click toggles. Validate button appears when set is non-empty.
  • Validate: POST /api/annotations/dataset/bulk-status with { annotationIds[], status: Validated }.
  • Distribution: lazy-loaded on tab switch via GET /api/annotations/dataset/class-distribution.
  • Editor tab mounts <CanvasEditor> with a synthesised Media stub built from editorAnnotation.mediaId (most fields blank). Used so CanvasEditor can fetch the image via /api/annotations/annotations/{id}/image.

Dependencies

  • Internal: api/client, useDebounce, useResizablePanel (left panel 250 / 200400), FlightContext, DetectionClasses, ConfirmDialog (imported but not used here — see Findings), features/annotations/CanvasEditor, types/index.
  • External: react, react-i18next.

External integrations

Endpoint Where Notes
GET /api/annotations/dataset?... fetchItems Filters: page, pageSize, fromDate, toDate, flightId, status, classNum, hasDetections, name.
GET /api/annotations/dataset/{id} handleDoubleClick Loads full AnnotationListItem for the editor tab.
POST /api/annotations/dataset/bulk-status handleValidate Body: { annotationIds, status }.
GET /api/annotations/dataset/class-distribution loadDistribution Class histogram.
GET /api/annotations/annotations/{id}/thumbnail grid tile <img src=> One HTTP per visible tile.
GET /api/annotations/annotations/{id}/image CanvasEditor (delegated) When the editor is open.

Spec contract is in parent suite _docs/09_dataset_explorer.md.

Findings carried into Step 4 / 6 / 8

  1. No keyboard shortcuts implemented: spec demands 19 (class), Enter (save), Del (delete), X (delete all), Esc (close editor), V (validate selected), Up/Down/PageUp/PageDown (navigate). Only Ctrl+click for multi-select works. The editor tab has no Save / Delete buttons either. Step 6 problem extraction.
  2. Refresh thumbnails button is missing — spec calls for a status-bar action to regenerate the thumbnail database with progress. Step 6.
  3. No virtualisation in the grid: spec says "virtualized grid" — current code renders all items returned by the page (max 20 due to pageSize). For larger pages performance would degrade. Today not a problem because pageSize=20. Step 8.
  4. Editor tab does not Save: opening an annotation in the editor lets the user edit editorDetections locally but there's no Save / Cancel control wired up. Edits are discarded when the user changes tab. Step 6.
  5. editorMedia synthetic stubmediaType: 1 is a magic number (MediaType.Image = 1); should reuse the enum import already present. Step 4.
  6. ConfirmDialog imported but never used — dead import. Step 4 cleanup.
  7. fetchItems does catch {} silently — same coderule.mdc violation as elsewhere. Step 4.
  8. Empty-state: when items.length === 0 the grid renders nothing; no "No matches" message. Step 4.
  9. thumbnail URL does not include a cache-buster; if a thumbnail is regenerated server-side, the browser will keep the stale image. Step 4 / Step 8.
  10. isSeed red-ring is correctly rendered, but isSeed is not in AnnotationStatus filters — the user can't filter to seeds-only. Step 6 if intended.
  11. Date inputs accept any <input type="date"> string; no validation that fromDate ≤ toDate. Step 4.
  12. Status filter buttons skip status None (spec lists None as one of the four buttons) — current code shows All, Created, Edited, Validated, conflating All with "include None". Step 4.
  13. selectedClassNum=0 is the "no filter" sentinel but also a real class number (class 0 exists per _docs/ui_design/README.md → military vehicle). Selecting class 0 in DetectionClasses is indistinguishable from "no filter". Step 6.
  14. Inherits one cross-cutting UI fix and one cross-repo parent-doc fix (resolved with user 2026-05-10):
    • [STEP 4 — UI FIX] AnnotationStatus values must change from UI 0/1/2 to spec 0/10/20/30/40 (src/types/index.ts:23). Every status filter button in this page (null/null/Created/Edited/Validated) currently sends a wrong integer. The "All" button is value null (no filter) — keep, but also expose a real "None" filter using the new AnnotationStatus.None=0. PRIORITY for Step 4. See annotations doc finding #27.
    • [RESOLVED 2026-05-10] DatasetItem.isSplit is correct on UI; parent ../../../../_docs/09_dataset_explorer.md §1 response schema now includes it. See annotations doc finding #33.

Tests

None.

Cross-doc references

  • Parent suite Dataset Explorer API: ../../../../_docs/09_dataset_explorer.md
  • UI spec: ../../ui_design/README.md (Dataset Explorer Layout, Keyboard Shortcuts).
  • Imports CanvasEditor from features/annotations/ — see 00_discovery.md §8 cross-feature edge.
  • Legacy WPF reference: ../../legacy/wpf-era.md §5 (Dataset Explorer window).