Finish audit UI and live validation closure
This commit is contained in:
@@ -25,8 +25,29 @@ function detectionQualityInterpretation(f1: number | null | undefined): string {
|
||||
return 'Onvoldoende betrouwbaar voor operationeel gebruik.'
|
||||
}
|
||||
|
||||
function detectionStatusLabel(status: string): string {
|
||||
if (status === 'completed') return 'afgerond'
|
||||
if (status === 'success') return 'geslaagd'
|
||||
if (status === 'failed') return 'mislukt'
|
||||
if (status === 'running') return 'bezig'
|
||||
if (status === 'queued') return 'in wachtrij'
|
||||
return status.replace(/_/g, ' ')
|
||||
}
|
||||
|
||||
function persistedDetectionModelLabel(modelName: string | null | undefined): string {
|
||||
if (!modelName) return 'Gebouwdetectie'
|
||||
if (modelName === 'yolo-configured') return 'Lokaal gebouwmodel'
|
||||
if (modelName === 'manual-fixture-detector') return 'Testmodel'
|
||||
if (modelName === 'yolo-placeholder') return 'Niet-geconfigureerd gebouwmodel'
|
||||
return modelName
|
||||
}
|
||||
|
||||
function detectionClassLabel(className: string): string {
|
||||
if (className.toLowerCase() === 'building') return 'Gebouw'
|
||||
return className
|
||||
}
|
||||
|
||||
function formatDetectionRunLabel(run: DetectionRunRead): string {
|
||||
const status = run.status === 'completed' ? 'afgerond' : run.status
|
||||
const timestamp = run.finished_at ?? run.created_at
|
||||
const dateLabel = timestamp
|
||||
? new Intl.DateTimeFormat('nl-BE', {
|
||||
@@ -34,7 +55,7 @@ function formatDetectionRunLabel(run: DetectionRunRead): string {
|
||||
timeStyle: 'short',
|
||||
}).format(new Date(timestamp))
|
||||
: 'datum onbekend'
|
||||
return `${run.model_name || 'Gebouwdetectie'} · ${status} · ${dateLabel}`
|
||||
return `${persistedDetectionModelLabel(run.model_name)} · ${detectionStatusLabel(run.status)} · ${dateLabel}`
|
||||
}
|
||||
|
||||
interface CalibrationRow {
|
||||
@@ -753,18 +774,16 @@ export function DetectionLab({
|
||||
<th>Type</th>
|
||||
<th>Zekerheid</th>
|
||||
<th>Model</th>
|
||||
<th>Beeldtegel</th>
|
||||
<th>Herkomst</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{visibleDetectionItems.map((detection) => (
|
||||
<tr key={detection.id}>
|
||||
<td>{detection.class_name}</td>
|
||||
<td>{detectionClassLabel(detection.class_name)}</td>
|
||||
<td>{detection.confidence.toFixed(2)}</td>
|
||||
<td>{detection.model_name}</td>
|
||||
<td className="source-tile-cell" title={detection.source_tile_path ?? undefined}>
|
||||
{formatSourceTilePath(detection.source_tile_path)}
|
||||
</td>
|
||||
<td>{persistedDetectionModelLabel(detection.model_name)}</td>
|
||||
<td className="source-tile-cell">Luchtbeeldtegel</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
@@ -1119,11 +1138,3 @@ function downloadJsonFile(filename: string, payload: unknown): void {
|
||||
function formatNullableNumber(value: number | null, digits: number): string {
|
||||
return typeof value === 'number' && Number.isFinite(value) ? value.toFixed(digits) : 'n.v.t.'
|
||||
}
|
||||
|
||||
function formatSourceTilePath(path: string | null | undefined): string {
|
||||
if (!path) {
|
||||
return 'n.v.t.'
|
||||
}
|
||||
const parts = path.replace(/\\/g, '/').split('/').filter(Boolean)
|
||||
return parts[parts.length - 1] ?? path
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user