Improve useful default workbench context
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-06-22 23:19:35 +02:00
parent 0a5f99d255
commit aaf1299a5d
8 changed files with 96 additions and 0 deletions
+4
View File
@@ -4,6 +4,8 @@ React + TypeScript + MapLibre foundation for project/area/dataset workflow.
The workbench now uses a task-based shell instead of a single long panel stack. `App.tsx` still owns shared orchestration state, but the UI is organized into Overview, Data, Map, QA/QC, AI Labs, Exports and System workspaces with a persistent top context bar and right-side dataset inspector.
When project data loads and no dataset is selected yet, the workbench auto-opens the first ready vector dataset. This gives Data, Map and Exports an immediately usable default context while preserving explicit user selection once the user picks another dataset.
Data and Map workspaces include mobile-density CSS for file inputs, dataset action buttons, map toolbar controls, range sliders and empty-map quick actions so narrow screens avoid accidental viewport overflow.
Map workspace now surfaces the selected AOI, active layer and rendered feature state before controls, then separates layer controls, provenance, the MapLibre frame and the feature inspector into focused surfaces. The underlying overlay, opacity and feature-selection behavior is unchanged.
@@ -32,6 +34,8 @@ QA/QC, exports and AI lab result panels use shared loading, error, empty and rea
Detection Lab and Segmentation Lab now share the same AI workspace hierarchy: model capabilities, run controls, persisted results and QA controls are separated into focused surfaces. Existing run, filter, result loading and QA callbacks remain unchanged, but the screens are denser and easier to scan on desktop and mobile.
AI Lab run controls explicitly explain when no raster dataset is available, instead of only showing disabled detection/segmentation run buttons.
## Scope implemented
- API client layer (`src/services/api`)
- Project and area list/create flows
@@ -143,6 +143,12 @@ export function DetectionLab({
<div className="lab-block">
<div className="ai-lab-run-surface" aria-label="Detection run controls">
<h3>Run detection</h3>
{rasterDatasets.length === 0 ? (
<div className="result-state result-state-empty">
<strong>No raster datasets available for detection.</strong>
<p>Upload or select a raster dataset in Data before running object detection.</p>
</div>
) : null}
<div className="lab-form-grid">
<label>
Raster dataset
@@ -143,6 +143,12 @@ export function SegmentationLab({
<div className="lab-block">
<div className="ai-lab-run-surface" aria-label="Segmentation run controls">
<h3>Run segmentation</h3>
{rasterDatasets.length === 0 ? (
<div className="result-state result-state-empty">
<strong>No raster datasets available for segmentation.</strong>
<p>Upload or select a raster dataset in Data before running segmentation.</p>
</div>
) : null}
<div className="lab-form-grid">
<label>
Raster dataset
+14
View File
@@ -83,6 +83,20 @@ export function useDatasetWorkflow({
}
}, [areas, selectedClipAreaId])
useEffect(() => {
if (!selectedProjectId || selectedDatasetId || datasets.length === 0) {
return
}
// Auto-open the first usable dataset so Data, Map and Exports start with real context.
const defaultDataset =
datasets.find((dataset) => isVectorDatasetType(dataset.dataset_type) && dataset.status === 'ready') ??
datasets.find((dataset) => dataset.status === 'ready') ??
datasets[0]
if (defaultDataset) {
loadDatasetDetails(selectedProjectId, defaultDataset).catch(() => null)
}
}, [datasets, isVectorDatasetType, selectedDatasetId, selectedProjectId])
const loadDatasetJobs = async (projectId: string, datasetId: string) => {
const response = await jobsApi.list(projectId, { dataset_id: datasetId, limit: 20, offset: 0 })
setJobs(response.items)