fix: polish live regional workbench labels
This commit is contained in:
@@ -17,7 +17,7 @@ export interface DetectionOperatorProfile {
|
||||
export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
|
||||
{
|
||||
id: 'small-building-balanced-review',
|
||||
displayName: 'Recommended small-building review',
|
||||
displayName: 'Aanbevolen controleprofiel kleine gebouwen',
|
||||
modelAssetId: 'geointel-building-yolov8s-smallbld-minpx3-img640-ft30-pt',
|
||||
confidenceThreshold: 0.15,
|
||||
defaultApproved: true,
|
||||
@@ -28,13 +28,13 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
description:
|
||||
'Recommended recall-balanced profile for building review, with improved small-building coverage across seven Kempen AOIs.',
|
||||
'Aanbevolen profiel met een evenwicht tussen gevonden en gemiste kleine gebouwen, gemeten over zeven testgebieden in de Kempen.',
|
||||
limitationMessage:
|
||||
'The pure-empty gate passed and persisted QA found 1,571 fewer false negatives than the previous balanced profile; expect a higher false-positive review load.',
|
||||
'De lege-achtergrondtest is geslaagd en de kwaliteitsmeting vond 1.571 minder gemiste gebouwen dan het vorige profiel. Controleer wel extra op onterecht gevonden objecten.',
|
||||
},
|
||||
{
|
||||
id: 'expanded-balanced-review',
|
||||
displayName: 'Legacy expanded balanced review',
|
||||
displayName: 'Voorgaand gebalanceerd controleprofiel',
|
||||
modelAssetId: 'geointel-building-yolov8s-aoi1024expandedminpx4vis035e50-pt',
|
||||
confidenceThreshold: 0.15,
|
||||
defaultApproved: true,
|
||||
@@ -44,13 +44,13 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
|
||||
f1: 0.5432865390636915,
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
description: 'Legacy expanded-AOI profile for review sessions where precision matters more than the newest recall gain.',
|
||||
description: 'Voorgaand profiel voor controles waarbij minder foutieve vondsten belangrijker zijn dan maximale dekking.',
|
||||
limitationMessage:
|
||||
'The pure-empty gate passed; this profile has fewer false positives but more persistent small-building misses than the recommended profile.',
|
||||
'De lege-achtergrondtest is geslaagd. Dit profiel vindt minder onterechte objecten, maar mist meer kleine gebouwen dan het aanbevolen profiel.',
|
||||
},
|
||||
{
|
||||
id: 'conservative-review',
|
||||
displayName: 'Promoted conservative review',
|
||||
displayName: 'Conservatief controleprofiel',
|
||||
modelAssetId: 'geointel-building-yolov8s-aoi1024bg512r3e50-pt',
|
||||
confidenceThreshold: 0.35,
|
||||
defaultApproved: true,
|
||||
@@ -60,8 +60,8 @@ export const DETECTION_OPERATOR_PROFILES: DetectionOperatorProfile[] = [
|
||||
f1: 0.32086574003576274,
|
||||
positiveSampleCount: 7,
|
||||
maxBackgroundDetections: 0,
|
||||
description: 'Legacy high-precision profile for review sessions where fewer false positives matter more than recall.',
|
||||
description: 'Profiel met hoge precisie voor controles waarbij zo weinig mogelijk foutieve vondsten zwaarder wegen dan volledige dekking.',
|
||||
limitationMessage:
|
||||
'Default-approved after the split-background pure-empty gate passed; sparse-context detections remain review-only evidence.',
|
||||
'Goedgekeurd na de lege-achtergrondtest. Resultaten in dun bebouwde context blijven altijd controlebewijs en geen automatische waarheid.',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import type { FormEvent } from 'react'
|
||||
import type { AreaRead, ProjectRead } from '../../types'
|
||||
|
||||
function projectDisplayName(project: ProjectRead | null): string {
|
||||
if (project?.name === 'Kempen Regional Workbench') {
|
||||
return 'Kempen · volledige regio'
|
||||
}
|
||||
if (project?.name === 'Mol Municipality Workbench') {
|
||||
return 'Mol · lokale historische werkruimte'
|
||||
}
|
||||
return project?.name ?? 'Geen werkruimte actief'
|
||||
}
|
||||
|
||||
interface AreaFormState {
|
||||
name: string
|
||||
geometry: string
|
||||
@@ -41,7 +51,7 @@ export function AreaPanel({
|
||||
</div>
|
||||
<span className="count-pill">{areas.length}</span>
|
||||
</div>
|
||||
<p className="muted">{selectedProject ? selectedProject.name : 'Geen werkruimte actief'}</p>
|
||||
<p className="muted">{projectDisplayName(selectedProject)}</p>
|
||||
|
||||
<div className="data-selection-summary data-selection-summary-area">
|
||||
<span>Getoond op de kaart</span>
|
||||
|
||||
@@ -2,11 +2,27 @@ import type { FormEvent } from 'react'
|
||||
import type { ProjectCreate, ProjectRead } from '../../types'
|
||||
|
||||
const TECHNICAL_PROJECT_PATTERN = /^(GeoIntel Detection Quality Matrix|GeoIntel hard-negative|GeoIntel training|Mol Building QA)/i
|
||||
const REGIONAL_PROJECT_NAME = 'Kempen Regional Workbench'
|
||||
const LEGACY_MOL_PROJECT_NAME = 'Mol Municipality Workbench'
|
||||
|
||||
function isTechnicalProject(project: ProjectRead): boolean {
|
||||
return TECHNICAL_PROJECT_PATTERN.test(project.name)
|
||||
}
|
||||
|
||||
function isAdvancedProject(project: ProjectRead): boolean {
|
||||
return isTechnicalProject(project) || project.name === LEGACY_MOL_PROJECT_NAME
|
||||
}
|
||||
|
||||
function projectDisplayName(project: ProjectRead): string {
|
||||
if (project.name === REGIONAL_PROJECT_NAME) {
|
||||
return 'Kempen · volledige regionale werkruimte'
|
||||
}
|
||||
if (project.name === LEGACY_MOL_PROJECT_NAME) {
|
||||
return 'Mol · lokale historische werkruimte'
|
||||
}
|
||||
return project.name
|
||||
}
|
||||
|
||||
interface ProjectPanelProps {
|
||||
projects: ProjectRead[]
|
||||
selectedProjectId: string | null
|
||||
@@ -33,9 +49,9 @@ export function ProjectPanel({
|
||||
onLoadDemoWorkflow,
|
||||
}: ProjectPanelProps): JSX.Element {
|
||||
const selectedProject = projects.find((project) => project.id === selectedProjectId)
|
||||
const regularProjects = projects.filter((project) => !isTechnicalProject(project))
|
||||
const technicalProjects = projects.filter(isTechnicalProject)
|
||||
const visibleProjects = selectedProject && isTechnicalProject(selectedProject)
|
||||
const regularProjects = projects.filter((project) => !isAdvancedProject(project))
|
||||
const advancedProjects = projects.filter(isAdvancedProject)
|
||||
const visibleProjects = selectedProject && isAdvancedProject(selectedProject)
|
||||
? [selectedProject, ...regularProjects]
|
||||
: regularProjects
|
||||
|
||||
@@ -52,7 +68,7 @@ export function ProjectPanel({
|
||||
|
||||
<div className="data-selection-summary data-selection-summary-project">
|
||||
<span>Actieve werkruimte</span>
|
||||
<strong>{selectedProject?.name ?? 'Geen werkruimte actief'}</strong>
|
||||
<strong>{selectedProject ? projectDisplayName(selectedProject) : 'Geen werkruimte actief'}</strong>
|
||||
<small>{selectedProject?.region ?? 'De regionale werkruimte wordt automatisch gekozen.'}</small>
|
||||
</div>
|
||||
|
||||
@@ -68,7 +84,7 @@ export function ProjectPanel({
|
||||
aria-pressed={project.id === selectedProjectId}
|
||||
data-testid={`project-select-${project.id}`}
|
||||
>
|
||||
<strong>{project.name}</strong>
|
||||
<strong>{projectDisplayName(project)}</strong>
|
||||
<span>{project.region || 'Regio niet opgegeven'}</span>
|
||||
</button>
|
||||
</li>
|
||||
@@ -118,11 +134,11 @@ export function ProjectPanel({
|
||||
</button>
|
||||
{demoWorkflowMessage ? <p>{demoWorkflowMessage}</p> : null}
|
||||
</div>
|
||||
{technicalProjects.length > 0 ? (
|
||||
{advancedProjects.length > 0 ? (
|
||||
<details className="technical-run-list">
|
||||
<summary>{technicalProjects.length} technische test- en benchmarkruns</summary>
|
||||
<summary>{advancedProjects.length} alternatieve en technische werkruimtes</summary>
|
||||
<ul className="entity-list">
|
||||
{technicalProjects.map((project) => (
|
||||
{advancedProjects.map((project) => (
|
||||
<li key={project.id}>
|
||||
<button
|
||||
className={project.id === selectedProjectId ? 'entity-card entity-card-active' : 'entity-card'}
|
||||
@@ -131,7 +147,7 @@ export function ProjectPanel({
|
||||
aria-pressed={project.id === selectedProjectId}
|
||||
data-testid={`project-select-${project.id}`}
|
||||
>
|
||||
<strong>{project.name}</strong>
|
||||
<strong>{projectDisplayName(project)}</strong>
|
||||
<span>{project.region || 'Technische run'}</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -45,6 +45,13 @@ function qualityMetricValue(metric: MetricRead | undefined): string {
|
||||
return Number.isInteger(value) ? String(value) : value.toFixed(3)
|
||||
}
|
||||
|
||||
function qualityStatusLabel(status: string | null | undefined): string {
|
||||
if (!status || status === 'waiting') return 'nog niet uitgevoerd'
|
||||
if (status === 'completed' || status === 'ok') return 'afgerond'
|
||||
if (status === 'failed') return 'mislukt'
|
||||
return status
|
||||
}
|
||||
|
||||
function metricByKey(check: QualityCheckRead | null, metricKey: string): MetricRead | undefined {
|
||||
return check?.metrics.find((metric) => metric.metric_key === metricKey)
|
||||
}
|
||||
@@ -169,7 +176,7 @@ export function QualityResultsPanel({
|
||||
</div>
|
||||
<div>
|
||||
<span>Laatste status</span>
|
||||
<strong>{latestCheck?.status ?? 'waiting'}</strong>
|
||||
<strong>{qualityStatusLabel(latestCheck?.status)}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -201,7 +208,7 @@ export function QualityResultsPanel({
|
||||
</div>
|
||||
<div>
|
||||
<span>Laatste vergelijking</span>
|
||||
<strong>{latestCheck?.status ?? 'waiting'}</strong>
|
||||
<strong>{qualityStatusLabel(latestCheck?.status)}</strong>
|
||||
<p className="quality-dataset-name">
|
||||
Te controleren: {latestCandidateName ?? latestCheck?.candidate_dataset_id ?? 'n.v.t.'} / referentie: {latestReferenceName ?? latestCheck?.reference_dataset_id ?? 'n.v.t.'}
|
||||
</p>
|
||||
|
||||
@@ -12,7 +12,7 @@ const DATASET_LABEL_BY_LAYER: Record<string, string> = {
|
||||
}
|
||||
|
||||
export function getDatasetDisplayName(dataset: DatasetCreateResponse): string {
|
||||
const layer = (dataset.reference_layer_name ?? dataset.source_metadata?.layer_name ?? '')
|
||||
const layer = (dataset.reference_layer_name ?? dataset.source_metadata?.layer_name ?? dataset.source_metadata?.layer_type ?? '')
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
const label = DATASET_LABEL_BY_LAYER[layer]
|
||||
|
||||
Reference in New Issue
Block a user