Improve dataset selection ergonomics
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:45:21 +02:00
parent cbdb990d51
commit b3548bfd52
8 changed files with 197 additions and 3 deletions
@@ -15,6 +15,7 @@ interface DatasetFormState {
interface DatasetPanelProps {
selectedProjectId: string | null
selectedDatasetId: string | null
areas: AreaRead[]
datasets: DatasetCreateResponse[]
datasetForm: DatasetFormState
@@ -23,6 +24,8 @@ interface DatasetPanelProps {
onUploadDataset: (event: FormEvent) => void
onLoadDatasetDetails: (projectId: string, dataset: DatasetCreateResponse) => void
onRefreshMetadata: (datasetId: string) => void
onOpenDatasetInMap: (dataset: DatasetCreateResponse) => void
onOpenDatasetExport: (dataset: DatasetCreateResponse) => void
}
function formatBytes(value: number | null | undefined): string {
@@ -52,6 +55,7 @@ function formatBounds(bounds: Record<string, number> | null | undefined): string
export function DatasetPanel({
selectedProjectId,
selectedDatasetId,
areas,
datasets,
datasetForm,
@@ -60,6 +64,8 @@ export function DatasetPanel({
onUploadDataset,
onLoadDatasetDetails,
onRefreshMetadata,
onOpenDatasetInMap,
onOpenDatasetExport,
}: DatasetPanelProps) {
const readyDatasets = datasets.filter((dataset) => dataset.status === 'ready').length
@@ -124,7 +130,7 @@ export function DatasetPanel({
{datasets.length === 0 ? <p>No datasets yet</p> : null}
<ul className="dataset-list">
{datasets.map((dataset) => (
<li className="dataset-card" key={dataset.id}>
<li className={dataset.id === selectedDatasetId ? 'dataset-card dataset-card-active' : 'dataset-card'} key={dataset.id}>
<div className="dataset-card-header">
<div>
<strong>{dataset.name}</strong>
@@ -152,6 +158,17 @@ export function DatasetPanel({
>
Select / details
</button>
<button className="secondary-action" type="button" onClick={() => onOpenDatasetInMap(dataset)}>
Open in map
</button>
<button
className="secondary-action"
type="button"
onClick={() => onOpenDatasetExport(dataset)}
disabled={!(dataset.dataset_type === 'vector' || dataset.dataset_type === 'geojson')}
>
Export / QA
</button>
<button
className="secondary-action"
type="button"
@@ -30,6 +30,11 @@ interface WorkbenchInspectorProps {
selectedSegmentationRunId: string
segmentationItems: SegmentationRead[]
datasetDetailProps: DatasetDetailPanelProps
onOpenDataWorkspace: () => void
onOpenMapWorkspace: () => void
onOpenQualityWorkspace: () => void
onOpenExportsWorkspace: () => void
onOpenAiWorkspace: () => void
}
function formatValue(value: string | number | null | undefined): string {
@@ -64,6 +69,11 @@ export function WorkbenchInspector({
selectedSegmentationRunId,
segmentationItems,
datasetDetailProps,
onOpenDataWorkspace,
onOpenMapWorkspace,
onOpenQualityWorkspace,
onOpenExportsWorkspace,
onOpenAiWorkspace,
}: WorkbenchInspectorProps): JSX.Element {
const [activeTab, setActiveTab] = useState<InspectorTab>('context')
const selectedDetectionRun = useMemo(
@@ -117,6 +127,11 @@ export function WorkbenchInspector({
<InspectorField label="Status" value={selectedProject?.status} />
<InspectorField label="AOIs" value={areas.length} />
<InspectorField label="Datasets" value={datasetsCount} />
<div className="button-row">
<button type="button" className="secondary-action" onClick={onOpenDataWorkspace}>
Open data setup
</button>
</div>
</div>
<div className="inspector-card">
<h3>Active AOI</h3>
@@ -124,6 +139,11 @@ export function WorkbenchInspector({
<InspectorField label="Area m2" value={selectedArea?.area_m2} />
<InspectorField label="CRS" value={selectedArea?.original_crs} />
<InspectorField label="Geometry" value={selectedArea?.geometry?.type} />
<div className="button-row">
<button type="button" className="secondary-action" onClick={onOpenMapWorkspace}>
Open map
</button>
</div>
</div>
<div className="inspector-card">
<h3>Map feature</h3>
@@ -138,6 +158,17 @@ export function WorkbenchInspector({
{activeTab === 'dataset' ? (
<div className="inspector-tab-panel">
<div className="inspector-action-bar">
<button type="button" className="secondary-action" onClick={onOpenDataWorkspace}>
Data catalog
</button>
<button type="button" className="secondary-action" onClick={onOpenMapWorkspace}>
Map layer
</button>
<button type="button" className="secondary-action" onClick={onOpenExportsWorkspace}>
Export
</button>
</div>
<DatasetDetailPanel {...datasetDetailProps} />
</div>
) : null}
@@ -151,6 +182,11 @@ export function WorkbenchInspector({
<InspectorField label="Score" value={latestQualityCheck?.score} />
<InspectorField label="Metrics" value={latestQualityCheck?.metrics.length} />
<InspectorField label="Reference" value={latestQualityCheck?.reference_dataset_id} />
<div className="button-row">
<button type="button" className="secondary-action" onClick={onOpenQualityWorkspace}>
Open QA/QC
</button>
</div>
</div>
<div className="inspector-card">
<h3>Latest export</h3>
@@ -159,6 +195,11 @@ export function WorkbenchInspector({
<InspectorField label="Status" value={latestPersistedExport?.status ?? latestExport?.status} />
<InspectorField label="Path" value={latestPersistedExport?.storage_path ?? latestExport?.path} />
<InspectorField label="Export count" value={exports.length} />
<div className="button-row">
<button type="button" className="secondary-action" onClick={onOpenExportsWorkspace}>
Open exports
</button>
</div>
</div>
</div>
) : null}
@@ -171,6 +212,11 @@ export function WorkbenchInspector({
<InspectorField label="Status" value={selectedDetectionRun?.status} />
<InspectorField label="Model" value={selectedDetectionRun?.model_name} />
<InspectorField label="Detections loaded" value={detectionItems.length} />
<div className="button-row">
<button type="button" className="secondary-action" onClick={onOpenAiWorkspace}>
Open AI Labs
</button>
</div>
</div>
<div className="inspector-card">
<h3>Segmentation run</h3>