81 lines
2.3 KiB
TypeScript
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,
|
|
),
|
|
}
|
|
}
|