Files
ui/_docs/02_document/modules/src__features__dataset__DatasetPage.md
T
Oleksandr Bezdieniezhnykh 17d5bb45e7
ci/woodpecker/push/build-arm Pipeline was successful
[AZ-485] [AZ-486] Cycle 1 docs refresh (Step 13)
Phase B cycle 1 was a structural refactor only: F4 (barrel imports +
STC-ARCH-01) and F7 (endpoint builders + STC-ARCH-02). This commit
brings docs in line with source after the cycle, no code changes.

Module docs (12 consumers): swap every /api/<service>/... literal in
code snippets and integration tables for the matching endpoints.*
builder; note the barrel import migration in Dependencies.

New module doc: src__api__endpoints.md (public surface, F4 barrel
re-export note, STC-ARCH-02 enforcement, contract-test reference).

Architecture compliance baseline: mark F4 + F7 CLOSED with commit
hashes (23746ec, 8a461a2).

01_api-transport component description: add endpoints.ts + barrel to
Internal Interfaces, close the F7 caveat, extend Module Inventory.

ripple_log_cycle1.md: Task Step 0.5 reverse-dep analysis records the
import-graph closure (no extra docs needed beyond the direct set).

Carry-over reports landed alongside the docs:
- test_run_report_phase_b_cycle1.md (Step 11 outcome)
- implementation_report_refactor_phase_b_cycle1.md (cycle summary)

State file: trimmed to the autodev <30-line target; Steps 14 + 15
recorded as SKIPPED with rationale (no security or perf surface
changed in this cycle); pointer moved to Step 16 (Deploy).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 00:01:04 +03:00

6.8 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 endpoints.annotations.datasetBulkStatus() (= /api/annotations/dataset/bulk-status) with { annotationIds[], status: Validated }.
  • Distribution: lazy-loaded on tab switch via GET endpoints.annotations.datasetClassDistribution() (= /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 endpoints.annotations.annotationImage(id) (= /api/annotations/annotations/{id}/image).

Dependencies

  • Internal: api (barrel — api, endpoints, since AZ-485 / F4 + AZ-486 / F7), 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

Builder → Path Where Notes
endpoints.annotations.dataset(qs)/api/annotations/dataset?... fetchItems Filters: page, pageSize, fromDate, toDate, flightId, status, classNum, hasDetections, name (caller builds URLSearchParams.toString()).
endpoints.annotations.datasetItem(id)/api/annotations/dataset/{id} handleDoubleClick Loads full AnnotationListItem for the editor tab.
endpoints.annotations.datasetBulkStatus()/api/annotations/dataset/bulk-status handleValidate Body: { annotationIds, status }.
endpoints.annotations.datasetClassDistribution()/api/annotations/dataset/class-distribution loadDistribution Class histogram.
endpoints.annotations.annotationThumbnail(id)/api/annotations/annotations/{id}/thumbnail grid tile <img src=> One HTTP per visible tile.
endpoints.annotations.annotationImage(id)/api/annotations/annotations/{id}/image CanvasEditor (delegated) When the editor is open.

Path builders live in src/api/endpoints.ts (since AZ-486 / F7).

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).