Files
geointel/frontend/src/hooks/useCoverageResolver.ts
T

81 lines
2.3 KiB
TypeScript

import { useEffect, useState } from 'react'
import { externalApi } from '../services/api'
import type { CoverageResolveResponse, VectorSelectionBBox } from '../types'
import {
COVERAGE_RESPONSE_BUDGET_MS,
exceedsPerformanceBudget,
} from '../lib/performanceBudget'
interface CoverageResolverOptions {
projectId: string | null
bbox: VectorSelectionBBox | null
}
export function useCoverageResolver({ projectId, bbox }: CoverageResolverOptions) {
const [coverage, setCoverage] = useState<CoverageResolveResponse | null>(null)
const [loadingCoverage, setLoadingCoverage] = useState(false)
const [coverageError, setCoverageError] = useState<string | null>(null)
const [coverageDurationMs, setCoverageDurationMs] = useState<number | null>(null)
useEffect(() => {
if (!projectId || !bbox) {
setCoverage(null)
setCoverageError(null)
setLoadingCoverage(false)
setCoverageDurationMs(null)
return
}
let cancelled = false
// A new AOI must never temporarily display the previous AOI's coverage.
// Clear immediately; the debounce only postpones the network request.
setCoverage(null)
setCoverageError(null)
setLoadingCoverage(true)
setCoverageDurationMs(null)
const timer = window.setTimeout(() => {
const startedAt = Date.now()
externalApi.resolveCoverage({
projectId,
bbox: {
minx: bbox.min_x,
miny: bbox.min_y,
maxx: bbox.max_x,
maxy: bbox.max_y,
},
})
.then((result) => {
if (!cancelled) {
setCoverage(result)
}
})
.catch((error) => {
if (!cancelled) {
setCoverage(null)
setCoverageError(error instanceof Error ? error.message : 'Dekking kon niet worden bepaald')
}
})
.finally(() => {
if (!cancelled) {
setCoverageDurationMs(Date.now() - startedAt)
setLoadingCoverage(false)
}
})
}, 250)
return () => {
cancelled = true
window.clearTimeout(timer)
}
}, [projectId, bbox?.min_x, bbox?.min_y, bbox?.max_x, bbox?.max_y])
return {
coverage,
loadingCoverage,
coverageError,
coverageDurationMs,
coverageBudgetExceeded: exceedsPerformanceBudget(
coverageDurationMs,
COVERAGE_RESPONSE_BUDGET_MS,
),
}
}