import type { DatasetCreateResponse, DetectionModelCapability, DetectionQaResult, DetectionRead, DetectionRunRead, DetectionRunResponse, } from '../../types' interface DetectionLabProps { detectionModels: DetectionModelCapability[] loadingDetectionModels: boolean detectionModelError: string | null selectedDetectionDatasetId: string selectedDetectionModelId: string detectionTileManifestPath: string detectionConfidenceThreshold: number runningDetection: boolean detectionRunResult: DetectionRunResponse | null detectionRunError: string | null detectionRuns: DetectionRunRead[] selectedDetectionRunId: string detectionItems: DetectionRead[] detectionClassFilter: string detectionMinConfidenceFilter: number loadingDetectionResults: boolean detectionReferenceDatasetId: string detectionQaResult: DetectionQaResult | null detectionQaError: string | null runningDetectionQa: boolean selectedProjectId: string | null rasterDatasets: DatasetCreateResponse[] referenceDatasets: DatasetCreateResponse[] onLoadModels: () => void onSelectDataset: (datasetId: string) => void onSelectModel: (modelId: string) => void onSetConfidenceThreshold: (value: number) => void onSetTileManifestPath: (value: string) => void onRunDetection: () => void onLoadRuns: () => void onSelectRun: (runId: string) => void onSetClassFilter: (value: string) => void onSetMinConfidenceFilter: (value: number) => void onLoadResults: () => void onSelectReferenceDataset: (datasetId: string) => void onRunQa: () => void } export function DetectionLab({ detectionModels, loadingDetectionModels, detectionModelError, selectedDetectionDatasetId, selectedDetectionModelId, detectionTileManifestPath, detectionConfidenceThreshold, runningDetection, detectionRunResult, detectionRunError, detectionRuns, selectedDetectionRunId, detectionItems, detectionClassFilter, detectionMinConfidenceFilter, loadingDetectionResults, detectionReferenceDatasetId, detectionQaResult, detectionQaError, runningDetectionQa, selectedProjectId, rasterDatasets, referenceDatasets, onLoadModels, onSelectDataset, onSelectModel, onSetConfidenceThreshold, onSetTileManifestPath, onRunDetection, onLoadRuns, onSelectRun, onSetClassFilter, onSetMinConfidenceFilter, onLoadResults, onSelectReferenceDataset, onRunQa, }: DetectionLabProps): JSX.Element { return (

Object detection

Detection Lab

Model registry

Backend-reported detector states and limitations.

{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}

Run detection

{rasterDatasets.length === 0 ? (
No raster datasets available for detection.

Upload or select a raster dataset in Data before running object detection.

) : null}
{selectedDetectionModelId === 'yolo-configured' ? ( ) : null}
{detectionRunError ? (
Detection run failed.

{detectionRunError}

) : null} {detectionRunResult ? (

Status: {detectionRunResult.status}

Message: {detectionRunResult.message}

Analysis run: {detectionRunResult.analysis_run_id}

Job: {detectionRunResult.job_id}

Detections: {detectionRunResult.detection_count}

{detectionRunResult.error_code ?

Code: {detectionRunResult.error_code}

: null}
) : null}

Detection results

Load persisted detections and filter by class or confidence.

{loadingDetectionResults ? (
Loading detection results.

Retrieving persisted detections for the selected run.

) : null}
Detections loaded: {detectionItems.length}

{selectedDetectionRunId ? 'Loaded from persisted detection records.' : 'Select a detection run before loading results.'}

{detectionItems.length > 0 ? (
{detectionItems.map((detection) => ( ))}
Class Confidence Model Source tile
{detection.class_name} {detection.confidence.toFixed(2)} {detection.model_name} {detection.source_tile_path || 'n/a'}
) : null}

Detection QA

{detectionQaError ? (
Detection QA failed.

{detectionQaError}

) : null} {detectionQaResult ? (

Status: {detectionQaResult.status}

Quality check: {detectionQaResult.quality_check_id}

Precision: {detectionQaResult.precision?.toFixed(3) ?? 'n/a'}

Recall: {detectionQaResult.recall?.toFixed(3) ?? 'n/a'}

F1: {detectionQaResult.f1_score?.toFixed(3) ?? 'n/a'}

Mean IoU: {detectionQaResult.mean_iou?.toFixed(3) ?? 'n/a'}

False positives: {detectionQaResult.false_positives}

False negatives: {detectionQaResult.false_negatives}

) : null}
) }