Refactor workbench into task-based UI shell
This commit is contained in:
+362
-248
@@ -1,4 +1,4 @@
|
||||
import { useMemo } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import './styles/app.css'
|
||||
import { ChangeDetectionPanel } from './components/analysis/ChangeDetectionPanel'
|
||||
import { DatasetDetailPanel } from './components/datasets/DatasetDetailPanel'
|
||||
@@ -30,7 +30,20 @@ function isVectorDatasetType(datasetType: string): boolean {
|
||||
return datasetType === 'vector' || datasetType === 'geojson'
|
||||
}
|
||||
|
||||
type WorkspaceKey = 'overview' | 'data' | 'map' | 'analysis' | 'ai' | 'exports' | 'system'
|
||||
|
||||
const workspaceNavItems: Array<{ key: WorkspaceKey; label: string; description: string }> = [
|
||||
{ key: 'overview', label: 'Overview', description: 'V1 readiness and next action' },
|
||||
{ key: 'data', label: 'Data', description: 'Projects, AOI and datasets' },
|
||||
{ key: 'map', label: 'Map', description: 'Layer review and inspection' },
|
||||
{ key: 'analysis', label: 'QA/QC', description: 'Quality checks and change detection' },
|
||||
{ key: 'ai', label: 'AI Labs', description: 'Detection and segmentation' },
|
||||
{ key: 'exports', label: 'Exports', description: 'Artifacts and downloads' },
|
||||
{ key: 'system', label: 'System', description: 'Provider capabilities' },
|
||||
]
|
||||
|
||||
function App(): JSX.Element {
|
||||
const [activeWorkspace, setActiveWorkspace] = useState<WorkspaceKey>('overview')
|
||||
const {
|
||||
projects,
|
||||
selectedProject,
|
||||
@@ -370,269 +383,370 @@ function App(): JSX.Element {
|
||||
resetExportsForProject,
|
||||
})
|
||||
|
||||
const selectedArea = areas.find((area) => area.id === selectedMapAreaId) ?? null
|
||||
const activeWorkspaceItem = workspaceNavItems.find((item) => item.key === activeWorkspace) ?? workspaceNavItems[0]
|
||||
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<header>
|
||||
<h1>GeoIntel Kempen V1 Workbench</h1>
|
||||
<p>Raster/vector workbench with QA/QC, exports, change detection and AI foundation layers.</p>
|
||||
<div className="app-shell workbench-shell">
|
||||
<header className="workbench-topbar">
|
||||
<div className="brand-block">
|
||||
<p className="eyebrow">GeoAI Workbench</p>
|
||||
<h1>GeoIntel Kempen</h1>
|
||||
</div>
|
||||
<div className="context-bar" aria-label="Active workbench context">
|
||||
<div>
|
||||
<span>Project</span>
|
||||
<strong>{selectedProject?.name ?? 'No project'}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>AOI</span>
|
||||
<strong>{selectedArea?.name ?? (areas.length > 0 ? 'Select area' : 'No AOI')}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Dataset</span>
|
||||
<strong>{selectedDataset?.name ?? (datasets.length > 0 ? 'Select dataset' : 'No dataset')}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Layer</span>
|
||||
<strong>{mapFeatureCollection ? `${mapFeatureCount} features` : 'No active layer'}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{errorMessage ? <p className="error">{errorMessage}</p> : null}
|
||||
|
||||
<WorkbenchStatusStrip
|
||||
selectedProject={selectedProject}
|
||||
areas={areas}
|
||||
datasets={datasets}
|
||||
qualityChecks={qualityChecks}
|
||||
exports={exports}
|
||||
activeLayerFeatureCount={mapFeatureCount}
|
||||
selectedAreaHasGeometry={Boolean(areaFeatureCollection)}
|
||||
/>
|
||||
<div className="workbench-layout">
|
||||
<aside className="workbench-sidebar" aria-label="Workbench navigation">
|
||||
<nav>
|
||||
{workspaceNavItems.map((item) => (
|
||||
<button
|
||||
key={item.key}
|
||||
type="button"
|
||||
className={item.key === activeWorkspace ? 'nav-item nav-item-active' : 'nav-item'}
|
||||
onClick={() => setActiveWorkspace(item.key)}
|
||||
aria-current={item.key === activeWorkspace ? 'page' : undefined}
|
||||
data-testid={`workspace-nav-${item.key}`}
|
||||
>
|
||||
<span>{item.label}</span>
|
||||
<small>{item.description}</small>
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<MapWorkspace
|
||||
areas={areas}
|
||||
selectedMapAreaId={selectedMapAreaId}
|
||||
areaFeatureCollection={areaFeatureCollection}
|
||||
mapFeatureCollection={mapFeatureCollection}
|
||||
mapLayerLabel={mapLayerLabel}
|
||||
mapLayerVisible={mapLayerVisible}
|
||||
mapLayerOpacity={mapLayerOpacity}
|
||||
areaLayerVisible={areaLayerVisible}
|
||||
areaLayerOpacity={areaLayerOpacity}
|
||||
mapFeatureCount={mapFeatureCount}
|
||||
areaFeatureCount={areaFeatureCount}
|
||||
selectedMapFeature={selectedMapFeature}
|
||||
onSelectMapArea={setSelectedMapAreaId}
|
||||
onSetAreaLayerVisible={setAreaLayerVisible}
|
||||
onSetAreaLayerOpacity={setAreaLayerOpacity}
|
||||
onSetMapLayerVisible={setMapLayerVisible}
|
||||
onSetMapLayerOpacity={setMapLayerOpacity}
|
||||
onSelectMapFeature={setSelectedMapFeature}
|
||||
/>
|
||||
<main className="workbench-main">
|
||||
<div className="workspace-heading">
|
||||
<div>
|
||||
<p className="eyebrow">Workspace</p>
|
||||
<h2>{activeWorkspaceItem.label}</h2>
|
||||
</div>
|
||||
<p>{activeWorkspaceItem.description}</p>
|
||||
</div>
|
||||
|
||||
<main className="workspace-grid">
|
||||
<ProjectPanel
|
||||
projects={projects}
|
||||
selectedProjectId={selectedProjectId}
|
||||
loadingProjects={loadingProjects}
|
||||
projectForm={projectForm}
|
||||
loadingDemoWorkflow={loadingDemoWorkflow}
|
||||
demoWorkflowMessage={demoWorkflowMessage}
|
||||
onCreateProject={createProject}
|
||||
onUpdateProjectForm={setProjectForm}
|
||||
onSelectProject={setSelectedProjectId}
|
||||
onLoadDemoWorkflow={loadDemoWorkflow}
|
||||
/>
|
||||
{activeWorkspace === 'overview' ? (
|
||||
<div className="workspace-stack">
|
||||
<WorkbenchStatusStrip
|
||||
selectedProject={selectedProject}
|
||||
areas={areas}
|
||||
datasets={datasets}
|
||||
qualityChecks={qualityChecks}
|
||||
exports={exports}
|
||||
activeLayerFeatureCount={mapFeatureCount}
|
||||
selectedAreaHasGeometry={Boolean(areaFeatureCollection)}
|
||||
/>
|
||||
<section className="overview-actions">
|
||||
<div>
|
||||
<p className="eyebrow">Recommended flow</p>
|
||||
<h2>Build the project, load data, review on map, validate, export.</h2>
|
||||
<p className="muted">
|
||||
Keep the daily workflow focused: prepare data first, inspect it spatially, then run QA/QC or AI lab tasks only when the
|
||||
required datasets are present.
|
||||
</p>
|
||||
</div>
|
||||
<div className="quick-action-grid">
|
||||
<button type="button" onClick={() => setActiveWorkspace('data')}>
|
||||
Open data setup
|
||||
</button>
|
||||
<button type="button" onClick={() => setActiveWorkspace('map')}>
|
||||
Inspect map
|
||||
</button>
|
||||
<button type="button" onClick={() => setActiveWorkspace('analysis')}>
|
||||
Review QA/QC
|
||||
</button>
|
||||
<button type="button" onClick={() => setActiveWorkspace('exports')}>
|
||||
Manage exports
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<AreaPanel
|
||||
areas={areas}
|
||||
selectedProject={selectedProject}
|
||||
selectedProjectId={selectedProjectId}
|
||||
loadingAreas={loadingAreas}
|
||||
areaForm={areaForm}
|
||||
selectedMapAreaId={selectedMapAreaId}
|
||||
onCreateArea={createArea}
|
||||
onUpdateAreaForm={setAreaForm}
|
||||
onSelectMapArea={setSelectedMapAreaId}
|
||||
/>
|
||||
{activeWorkspace === 'data' ? (
|
||||
<div className="workspace-grid workspace-grid-data">
|
||||
<ProjectPanel
|
||||
projects={projects}
|
||||
selectedProjectId={selectedProjectId}
|
||||
loadingProjects={loadingProjects}
|
||||
projectForm={projectForm}
|
||||
loadingDemoWorkflow={loadingDemoWorkflow}
|
||||
demoWorkflowMessage={demoWorkflowMessage}
|
||||
onCreateProject={createProject}
|
||||
onUpdateProjectForm={setProjectForm}
|
||||
onSelectProject={setSelectedProjectId}
|
||||
onLoadDemoWorkflow={loadDemoWorkflow}
|
||||
/>
|
||||
|
||||
<DatasetPanel
|
||||
selectedProjectId={selectedProjectId}
|
||||
areas={areas}
|
||||
datasets={datasets}
|
||||
datasetForm={datasetForm}
|
||||
loadingDatasets={loadingDatasets}
|
||||
onDatasetFormChange={setDatasetForm}
|
||||
onUploadDataset={uploadDataset}
|
||||
onLoadDatasetDetails={loadDatasetDetails}
|
||||
onRefreshMetadata={refreshMetadata}
|
||||
/>
|
||||
<AreaPanel
|
||||
areas={areas}
|
||||
selectedProject={selectedProject}
|
||||
selectedProjectId={selectedProjectId}
|
||||
loadingAreas={loadingAreas}
|
||||
areaForm={areaForm}
|
||||
selectedMapAreaId={selectedMapAreaId}
|
||||
onCreateArea={createArea}
|
||||
onUpdateAreaForm={setAreaForm}
|
||||
onSelectMapArea={setSelectedMapAreaId}
|
||||
/>
|
||||
|
||||
<ProviderPanel
|
||||
providers={providers}
|
||||
loadingCapabilities={loadingCapabilities}
|
||||
capabilitiesError={capabilitiesError}
|
||||
onRefresh={loadCapabilities}
|
||||
/>
|
||||
<DatasetPanel
|
||||
selectedProjectId={selectedProjectId}
|
||||
areas={areas}
|
||||
datasets={datasets}
|
||||
datasetForm={datasetForm}
|
||||
loadingDatasets={loadingDatasets}
|
||||
onDatasetFormChange={setDatasetForm}
|
||||
onUploadDataset={uploadDataset}
|
||||
onLoadDatasetDetails={loadDatasetDetails}
|
||||
onRefreshMetadata={refreshMetadata}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<ChangeDetectionPanel
|
||||
vectorDatasets={availableVectorDatasets}
|
||||
sourceDatasetId={changeSourceDatasetId}
|
||||
targetDatasetId={changeTargetDatasetId}
|
||||
iouThreshold={changeIouThreshold}
|
||||
includeUnchanged={changeIncludeUnchanged}
|
||||
running={runningChangeDetection}
|
||||
result={changeDetectionResult}
|
||||
error={changeDetectionError}
|
||||
onSourceDatasetChange={setChangeSourceDatasetId}
|
||||
onTargetDatasetChange={setChangeTargetDatasetId}
|
||||
onIouThresholdChange={setChangeIouThreshold}
|
||||
onIncludeUnchangedChange={setChangeIncludeUnchanged}
|
||||
onRun={runChangeDetection}
|
||||
/>
|
||||
{activeWorkspace === 'map' ? (
|
||||
<MapWorkspace
|
||||
areas={areas}
|
||||
selectedMapAreaId={selectedMapAreaId}
|
||||
areaFeatureCollection={areaFeatureCollection}
|
||||
mapFeatureCollection={mapFeatureCollection}
|
||||
mapLayerLabel={mapLayerLabel}
|
||||
mapLayerVisible={mapLayerVisible}
|
||||
mapLayerOpacity={mapLayerOpacity}
|
||||
areaLayerVisible={areaLayerVisible}
|
||||
areaLayerOpacity={areaLayerOpacity}
|
||||
mapFeatureCount={mapFeatureCount}
|
||||
areaFeatureCount={areaFeatureCount}
|
||||
selectedMapFeature={selectedMapFeature}
|
||||
onSelectMapArea={setSelectedMapAreaId}
|
||||
onSetAreaLayerVisible={setAreaLayerVisible}
|
||||
onSetAreaLayerOpacity={setAreaLayerOpacity}
|
||||
onSetMapLayerVisible={setMapLayerVisible}
|
||||
onSetMapLayerOpacity={setMapLayerOpacity}
|
||||
onSelectMapFeature={setSelectedMapFeature}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<DetectionLab
|
||||
detectionModels={detectionModels}
|
||||
loadingDetectionModels={loadingDetectionModels}
|
||||
detectionModelError={detectionModelError}
|
||||
selectedDetectionDatasetId={selectedDetectionDatasetId}
|
||||
selectedDetectionModelId={selectedDetectionModelId}
|
||||
detectionTileManifestPath={detectionTileManifestPath}
|
||||
detectionConfidenceThreshold={detectionConfidenceThreshold}
|
||||
runningDetection={runningDetection}
|
||||
detectionRunResult={detectionRunResult}
|
||||
detectionRunError={detectionRunError}
|
||||
detectionRuns={detectionRuns}
|
||||
selectedDetectionRunId={selectedDetectionRunId}
|
||||
detectionItems={detectionItems}
|
||||
detectionClassFilter={detectionClassFilter}
|
||||
detectionMinConfidenceFilter={detectionMinConfidenceFilter}
|
||||
loadingDetectionResults={loadingDetectionResults}
|
||||
detectionReferenceDatasetId={detectionReferenceDatasetId}
|
||||
detectionQaResult={detectionQaResult}
|
||||
detectionQaError={detectionQaError}
|
||||
runningDetectionQa={runningDetectionQa}
|
||||
selectedProjectId={selectedProjectId}
|
||||
rasterDatasets={rasterDatasets}
|
||||
referenceDatasets={referenceDatasets}
|
||||
onLoadModels={loadDetectionModels}
|
||||
onSelectDataset={setSelectedDetectionDatasetId}
|
||||
onSelectModel={setSelectedDetectionModelId}
|
||||
onSetConfidenceThreshold={setDetectionConfidenceThreshold}
|
||||
onSetTileManifestPath={setDetectionTileManifestPath}
|
||||
onRunDetection={runDetection}
|
||||
onLoadRuns={() => loadDetectionRuns()}
|
||||
onSelectRun={setSelectedDetectionRunId}
|
||||
onSetClassFilter={setDetectionClassFilter}
|
||||
onSetMinConfidenceFilter={setDetectionMinConfidenceFilter}
|
||||
onLoadResults={() => loadDetectionResults()}
|
||||
onSelectReferenceDataset={setDetectionReferenceDatasetId}
|
||||
onRunQa={runDetectionQa}
|
||||
/>
|
||||
{activeWorkspace === 'analysis' ? (
|
||||
<div className="workspace-grid workspace-grid-analysis">
|
||||
<ChangeDetectionPanel
|
||||
vectorDatasets={availableVectorDatasets}
|
||||
sourceDatasetId={changeSourceDatasetId}
|
||||
targetDatasetId={changeTargetDatasetId}
|
||||
iouThreshold={changeIouThreshold}
|
||||
includeUnchanged={changeIncludeUnchanged}
|
||||
running={runningChangeDetection}
|
||||
result={changeDetectionResult}
|
||||
error={changeDetectionError}
|
||||
onSourceDatasetChange={setChangeSourceDatasetId}
|
||||
onTargetDatasetChange={setChangeTargetDatasetId}
|
||||
onIouThresholdChange={setChangeIouThreshold}
|
||||
onIncludeUnchangedChange={setChangeIncludeUnchanged}
|
||||
onRun={runChangeDetection}
|
||||
/>
|
||||
|
||||
<SegmentationLab
|
||||
segmentationModels={segmentationModels}
|
||||
loadingSegmentationModels={loadingSegmentationModels}
|
||||
segmentationModelError={segmentationModelError}
|
||||
selectedSegmentationDatasetId={selectedSegmentationDatasetId}
|
||||
selectedSegmentationModelId={selectedSegmentationModelId}
|
||||
segmentationConfidenceThreshold={segmentationConfidenceThreshold}
|
||||
runningSegmentation={runningSegmentation}
|
||||
segmentationRunResult={segmentationRunResult}
|
||||
segmentationRunError={segmentationRunError}
|
||||
segmentationRuns={segmentationRuns}
|
||||
selectedSegmentationRunId={selectedSegmentationRunId}
|
||||
segmentationItems={segmentationItems}
|
||||
segmentationClassFilter={segmentationClassFilter}
|
||||
segmentationMinConfidenceFilter={segmentationMinConfidenceFilter}
|
||||
loadingSegmentationResults={loadingSegmentationResults}
|
||||
segmentationReferenceDatasetId={segmentationReferenceDatasetId}
|
||||
segmentationQaResult={segmentationQaResult}
|
||||
segmentationQaError={segmentationQaError}
|
||||
runningSegmentationQa={runningSegmentationQa}
|
||||
selectedProjectId={selectedProjectId}
|
||||
rasterDatasets={rasterDatasets}
|
||||
referenceDatasets={referenceDatasets}
|
||||
selectedSegmentationModelConfigured={Boolean(selectedSegmentationModel?.configured)}
|
||||
selectedSegmentationModelLimitation={selectedSegmentationModel?.limitation_message ?? null}
|
||||
onLoadModels={loadSegmentationModels}
|
||||
onSelectDataset={setSelectedSegmentationDatasetId}
|
||||
onSelectModel={setSelectedSegmentationModelId}
|
||||
onSetConfidenceThreshold={setSegmentationConfidenceThreshold}
|
||||
onRunSegmentation={runSegmentation}
|
||||
onLoadRuns={() => loadSegmentationRuns()}
|
||||
onSelectRun={setSelectedSegmentationRunId}
|
||||
onSetClassFilter={setSegmentationClassFilter}
|
||||
onSetMinConfidenceFilter={setSegmentationMinConfidenceFilter}
|
||||
onLoadResults={() => loadSegmentationResults()}
|
||||
onSelectReferenceDataset={setSegmentationReferenceDatasetId}
|
||||
onRunQa={runSegmentationQa}
|
||||
/>
|
||||
<QualityResultsPanel
|
||||
selectedProjectId={selectedProjectId}
|
||||
qualityChecks={qualityChecks}
|
||||
qualityChecksError={qualityChecksError}
|
||||
onRefresh={() => loadQualityChecks()}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<QualityResultsPanel
|
||||
selectedProjectId={selectedProjectId}
|
||||
qualityChecks={qualityChecks}
|
||||
qualityChecksError={qualityChecksError}
|
||||
onRefresh={() => loadQualityChecks()}
|
||||
/>
|
||||
{activeWorkspace === 'ai' ? (
|
||||
<div className="workspace-grid workspace-grid-ai">
|
||||
<DetectionLab
|
||||
detectionModels={detectionModels}
|
||||
loadingDetectionModels={loadingDetectionModels}
|
||||
detectionModelError={detectionModelError}
|
||||
selectedDetectionDatasetId={selectedDetectionDatasetId}
|
||||
selectedDetectionModelId={selectedDetectionModelId}
|
||||
detectionTileManifestPath={detectionTileManifestPath}
|
||||
detectionConfidenceThreshold={detectionConfidenceThreshold}
|
||||
runningDetection={runningDetection}
|
||||
detectionRunResult={detectionRunResult}
|
||||
detectionRunError={detectionRunError}
|
||||
detectionRuns={detectionRuns}
|
||||
selectedDetectionRunId={selectedDetectionRunId}
|
||||
detectionItems={detectionItems}
|
||||
detectionClassFilter={detectionClassFilter}
|
||||
detectionMinConfidenceFilter={detectionMinConfidenceFilter}
|
||||
loadingDetectionResults={loadingDetectionResults}
|
||||
detectionReferenceDatasetId={detectionReferenceDatasetId}
|
||||
detectionQaResult={detectionQaResult}
|
||||
detectionQaError={detectionQaError}
|
||||
runningDetectionQa={runningDetectionQa}
|
||||
selectedProjectId={selectedProjectId}
|
||||
rasterDatasets={rasterDatasets}
|
||||
referenceDatasets={referenceDatasets}
|
||||
onLoadModels={loadDetectionModels}
|
||||
onSelectDataset={setSelectedDetectionDatasetId}
|
||||
onSelectModel={setSelectedDetectionModelId}
|
||||
onSetConfidenceThreshold={setDetectionConfidenceThreshold}
|
||||
onSetTileManifestPath={setDetectionTileManifestPath}
|
||||
onRunDetection={runDetection}
|
||||
onLoadRuns={() => loadDetectionRuns()}
|
||||
onSelectRun={setSelectedDetectionRunId}
|
||||
onSetClassFilter={setDetectionClassFilter}
|
||||
onSetMinConfidenceFilter={setDetectionMinConfidenceFilter}
|
||||
onLoadResults={() => loadDetectionResults()}
|
||||
onSelectReferenceDataset={setDetectionReferenceDatasetId}
|
||||
onRunQa={runDetectionQa}
|
||||
/>
|
||||
|
||||
<ExportCenter
|
||||
selectedProjectId={selectedProjectId}
|
||||
selectedDataset={selectedDataset}
|
||||
selectedDetectionRunId={selectedDetectionRunId}
|
||||
selectedSegmentationRunId={selectedSegmentationRunId}
|
||||
exports={exports}
|
||||
latestExport={latestExport}
|
||||
exportError={exportError}
|
||||
loadingExports={loadingExports}
|
||||
exporting={exporting}
|
||||
onRefresh={() => loadExports()}
|
||||
onExportDataset={exportSelectedDatasetGeoJson}
|
||||
onExportDetectionRun={exportSelectedDetectionRunGeoJson}
|
||||
onExportSegmentationRun={exportSelectedSegmentationRunGeoJson}
|
||||
onExportProjectMetadata={exportProjectMetadata}
|
||||
onExportProjectReport={exportProjectReport}
|
||||
onPreviewContent={previewExportContent}
|
||||
onDownload={downloadExportArtifact}
|
||||
/>
|
||||
<ExportPreview content={exportPreview} />
|
||||
</main>
|
||||
<SegmentationLab
|
||||
segmentationModels={segmentationModels}
|
||||
loadingSegmentationModels={loadingSegmentationModels}
|
||||
segmentationModelError={segmentationModelError}
|
||||
selectedSegmentationDatasetId={selectedSegmentationDatasetId}
|
||||
selectedSegmentationModelId={selectedSegmentationModelId}
|
||||
segmentationConfidenceThreshold={segmentationConfidenceThreshold}
|
||||
runningSegmentation={runningSegmentation}
|
||||
segmentationRunResult={segmentationRunResult}
|
||||
segmentationRunError={segmentationRunError}
|
||||
segmentationRuns={segmentationRuns}
|
||||
selectedSegmentationRunId={selectedSegmentationRunId}
|
||||
segmentationItems={segmentationItems}
|
||||
segmentationClassFilter={segmentationClassFilter}
|
||||
segmentationMinConfidenceFilter={segmentationMinConfidenceFilter}
|
||||
loadingSegmentationResults={loadingSegmentationResults}
|
||||
segmentationReferenceDatasetId={segmentationReferenceDatasetId}
|
||||
segmentationQaResult={segmentationQaResult}
|
||||
segmentationQaError={segmentationQaError}
|
||||
runningSegmentationQa={runningSegmentationQa}
|
||||
selectedProjectId={selectedProjectId}
|
||||
rasterDatasets={rasterDatasets}
|
||||
referenceDatasets={referenceDatasets}
|
||||
selectedSegmentationModelConfigured={Boolean(selectedSegmentationModel?.configured)}
|
||||
selectedSegmentationModelLimitation={selectedSegmentationModel?.limitation_message ?? null}
|
||||
onLoadModels={loadSegmentationModels}
|
||||
onSelectDataset={setSelectedSegmentationDatasetId}
|
||||
onSelectModel={setSelectedSegmentationModelId}
|
||||
onSetConfidenceThreshold={setSegmentationConfidenceThreshold}
|
||||
onRunSegmentation={runSegmentation}
|
||||
onLoadRuns={() => loadSegmentationRuns()}
|
||||
onSelectRun={setSelectedSegmentationRunId}
|
||||
onSetClassFilter={setSegmentationClassFilter}
|
||||
onSetMinConfidenceFilter={setSegmentationMinConfidenceFilter}
|
||||
onLoadResults={() => loadSegmentationResults()}
|
||||
onSelectReferenceDataset={setSegmentationReferenceDatasetId}
|
||||
onRunQa={runSegmentationQa}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<DatasetDetailPanel
|
||||
areas={areas}
|
||||
availableVectorTargets={availableVectorTargets}
|
||||
selectedDatasetId={selectedDatasetId}
|
||||
selectedDataset={selectedDataset}
|
||||
selectedDatasetSummary={selectedDatasetSummary}
|
||||
selectedRasterMetadata={selectedRasterMetadata}
|
||||
selectedRasterStats={selectedRasterStats}
|
||||
rasterPreview={rasterPreview}
|
||||
rasterUnavailableMessage={rasterUnavailableMessage}
|
||||
selectedClipAreaId={selectedClipAreaId}
|
||||
selectedIntersectTargetId={selectedIntersectTargetId}
|
||||
rasterTileSize={rasterTileSize}
|
||||
rasterTileOverlap={rasterTileOverlap}
|
||||
rasterTileOutputName={rasterTileOutputName}
|
||||
rasterReprojectCrs={rasterReprojectCrs}
|
||||
rasterReprojectResampling={rasterReprojectResampling}
|
||||
ndviNirBand={ndviNirBand}
|
||||
ndviRedBand={ndviRedBand}
|
||||
ndwiGreenBand={ndwiGreenBand}
|
||||
ndwiNirBand={ndwiNirBand}
|
||||
ndbiSwirBand={ndbiSwirBand}
|
||||
ndbiNirBand={ndbiNirBand}
|
||||
isRasterTileInputValid={isRasterTileInputValid}
|
||||
jobs={jobs}
|
||||
loadingDatasetDetails={loadingDatasetDetails}
|
||||
datasetDetailError={datasetDetailError}
|
||||
isVectorDatasetType={isVectorDatasetType}
|
||||
onSetSelectedClipAreaId={setSelectedClipAreaId}
|
||||
onSetSelectedIntersectTargetId={setSelectedIntersectTargetId}
|
||||
onSetRasterTileSize={setRasterTileSize}
|
||||
onSetRasterTileOverlap={setRasterTileOverlap}
|
||||
onSetRasterTileOutputName={setRasterTileOutputName}
|
||||
onSetRasterReprojectCrs={setRasterReprojectCrs}
|
||||
onSetRasterReprojectResampling={setRasterReprojectResampling}
|
||||
onSetNdviNirBand={setNdviNirBand}
|
||||
onSetNdviRedBand={setNdviRedBand}
|
||||
onSetNdwiGreenBand={setNdwiGreenBand}
|
||||
onSetNdwiNirBand={setNdwiNirBand}
|
||||
onSetNdbiSwirBand={setNdbiSwirBand}
|
||||
onSetNdbiNirBand={setNdbiNirBand}
|
||||
onRunRasterInspect={runRasterInspect}
|
||||
onRunRasterPreview={runRasterPreview}
|
||||
onRunRasterStats={runRasterStats}
|
||||
onRunRasterReproject={runRasterReproject}
|
||||
onRunRasterClip={runRasterClip}
|
||||
onRunRasterTile={runRasterTile}
|
||||
onRunRasterNdvi={runRasterNdvi}
|
||||
onRunRasterNdwi={runRasterNdwi}
|
||||
onRunRasterNdbi={runRasterNdbi}
|
||||
onRunVectorClip={runVectorClip}
|
||||
onRunVectorBuffer={runVectorBuffer}
|
||||
onRunVectorIntersect={() => runVectorIntersect(availableVectorTargets)}
|
||||
onPickDerivedDataset={pickDerivedDataset}
|
||||
/>
|
||||
{activeWorkspace === 'exports' ? (
|
||||
<div className="workspace-grid workspace-grid-exports">
|
||||
<ExportCenter
|
||||
selectedProjectId={selectedProjectId}
|
||||
selectedDataset={selectedDataset}
|
||||
selectedDetectionRunId={selectedDetectionRunId}
|
||||
selectedSegmentationRunId={selectedSegmentationRunId}
|
||||
exports={exports}
|
||||
latestExport={latestExport}
|
||||
exportError={exportError}
|
||||
loadingExports={loadingExports}
|
||||
exporting={exporting}
|
||||
onRefresh={() => loadExports()}
|
||||
onExportDataset={exportSelectedDatasetGeoJson}
|
||||
onExportDetectionRun={exportSelectedDetectionRunGeoJson}
|
||||
onExportSegmentationRun={exportSelectedSegmentationRunGeoJson}
|
||||
onExportProjectMetadata={exportProjectMetadata}
|
||||
onExportProjectReport={exportProjectReport}
|
||||
onPreviewContent={previewExportContent}
|
||||
onDownload={downloadExportArtifact}
|
||||
/>
|
||||
<ExportPreview content={exportPreview} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{activeWorkspace === 'system' ? (
|
||||
<ProviderPanel
|
||||
providers={providers}
|
||||
loadingCapabilities={loadingCapabilities}
|
||||
capabilitiesError={capabilitiesError}
|
||||
onRefresh={loadCapabilities}
|
||||
/>
|
||||
) : null}
|
||||
</main>
|
||||
|
||||
<aside className="workbench-inspector" aria-label="Current selection inspector">
|
||||
<DatasetDetailPanel
|
||||
areas={areas}
|
||||
availableVectorTargets={availableVectorTargets}
|
||||
selectedDatasetId={selectedDatasetId}
|
||||
selectedDataset={selectedDataset}
|
||||
selectedDatasetSummary={selectedDatasetSummary}
|
||||
selectedRasterMetadata={selectedRasterMetadata}
|
||||
selectedRasterStats={selectedRasterStats}
|
||||
rasterPreview={rasterPreview}
|
||||
rasterUnavailableMessage={rasterUnavailableMessage}
|
||||
selectedClipAreaId={selectedClipAreaId}
|
||||
selectedIntersectTargetId={selectedIntersectTargetId}
|
||||
rasterTileSize={rasterTileSize}
|
||||
rasterTileOverlap={rasterTileOverlap}
|
||||
rasterTileOutputName={rasterTileOutputName}
|
||||
rasterReprojectCrs={rasterReprojectCrs}
|
||||
rasterReprojectResampling={rasterReprojectResampling}
|
||||
ndviNirBand={ndviNirBand}
|
||||
ndviRedBand={ndviRedBand}
|
||||
ndwiGreenBand={ndwiGreenBand}
|
||||
ndwiNirBand={ndwiNirBand}
|
||||
ndbiSwirBand={ndbiSwirBand}
|
||||
ndbiNirBand={ndbiNirBand}
|
||||
isRasterTileInputValid={isRasterTileInputValid}
|
||||
jobs={jobs}
|
||||
loadingDatasetDetails={loadingDatasetDetails}
|
||||
datasetDetailError={datasetDetailError}
|
||||
isVectorDatasetType={isVectorDatasetType}
|
||||
onSetSelectedClipAreaId={setSelectedClipAreaId}
|
||||
onSetSelectedIntersectTargetId={setSelectedIntersectTargetId}
|
||||
onSetRasterTileSize={setRasterTileSize}
|
||||
onSetRasterTileOverlap={setRasterTileOverlap}
|
||||
onSetRasterTileOutputName={setRasterTileOutputName}
|
||||
onSetRasterReprojectCrs={setRasterReprojectCrs}
|
||||
onSetRasterReprojectResampling={setRasterReprojectResampling}
|
||||
onSetNdviNirBand={setNdviNirBand}
|
||||
onSetNdviRedBand={setNdviRedBand}
|
||||
onSetNdwiGreenBand={setNdwiGreenBand}
|
||||
onSetNdwiNirBand={setNdwiNirBand}
|
||||
onSetNdbiSwirBand={setNdbiSwirBand}
|
||||
onSetNdbiNirBand={setNdbiNirBand}
|
||||
onRunRasterInspect={runRasterInspect}
|
||||
onRunRasterPreview={runRasterPreview}
|
||||
onRunRasterStats={runRasterStats}
|
||||
onRunRasterReproject={runRasterReproject}
|
||||
onRunRasterClip={runRasterClip}
|
||||
onRunRasterTile={runRasterTile}
|
||||
onRunRasterNdvi={runRasterNdvi}
|
||||
onRunRasterNdwi={runRasterNdwi}
|
||||
onRunRasterNdbi={runRasterNdbi}
|
||||
onRunVectorClip={runVectorClip}
|
||||
onRunVectorBuffer={runVectorBuffer}
|
||||
onRunVectorIntersect={() => runVectorIntersect(availableVectorTargets)}
|
||||
onPickDerivedDataset={pickDerivedDataset}
|
||||
/>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user