feat: add governed nationwide AOI orchestration and CUDA enforcement
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
import type { ProviderCapability } from '../../types'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import type { AoiOperation, ProviderCapability } from '../../types'
|
||||
import { aoiOperationsApi } from '../../services/api'
|
||||
|
||||
interface ProviderPanelProps {
|
||||
selectedProjectId: string | null
|
||||
providers: ProviderCapability[]
|
||||
loadingCapabilities: boolean
|
||||
capabilitiesError: string | null
|
||||
@@ -40,6 +43,7 @@ function providerLayerLabel(value: string): string {
|
||||
}
|
||||
|
||||
export function ProviderPanel({
|
||||
selectedProjectId,
|
||||
providers,
|
||||
loadingCapabilities,
|
||||
capabilitiesError,
|
||||
@@ -49,6 +53,32 @@ export function ProviderPanel({
|
||||
onOpenMap,
|
||||
}: ProviderPanelProps): JSX.Element {
|
||||
const configuredCount = providers.filter((provider) => provider.configured).length
|
||||
const [operations, setOperations] = useState<AoiOperation[]>([])
|
||||
const [operationsError, setOperationsError] = useState<string | null>(null)
|
||||
const [loadingOperations, setLoadingOperations] = useState(false)
|
||||
const loadOperations = useCallback(async () => {
|
||||
if (!selectedProjectId) {
|
||||
setOperations([])
|
||||
return
|
||||
}
|
||||
setLoadingOperations(true)
|
||||
try {
|
||||
const response = await aoiOperationsApi.list(selectedProjectId)
|
||||
setOperations(response.items)
|
||||
setOperationsError(null)
|
||||
} catch (error) {
|
||||
setOperationsError(error instanceof Error ? error.message : 'AOI-verwerking kon niet worden geladen.')
|
||||
} finally {
|
||||
setLoadingOperations(false)
|
||||
}
|
||||
}, [selectedProjectId])
|
||||
|
||||
useEffect(() => {
|
||||
void loadOperations()
|
||||
const timer = window.setInterval(() => void loadOperations(), 5000)
|
||||
return () => window.clearInterval(timer)
|
||||
}, [loadOperations])
|
||||
|
||||
return (
|
||||
<section className="system-provider-panel">
|
||||
<div className="system-provider-shell">
|
||||
@@ -93,6 +123,31 @@ export function ProviderPanel({
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<section className="system-provider-capability-surface" aria-label="AOI-verwerkingsvoortgang">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<strong>Gebiedsverwerking</strong>
|
||||
<p className="muted">Server-side partities, hervatbare voortgang en bronfouten voor grote selecties.</p>
|
||||
</div>
|
||||
<button type="button" className="secondary-action" onClick={() => void loadOperations()} disabled={loadingOperations || !selectedProjectId}>Vernieuwen</button>
|
||||
</div>
|
||||
{loadingOperations && operations.length === 0 ? <div className="result-state result-state-loading"><strong>Verwerkingen laden.</strong></div> : null}
|
||||
{operationsError ? <div className="result-state result-state-error"><strong>Verwerkingsstatus niet bereikbaar.</strong><p>{operationsError}</p></div> : null}
|
||||
{!loadingOperations && !operationsError && operations.length === 0 ? <div className="result-state result-state-empty"><strong>Nog geen gebiedsverwerking.</strong><p>Grote officiële bronselecties verschijnen hier met één gezamenlijke voortgang.</p></div> : null}
|
||||
{operations.length > 0 ? (
|
||||
<ul className="system-provider-list">
|
||||
{operations.map((operation) => (
|
||||
<li className="system-provider-card" key={operation.id}>
|
||||
<div className="system-provider-header"><div><strong>{operation.operation_type}</strong><span>{String(operation.plan_json.provider_key ?? 'bron')} · {String(operation.plan_json.product_key ?? 'product')}</span></div><span className={operation.status === 'success' ? 'status-badge status-badge-ready' : 'status-badge'}>{operation.status}</span></div>
|
||||
<progress value={operation.progress} max={1} aria-label={`Voortgang ${operation.operation_type}`} />
|
||||
<div className="entity-meta"><span>{Math.round(operation.progress * 100)}%</span><span>{operation.partitions.length} partities</span><span>{operation.partition_counts.failed ?? 0} mislukt</span></div>
|
||||
{operation.error_message ? <p className="inline-error">{operation.error_message}</p> : null}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</section>
|
||||
|
||||
<div className="system-provider-capability-surface" aria-label="Provider capability registry">
|
||||
<div className="provider-detail-stack">
|
||||
<strong>Officiële referentiebronnen</strong>
|
||||
|
||||
Reference in New Issue
Block a user