import type { DetectionModelCapability, ModelAssetRead, YoloPreflightResponse, } from '../../types' import { DETECTION_OPERATOR_PROFILES, type DetectionOperatorProfile } from './detectionProfiles' import { analysisModelAvailabilityMessage } from '../models/modelOptions' interface DetectionModelManagementProps { detectionModels: DetectionModelCapability[] modelAssets: ModelAssetRead[] loadingDetectionModels: boolean detectionModelError: string | null modelAssetError: string | null selectedDetectionModelId: string selectedModelAssetId: string detectionConfidenceThreshold: number yoloPreflight: YoloPreflightResponse | null loadingYoloPreflight: boolean yoloPreflightError: string | null onRefreshYoloPreflight: () => void onSelectModelAsset: (modelAssetId: string) => void onApplyOperatorProfile: (profile: DetectionOperatorProfile) => void } export function detectionModelLabel(model: DetectionModelCapability): string { if (model.model_id === 'yolo-configured') return 'Lokaal gebouwmodel' if (model.model_id === 'manual-fixture-detector') return 'Testmodel (alleen voor demo)' if (model.model_id === 'yolo-placeholder') return 'Gebouwmodel nog niet geconfigureerd' return model.display_name } function formatModelAssetSize(sizeBytes: number): string { if (!Number.isFinite(sizeBytes) || sizeBytes <= 0) return 'n.v.t.' const megabytes = sizeBytes / (1024 * 1024) return `${megabytes.toLocaleString('nl-BE', { maximumFractionDigits: 1 })} MB` } function statusLabel(value: string): string { if (value === 'configured' || value === 'ready') return 'gereed' if (value === 'not_configured') return 'niet geconfigureerd' if (value === 'dependency_unavailable') return 'software ontbreekt' if (value === 'accelerator_unavailable') return 'GPU niet beschikbaar' if (value === 'contract_incomplete') return 'provenance onvolledig' return value.replace(/_/g, ' ') } export function DetectionModelManagement({ detectionModels, modelAssets, loadingDetectionModels, detectionModelError, modelAssetError, selectedDetectionModelId, selectedModelAssetId, detectionConfidenceThreshold, yoloPreflight, loadingYoloPreflight, yoloPreflightError, onRefreshYoloPreflight, onSelectModelAsset, onApplyOperatorProfile, }: DetectionModelManagementProps): JSX.Element { const selectedModelAsset = modelAssets.find((asset) => asset.model_asset_id === selectedModelAssetId) ?? null const selectedOperatorProfile = DETECTION_OPERATOR_PROFILES.find( (profile) => profile.modelAssetId === selectedModelAssetId, ) ?? null const yoloRuntimeReady = Boolean( yoloPreflight?.checks.enabled && yoloPreflight.checks.dependencies_available && yoloPreflight.checks.accelerator_ready === true && yoloPreflight.checks.model_file_exists, ) return (
GeoIntel leest de modelregistratie en lokale bestanden.
{detectionModelError}
{modelAssetError}
Vernieuw de status zodra de backend opnieuw bereikbaar is.
Ondersteunde klassen: {model.supported_classes.join(', ') || 'niet opgegeven'}
{analysisModelAvailabilityMessage(model)}
GeoIntel kiest automatisch het actieve lokale model. Een andere keuze geldt alleen voor deze analyse.
{profile.description}
Achtergrondtoets: {profile.backgroundGate}. Meting: {profile.evidenceReference}.
{profile.limitationMessage}
Plaats een gecontroleerd model in de modelmap of configureer het bestaande YOLO-modelpad.
Bestand: {selectedModelAsset.filename}
Status: {statusLabel(selectedModelAsset.status)}
Actief servermodel: {selectedModelAsset.active ? 'ja' : 'nee'}
Automatisch downloaden: {selectedModelAsset.will_download_models ? 'ja' : 'nee'}
Grootte: {formatModelAssetSize(selectedModelAsset.size_bytes)}
SHA-256: {selectedModelAsset.sha256.slice(0, 12)}
Pad: {selectedModelAsset.model_path}
Deze alleen-lezen controle start geen analyse en downloadt geen modelbestanden.
GeoIntel controleert configuratie, optionele software en lokale bestanden.
{yoloPreflightError}
Vernieuw de controle voordat je een lokaal model gebruikt.