Files
geointel/frontend/src/hooks/useExportWorkflow.ts
T
Codex a29c787238
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s
Complete operational map result workflow
2026-07-17 12:35:50 +02:00

244 lines
7.4 KiB
TypeScript

import { useState } from 'react'
import { exportsApi } from '../services/api'
import type {
DatasetCreateResponse,
ExportCreateResponse,
ExportRead,
MapResultExportRequest,
VectorSelectionBBox,
} from '../types'
import { formatError } from '../lib/formatError'
interface ExportWorkflowOptions {
selectedProjectId: string | null
selectedDataset: DatasetCreateResponse | null
selectedDetectionRunId: string
selectedSegmentationRunId: string
isVectorDatasetType: (datasetType: string) => boolean
}
export function useExportWorkflow({
selectedProjectId,
selectedDataset,
selectedDetectionRunId,
selectedSegmentationRunId,
isVectorDatasetType,
}: ExportWorkflowOptions) {
const [exports, setExports] = useState<ExportRead[]>([])
const [latestExport, setLatestExport] = useState<ExportCreateResponse | null>(null)
const [exportError, setExportError] = useState<string | null>(null)
const [loadingExports, setLoadingExports] = useState(false)
const [exporting, setExporting] = useState(false)
const [selectionExporting, setSelectionExporting] = useState(false)
const [selectionExportError, setSelectionExportError] = useState<string | null>(null)
const [latestSelectionExport, setLatestSelectionExport] = useState<ExportCreateResponse | null>(null)
const [exportPreview, setExportPreview] = useState<Record<string, unknown> | null>(null)
const loadExports = async (projectId = selectedProjectId) => {
if (!projectId) {
setExports([])
return
}
setLoadingExports(true)
setExportError(null)
try {
const response = await exportsApi.listProjectExports(projectId)
setExports(response.items)
} catch (error) {
setExportError(formatError(error, 'Failed to load exports'))
} finally {
setLoadingExports(false)
}
}
const exportSelectedDatasetGeoJson = async () => {
if (!selectedDataset || !isVectorDatasetType(selectedDataset.dataset_type)) {
setExportError('Select a vector dataset before exporting GeoJSON.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson({
dataset_id: selectedDataset.id,
export_kind: 'dataset',
name: selectedDataset.name.replace(/\.(geo)?json$/i, ''),
})
setLatestExport(response)
await loadExports(selectedDataset.project_id)
} catch (error) {
setExportError(formatError(error, 'Failed to export selected dataset'))
} finally {
setExporting(false)
}
}
const exportSelectedDetectionRunGeoJson = async () => {
if (!selectedDetectionRunId) {
setExportError('Select a detection run before exporting GeoJSON.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson({
analysis_run_id: selectedDetectionRunId,
export_kind: 'detection_run',
})
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'Failed to export detection run'))
} finally {
setExporting(false)
}
}
const exportSelectedSegmentationRunGeoJson = async () => {
if (!selectedSegmentationRunId) {
setExportError('Select a segmentation run before exporting GeoJSON.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson({
analysis_run_id: selectedSegmentationRunId,
export_kind: 'segmentation_run',
})
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'Failed to export segmentation run'))
} finally {
setExporting(false)
}
}
const exportMapSelectionGeoJson = async (bbox: VectorSelectionBBox, areaId?: string) => {
if (!selectedDataset || !isVectorDatasetType(selectedDataset.dataset_type)) {
setSelectionExportError('Select a vector dataset before saving an area export.')
return null
}
setSelectionExporting(true)
setSelectionExportError(null)
try {
const response = await exportsApi.exportGeojson({
dataset_id: selectedDataset.id,
area_id: areaId,
export_kind: 'vector_selection',
bbox: { ...bbox, crs: 'EPSG:4326' },
limit: 250,
name: `${selectedDataset.name.replace(/\.(geo)?json$/i, '')}-selection`,
})
setLatestExport(response)
setLatestSelectionExport(response)
await loadExports(selectedDataset.project_id)
return response
} catch (error) {
setSelectionExportError(formatError(error, 'Failed to save area export'))
return null
} finally {
setSelectionExporting(false)
}
}
const exportProjectMetadata = async () => {
if (!selectedProjectId) {
setExportError('Select a project before exporting metadata.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportProjectMetadata(selectedProjectId)
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'Failed to export project metadata'))
} finally {
setExporting(false)
}
}
const exportProjectReport = async () => {
if (!selectedProjectId) {
setExportError('Select a project before exporting a report.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportProjectReport(selectedProjectId)
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'Failed to export project report'))
} finally {
setExporting(false)
}
}
const persistMapResult = async (payload: MapResultExportRequest) => {
setSelectionExporting(true)
setSelectionExportError(null)
try {
const response = await exportsApi.exportMapResult(payload)
setLatestExport(response)
setLatestSelectionExport(response)
await loadExports(payload.project_id)
return response
} catch (error) {
setSelectionExportError(formatError(error, 'Het kaartresultaat kon niet worden bewaard.'))
return null
} finally {
setSelectionExporting(false)
}
}
const previewExportContent = async (exportId: string) => {
setExportError(null)
try {
const response = await exportsApi.getContent(exportId)
setExportPreview(response.content)
} catch (error) {
setExportError(formatError(error, 'Failed to load export content'))
}
}
const downloadExportArtifact = (exportId: string) => {
window.open(exportsApi.downloadUrl(exportId), '_blank', 'noopener,noreferrer')
}
const resetExportsForProject = () => {
setExports([])
setLatestExport(null)
setLatestSelectionExport(null)
setSelectionExportError(null)
setExportPreview(null)
}
return {
exports,
latestExport,
exportError,
loadingExports,
exporting,
selectionExporting,
selectionExportError,
latestSelectionExport,
exportPreview,
loadExports,
exportSelectedDatasetGeoJson,
exportSelectedDetectionRunGeoJson,
exportSelectedSegmentationRunGeoJson,
exportMapSelectionGeoJson,
persistMapResult,
exportProjectMetadata,
exportProjectReport,
previewExportContent,
downloadExportArtifact,
resetExportsForProject,
}
}