Add raster tile detection handoff
This commit is contained in:
@@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Sprint 99 raster tile Detection Lab handoff (2026-06-23)
|
||||||
|
|
||||||
|
- Surfaced the latest persisted `raster.tile` manifest path in the raster dataset inspector.
|
||||||
|
- Added a direct Detection Lab handoff action that fills the selected raster dataset and tile manifest path from the existing raster tile job result.
|
||||||
|
- Preserved existing raster, detection and segmentation API contracts; no AI inference, provider fetching, migrations or backend route changes were introduced.
|
||||||
|
- Added regression coverage for the frontend handoff wiring.
|
||||||
|
|
||||||
## Sprint 98 demo raster workflow smoke (2026-06-23)
|
## Sprint 98 demo raster workflow smoke (2026-06-23)
|
||||||
|
|
||||||
- Added `scripts/verify_demo_raster_workflow.sh` to validate the browser-facing demo raster happy path: inspect, preview, stats and tile manifest generation.
|
- Added `scripts/verify_demo_raster_workflow.sh` to validate the browser-facing demo raster happy path: inspect, preview, stats and tile manifest generation.
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_raster_tile_manifest_is_visible_and_can_handoff_to_detection_lab() -> None:
|
||||||
|
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||||
|
hook = (ROOT / "frontend" / "src" / "hooks" / "useDatasetWorkflow.ts").read_text(encoding="utf-8")
|
||||||
|
detail_panel = (ROOT / "frontend" / "src" / "components" / "datasets" / "DatasetDetailPanel.tsx").read_text(encoding="utf-8")
|
||||||
|
raster_controls = (ROOT / "frontend" / "src" / "components" / "datasets" / "RasterControls.tsx").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
assert "latestRasterTileManifestPath" in hook
|
||||||
|
assert "extractRasterTileManifestPath" in hook
|
||||||
|
assert "setLatestRasterTileManifestPath(manifestPath)" in hook
|
||||||
|
assert "latestRasterTileManifestPath," in app
|
||||||
|
assert "onUseTileManifestForDetection: useRasterTileManifestForDetection" in app
|
||||||
|
assert "setDetectionTileManifestPath(manifestPath)" in app
|
||||||
|
assert "setSelectedDetectionDatasetId(selectedDataset.id)" in app
|
||||||
|
assert "latestRasterTileManifestPath" in detail_panel
|
||||||
|
assert "onUseTileManifestForDetection" in detail_panel
|
||||||
|
assert "Latest tile manifest" in raster_controls
|
||||||
|
assert "Use in Detection Lab" in raster_controls
|
||||||
|
assert "disabled={!latestRasterTileManifestPath}" in raster_controls
|
||||||
@@ -1,3 +1,32 @@
|
|||||||
|
## Sprint 99 raster tile Detection Lab handoff (2026-06-23)
|
||||||
|
|
||||||
|
Changed:
|
||||||
|
- Added latest raster tile manifest tracking to `frontend/src/hooks/useDatasetWorkflow.ts` from persisted `raster.tile` job results and direct tile generation responses.
|
||||||
|
- Surfaced the latest manifest path in `frontend/src/components/datasets/RasterControls.tsx`.
|
||||||
|
- Added a `Use in Detection Lab` handoff that fills the selected raster dataset and tile manifest path in the existing Detection Lab state.
|
||||||
|
- Updated `frontend/src/components/datasets/DatasetDetailPanel.tsx`, `frontend/src/App.tsx`, `frontend/README.md` and `CHANGELOG.md`.
|
||||||
|
- Added `backend/tests/test_sprint99_raster_ui_handoff.py`.
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
- RED: `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py -q` failed before implementation because the raster tile manifest state and handoff wiring did not exist.
|
||||||
|
- `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py -q` passed.
|
||||||
|
- `cd frontend && npm run typecheck` passed.
|
||||||
|
- `python -m pytest backend\tests\test_sprint99_raster_ui_handoff.py backend\tests\test_sprint95_raster_pipeline_hardening.py backend\tests\test_sprint28_dataset_workflow_hook.py -q` passed: 6 tests.
|
||||||
|
- `cd frontend && npm run build` passed.
|
||||||
|
- `python -m compileall backend/app` passed.
|
||||||
|
- `python -m pytest -q` from `backend/` passed: 322 tests.
|
||||||
|
- `bash scripts/run_readiness_check.sh` passed.
|
||||||
|
- `cd backend && python -m alembic heads` passed: `202606120900 (head)`.
|
||||||
|
- `cd backend && python -m alembic upgrade head --sql` passed.
|
||||||
|
- `bash -n scripts/live_migration_smoke.sh` passed.
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
- Frontend handoff only; no API contract, migration, provider fetching, AI inference or model behavior changes.
|
||||||
|
- The Detection Lab still follows the existing model availability and explicit-run constraints.
|
||||||
|
|
||||||
|
Next recommended pass:
|
||||||
|
- Run full readiness, redeploy, then validate the demo raster tile flow and Detection Lab prefill live on `http://192.168.10.150:1202`.
|
||||||
|
|
||||||
## Sprint 98 demo raster workflow smoke (2026-06-23)
|
## Sprint 98 demo raster workflow smoke (2026-06-23)
|
||||||
|
|
||||||
Changed:
|
Changed:
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ AI Lab run controls explicitly explain when no raster dataset is available, inst
|
|||||||
- When the Map workspace has no active result layer, it lists ready vector/GeoJSON datasets as direct quick actions so populated demo projects can jump straight from the empty state to map inspection.
|
- When the Map workspace has no active result layer, it lists ready vector/GeoJSON datasets as direct quick actions so populated demo projects can jump straight from the empty state to map inspection.
|
||||||
- The Data catalog shows a compact selected/reference/candidate/source summary and scan-friendly badges. Persisted `reference` datasets are shown as Reference, non-reference vector/GeoJSON layers are shown as QA Candidates for workbench scanning, and raster/other uploads remain Source.
|
- The Data catalog shows a compact selected/reference/candidate/source summary and scan-friendly badges. Persisted `reference` datasets are shown as Reference, non-reference vector/GeoJSON layers are shown as QA Candidates for workbench scanning, and raster/other uploads remain Source.
|
||||||
- Dataset cards explain the recommended next action and use compact two-line action buttons for inspect, map, export/QA and metadata refresh. Disabled actions keep a visible reason, such as `Vector/GeoJSON only`.
|
- Dataset cards explain the recommended next action and use compact two-line action buttons for inspect, map, export/QA and metadata refresh. Disabled actions keep a visible reason, such as `Vector/GeoJSON only`.
|
||||||
|
- Raster controls show the latest generated tile manifest path from persisted `raster.tile` jobs and can hand that path directly to Detection Lab with the selected raster dataset.
|
||||||
- The QA/QC workspace shows candidate/reference handoff cards and resolves persisted quality-check dataset IDs back to dataset names when the datasets are loaded in the current project context.
|
- The QA/QC workspace shows candidate/reference handoff cards and resolves persisted quality-check dataset IDs back to dataset names when the datasets are loaded in the current project context.
|
||||||
- The QA/QC workspace includes a selected-check evidence drilldown with candidate/reference provenance, false-positive/negative metric evidence, map handoff context and parameters/findings JSON.
|
- The QA/QC workspace includes a selected-check evidence drilldown with candidate/reference provenance, false-positive/negative metric evidence, map handoff context and parameters/findings JSON.
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ function App(): JSX.Element {
|
|||||||
datasetContent,
|
datasetContent,
|
||||||
jobs,
|
jobs,
|
||||||
rasterPreview,
|
rasterPreview,
|
||||||
|
latestRasterTileManifestPath,
|
||||||
selectedIntersectTargetId,
|
selectedIntersectTargetId,
|
||||||
selectedClipAreaId,
|
selectedClipAreaId,
|
||||||
rasterTileSize,
|
rasterTileSize,
|
||||||
@@ -254,6 +255,15 @@ function App(): JSX.Element {
|
|||||||
loadProjectData,
|
loadProjectData,
|
||||||
loadQualityChecks,
|
loadQualityChecks,
|
||||||
})
|
})
|
||||||
|
const useRasterTileManifestForDetection = () => {
|
||||||
|
const manifestPath = latestRasterTileManifestPath.trim()
|
||||||
|
if (!manifestPath || !selectedDataset || selectedDataset.dataset_type !== 'raster') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setDetectionTileManifestPath(manifestPath)
|
||||||
|
setSelectedDetectionDatasetId(selectedDataset.id)
|
||||||
|
setActiveWorkspace('ai')
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
segmentationModels,
|
segmentationModels,
|
||||||
loadingSegmentationModels,
|
loadingSegmentationModels,
|
||||||
@@ -949,6 +959,7 @@ function App(): JSX.Element {
|
|||||||
selectedRasterMetadata,
|
selectedRasterMetadata,
|
||||||
selectedRasterStats,
|
selectedRasterStats,
|
||||||
rasterPreview,
|
rasterPreview,
|
||||||
|
latestRasterTileManifestPath,
|
||||||
rasterUnavailableMessage,
|
rasterUnavailableMessage,
|
||||||
selectedClipAreaId,
|
selectedClipAreaId,
|
||||||
selectedIntersectTargetId,
|
selectedIntersectTargetId,
|
||||||
@@ -987,6 +998,7 @@ function App(): JSX.Element {
|
|||||||
onRunRasterReproject: runRasterReproject,
|
onRunRasterReproject: runRasterReproject,
|
||||||
onRunRasterClip: runRasterClip,
|
onRunRasterClip: runRasterClip,
|
||||||
onRunRasterTile: runRasterTile,
|
onRunRasterTile: runRasterTile,
|
||||||
|
onUseTileManifestForDetection: useRasterTileManifestForDetection,
|
||||||
onRunRasterNdvi: runRasterNdvi,
|
onRunRasterNdvi: runRasterNdvi,
|
||||||
onRunRasterNdwi: runRasterNdwi,
|
onRunRasterNdwi: runRasterNdwi,
|
||||||
onRunRasterNdbi: runRasterNdbi,
|
onRunRasterNdbi: runRasterNdbi,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface DatasetDetailPanelProps {
|
|||||||
selectedRasterMetadata: RasterMetadataResponse | null
|
selectedRasterMetadata: RasterMetadataResponse | null
|
||||||
selectedRasterStats: RasterStatsResponse | null
|
selectedRasterStats: RasterStatsResponse | null
|
||||||
rasterPreview: RasterPreviewResponse | null
|
rasterPreview: RasterPreviewResponse | null
|
||||||
|
latestRasterTileManifestPath: string
|
||||||
rasterUnavailableMessage: string | null
|
rasterUnavailableMessage: string | null
|
||||||
selectedClipAreaId: string
|
selectedClipAreaId: string
|
||||||
selectedIntersectTargetId: string
|
selectedIntersectTargetId: string
|
||||||
@@ -57,6 +58,7 @@ export interface DatasetDetailPanelProps {
|
|||||||
onRunRasterReproject: () => void
|
onRunRasterReproject: () => void
|
||||||
onRunRasterClip: () => void
|
onRunRasterClip: () => void
|
||||||
onRunRasterTile: () => void
|
onRunRasterTile: () => void
|
||||||
|
onUseTileManifestForDetection: () => void
|
||||||
onRunRasterNdvi: () => void
|
onRunRasterNdvi: () => void
|
||||||
onRunRasterNdwi: () => void
|
onRunRasterNdwi: () => void
|
||||||
onRunRasterNdbi: () => void
|
onRunRasterNdbi: () => void
|
||||||
@@ -100,6 +102,7 @@ export function DatasetDetailPanel({
|
|||||||
selectedRasterMetadata,
|
selectedRasterMetadata,
|
||||||
selectedRasterStats,
|
selectedRasterStats,
|
||||||
rasterPreview,
|
rasterPreview,
|
||||||
|
latestRasterTileManifestPath,
|
||||||
rasterUnavailableMessage,
|
rasterUnavailableMessage,
|
||||||
selectedClipAreaId,
|
selectedClipAreaId,
|
||||||
selectedIntersectTargetId,
|
selectedIntersectTargetId,
|
||||||
@@ -138,6 +141,7 @@ export function DatasetDetailPanel({
|
|||||||
onRunRasterReproject,
|
onRunRasterReproject,
|
||||||
onRunRasterClip,
|
onRunRasterClip,
|
||||||
onRunRasterTile,
|
onRunRasterTile,
|
||||||
|
onUseTileManifestForDetection,
|
||||||
onRunRasterNdvi,
|
onRunRasterNdvi,
|
||||||
onRunRasterNdwi,
|
onRunRasterNdwi,
|
||||||
onRunRasterNdbi,
|
onRunRasterNdbi,
|
||||||
@@ -171,6 +175,7 @@ export function DatasetDetailPanel({
|
|||||||
selectedRasterMetadata={selectedRasterMetadata}
|
selectedRasterMetadata={selectedRasterMetadata}
|
||||||
selectedRasterStats={selectedRasterStats}
|
selectedRasterStats={selectedRasterStats}
|
||||||
rasterPreview={rasterPreview}
|
rasterPreview={rasterPreview}
|
||||||
|
latestRasterTileManifestPath={latestRasterTileManifestPath}
|
||||||
rasterUnavailableMessage={rasterUnavailableMessage}
|
rasterUnavailableMessage={rasterUnavailableMessage}
|
||||||
selectedClipAreaId={selectedClipAreaId}
|
selectedClipAreaId={selectedClipAreaId}
|
||||||
rasterTileSize={rasterTileSize}
|
rasterTileSize={rasterTileSize}
|
||||||
@@ -203,6 +208,7 @@ export function DatasetDetailPanel({
|
|||||||
onRunRasterReproject={onRunRasterReproject}
|
onRunRasterReproject={onRunRasterReproject}
|
||||||
onRunRasterClip={onRunRasterClip}
|
onRunRasterClip={onRunRasterClip}
|
||||||
onRunRasterTile={onRunRasterTile}
|
onRunRasterTile={onRunRasterTile}
|
||||||
|
onUseTileManifestForDetection={onUseTileManifestForDetection}
|
||||||
onRunRasterNdvi={onRunRasterNdvi}
|
onRunRasterNdvi={onRunRasterNdvi}
|
||||||
onRunRasterNdwi={onRunRasterNdwi}
|
onRunRasterNdwi={onRunRasterNdwi}
|
||||||
onRunRasterNdbi={onRunRasterNdbi}
|
onRunRasterNdbi={onRunRasterNdbi}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ interface RasterControlsProps {
|
|||||||
selectedRasterMetadata: RasterMetadataResponse | null
|
selectedRasterMetadata: RasterMetadataResponse | null
|
||||||
selectedRasterStats: RasterStatsResponse | null
|
selectedRasterStats: RasterStatsResponse | null
|
||||||
rasterPreview: RasterPreviewResponse | null
|
rasterPreview: RasterPreviewResponse | null
|
||||||
|
latestRasterTileManifestPath: string
|
||||||
rasterUnavailableMessage: string | null
|
rasterUnavailableMessage: string | null
|
||||||
selectedClipAreaId: string
|
selectedClipAreaId: string
|
||||||
rasterTileSize: number
|
rasterTileSize: number
|
||||||
@@ -38,6 +39,7 @@ interface RasterControlsProps {
|
|||||||
onRunRasterReproject: () => void
|
onRunRasterReproject: () => void
|
||||||
onRunRasterClip: () => void
|
onRunRasterClip: () => void
|
||||||
onRunRasterTile: () => void
|
onRunRasterTile: () => void
|
||||||
|
onUseTileManifestForDetection: () => void
|
||||||
onRunRasterNdvi: () => void
|
onRunRasterNdvi: () => void
|
||||||
onRunRasterNdwi: () => void
|
onRunRasterNdwi: () => void
|
||||||
onRunRasterNdbi: () => void
|
onRunRasterNdbi: () => void
|
||||||
@@ -57,6 +59,7 @@ export function RasterControls({
|
|||||||
selectedRasterMetadata,
|
selectedRasterMetadata,
|
||||||
selectedRasterStats,
|
selectedRasterStats,
|
||||||
rasterPreview,
|
rasterPreview,
|
||||||
|
latestRasterTileManifestPath,
|
||||||
rasterUnavailableMessage,
|
rasterUnavailableMessage,
|
||||||
selectedClipAreaId,
|
selectedClipAreaId,
|
||||||
rasterTileSize,
|
rasterTileSize,
|
||||||
@@ -89,6 +92,7 @@ export function RasterControls({
|
|||||||
onRunRasterReproject,
|
onRunRasterReproject,
|
||||||
onRunRasterClip,
|
onRunRasterClip,
|
||||||
onRunRasterTile,
|
onRunRasterTile,
|
||||||
|
onUseTileManifestForDetection,
|
||||||
onRunRasterNdvi,
|
onRunRasterNdvi,
|
||||||
onRunRasterNdwi,
|
onRunRasterNdwi,
|
||||||
onRunRasterNdbi,
|
onRunRasterNdbi,
|
||||||
@@ -156,11 +160,14 @@ export function RasterControls({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="raster-manifest-handoff">
|
<div className="raster-manifest-handoff">
|
||||||
<span>Tile manifest handoff</span>
|
<span>Latest tile manifest</span>
|
||||||
<p>
|
<p>
|
||||||
Generated tile manifests remain backend artifacts and are referenced by path in detection/segmentation requests; this panel only prepares
|
{latestRasterTileManifestPath ||
|
||||||
and explains the handoff.
|
'No tile manifest generated yet. Generate tiles before handing this raster to Detection Lab.'}
|
||||||
</p>
|
</p>
|
||||||
|
<button type="button" onClick={onUseTileManifestForDetection} disabled={!latestRasterTileManifestPath}>
|
||||||
|
Use in Detection Lab
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section className="raster-guardrail-surface" aria-label="Processing guardrails">
|
<section className="raster-guardrail-surface" aria-label="Processing guardrails">
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ function toRasterMetadata(metadata: Record<string, unknown> | null | undefined):
|
|||||||
return metadata as unknown as RasterMetadataResponse
|
return metadata as unknown as RasterMetadataResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractRasterTileManifestPath(job: JobRead | null | undefined): string {
|
||||||
|
const result = job?.result_json
|
||||||
|
if (!result) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const manifestPath = result.manifest_path
|
||||||
|
return typeof manifestPath === 'string' ? manifestPath : ''
|
||||||
|
}
|
||||||
|
|
||||||
export function useDatasetWorkflow({
|
export function useDatasetWorkflow({
|
||||||
selectedProjectId,
|
selectedProjectId,
|
||||||
areas,
|
areas,
|
||||||
@@ -43,6 +52,7 @@ export function useDatasetWorkflow({
|
|||||||
const [datasetContent, setDatasetContent] = useState<GeoJSON.FeatureCollection | null>(null)
|
const [datasetContent, setDatasetContent] = useState<GeoJSON.FeatureCollection | null>(null)
|
||||||
const [jobs, setJobs] = useState<JobRead[]>([])
|
const [jobs, setJobs] = useState<JobRead[]>([])
|
||||||
const [rasterPreview, setRasterPreview] = useState<RasterPreviewResponse | null>(null)
|
const [rasterPreview, setRasterPreview] = useState<RasterPreviewResponse | null>(null)
|
||||||
|
const [latestRasterTileManifestPath, setLatestRasterTileManifestPath] = useState('')
|
||||||
const [selectedIntersectTargetId, setSelectedIntersectTargetId] = useState('')
|
const [selectedIntersectTargetId, setSelectedIntersectTargetId] = useState('')
|
||||||
const [selectedClipAreaId, setSelectedClipAreaId] = useState('')
|
const [selectedClipAreaId, setSelectedClipAreaId] = useState('')
|
||||||
const [rasterTileSize, setRasterTileSize] = useState(512)
|
const [rasterTileSize, setRasterTileSize] = useState(512)
|
||||||
@@ -100,6 +110,10 @@ export function useDatasetWorkflow({
|
|||||||
const loadDatasetJobs = async (projectId: string, datasetId: string) => {
|
const loadDatasetJobs = async (projectId: string, datasetId: string) => {
|
||||||
const response = await jobsApi.list(projectId, { dataset_id: datasetId, limit: 20, offset: 0 })
|
const response = await jobsApi.list(projectId, { dataset_id: datasetId, limit: 20, offset: 0 })
|
||||||
setJobs(response.items)
|
setJobs(response.items)
|
||||||
|
const latestRasterTileJob = response.items.find(
|
||||||
|
(job) => job.job_type === 'raster.tile' && extractRasterTileManifestPath(job),
|
||||||
|
)
|
||||||
|
setLatestRasterTileManifestPath(extractRasterTileManifestPath(latestRasterTileJob))
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadDatasetDetails = async (projectId: string, dataset: DatasetCreateResponse) => {
|
const loadDatasetDetails = async (projectId: string, dataset: DatasetCreateResponse) => {
|
||||||
@@ -111,6 +125,7 @@ export function useDatasetWorkflow({
|
|||||||
setSelectedRasterStats(null)
|
setSelectedRasterStats(null)
|
||||||
setDatasetContent(null)
|
setDatasetContent(null)
|
||||||
setRasterPreview(null)
|
setRasterPreview(null)
|
||||||
|
setLatestRasterTileManifestPath('')
|
||||||
setSelectedDatasetId(dataset.id)
|
setSelectedDatasetId(dataset.id)
|
||||||
setJobs([])
|
setJobs([])
|
||||||
try {
|
try {
|
||||||
@@ -352,12 +367,17 @@ export function useDatasetWorkflow({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await datasetsApi.rasterTile(selectedProjectId, selectedDatasetId, {
|
const job = await datasetsApi.rasterTile(selectedProjectId, selectedDatasetId, {
|
||||||
tile_size: rasterTileSize,
|
tile_size: rasterTileSize,
|
||||||
overlap: rasterTileOverlap,
|
overlap: rasterTileOverlap,
|
||||||
output_name: rasterTileOutputName || undefined,
|
output_name: rasterTileOutputName || undefined,
|
||||||
})
|
})
|
||||||
|
const manifestPath = extractRasterTileManifestPath(job)
|
||||||
|
setLatestRasterTileManifestPath(manifestPath)
|
||||||
await refreshSelectedDatasetAfterJob()
|
await refreshSelectedDatasetAfterJob()
|
||||||
|
if (manifestPath) {
|
||||||
|
setLatestRasterTileManifestPath(manifestPath)
|
||||||
|
}
|
||||||
setDatasetDetailError(null)
|
setDatasetDetailError(null)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setDatasetDetailError(formatError(error, 'Raster tile failed'))
|
setDatasetDetailError(formatError(error, 'Raster tile failed'))
|
||||||
@@ -444,6 +464,7 @@ export function useDatasetWorkflow({
|
|||||||
setSelectedRasterStats(null)
|
setSelectedRasterStats(null)
|
||||||
setDatasetContent(null)
|
setDatasetContent(null)
|
||||||
setRasterPreview(null)
|
setRasterPreview(null)
|
||||||
|
setLatestRasterTileManifestPath('')
|
||||||
setJobs([])
|
setJobs([])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +477,7 @@ export function useDatasetWorkflow({
|
|||||||
datasetContent,
|
datasetContent,
|
||||||
jobs,
|
jobs,
|
||||||
rasterPreview,
|
rasterPreview,
|
||||||
|
latestRasterTileManifestPath,
|
||||||
selectedIntersectTargetId,
|
selectedIntersectTargetId,
|
||||||
selectedClipAreaId,
|
selectedClipAreaId,
|
||||||
rasterTileSize,
|
rasterTileSize,
|
||||||
|
|||||||
Reference in New Issue
Block a user