Files
geointel/frontend/src/hooks/useExportWorkflow.ts
T
JensandClaude Opus 5 596bbb0e8c Vertaal 56 Engelse foutteksten in de Nederlandse interface
Deze verschenen zodra de backend geen eigen melding meegaf: de terugvalteksten
van formatError en de controles vóór een handeling. Een operator kreeg dan
"Failed to load exports" of "Select a project first" te zien, midden in een
verder Nederlandse werkbank.

Dit is geen meertaligheidsvraagstuk maar inconsistentie binnen de taal die het
product al spreekt. De teksten volgen nu de bestaande toon: benoemen wat er
misging of wat er eerst nodig is, in actieve vorm, zonder excuus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 15:10:07 +02:00

247 lines
7.8 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, 'De downloads konden niet worden geladen'))
} finally {
setLoadingExports(false)
}
}
const exportSelectedDatasetGeoJson = async () => {
if (!selectedDataset || !isVectorDatasetType(selectedDataset.dataset_type)) {
setExportError('Kies eerst een vectorbron om als GeoJSON te bewaren.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson(selectedDataset.project_id, {
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, 'De gekozen bron kon niet worden geëxporteerd'))
} finally {
setExporting(false)
}
}
const exportSelectedDetectionRunGeoJson = async () => {
if (!selectedDetectionRunId || !selectedProjectId) {
setExportError('Kies eerst een detectierun om als GeoJSON te bewaren.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson(selectedProjectId, {
analysis_run_id: selectedDetectionRunId,
export_kind: 'detection_run',
intended_use: 'review',
})
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'De detectierun kon niet worden geëxporteerd'))
} finally {
setExporting(false)
}
}
const exportSelectedSegmentationRunGeoJson = async () => {
if (!selectedSegmentationRunId || !selectedProjectId) {
setExportError('Kies eerst een segmentatierun om als GeoJSON te bewaren.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportGeojson(selectedProjectId, {
analysis_run_id: selectedSegmentationRunId,
export_kind: 'segmentation_run',
})
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'De segmentatierun kon niet worden geëxporteerd'))
} finally {
setExporting(false)
}
}
const exportMapSelectionGeoJson = async (bbox: VectorSelectionBBox, areaId?: string) => {
if (!selectedDataset || !isVectorDatasetType(selectedDataset.dataset_type)) {
setSelectionExportError('Kies eerst een vectorbron om het gebied mee te bewaren.')
return null
}
setSelectionExporting(true)
setSelectionExportError(null)
try {
const response = await exportsApi.exportGeojson(selectedDataset.project_id, {
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, 'De gebiedsdownload kon niet worden bewaard'))
return null
} finally {
setSelectionExporting(false)
}
}
const exportProjectMetadata = async () => {
if (!selectedProjectId) {
setExportError('Kies eerst een werkruimte om de projectgegevens te bewaren.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportProjectMetadata(selectedProjectId)
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'De projectgegevens konden niet worden geëxporteerd'))
} finally {
setExporting(false)
}
}
const exportProjectReport = async () => {
if (!selectedProjectId) {
setExportError('Kies eerst een werkruimte om een rapport te maken.')
return
}
setExporting(true)
setExportError(null)
try {
const response = await exportsApi.exportProjectReport(selectedProjectId)
setLatestExport(response)
await loadExports(selectedProjectId)
} catch (error) {
setExportError(formatError(error, 'Het projectrapport kon niet worden gemaakt'))
} 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 {
if (!selectedProjectId) return
const response = await exportsApi.getContent(selectedProjectId, exportId)
setExportPreview(response.content)
} catch (error) {
setExportError(formatError(error, 'De inhoud van de download kon niet worden geladen'))
}
}
const downloadExportArtifact = (exportId: string) => {
if (!selectedProjectId) return
window.open(exportsApi.downloadUrl(selectedProjectId, 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,
}
}