Close full operational audit findings
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
import type {
|
||||
AreaRead,
|
||||
DatasetCreateResponse,
|
||||
ExportRead,
|
||||
ProjectRead,
|
||||
QualityCheckRead,
|
||||
} from '../../types'
|
||||
import type { useSourceFreshness } from '../../hooks/useSourceFreshness'
|
||||
import { SourceFreshnessPanel } from '../status/SourceFreshnessPanel'
|
||||
import { WorkbenchStatusStrip } from '../WorkbenchStatusStrip'
|
||||
|
||||
export type WorkspaceKey = 'overview' | 'data' | 'map' | 'assistant' | 'analysis' | 'ai' | 'exports' | 'system'
|
||||
|
||||
interface OverviewWorkspaceProps {
|
||||
selectedProject: ProjectRead | null
|
||||
selectedProjectId: string | null
|
||||
areas: AreaRead[]
|
||||
datasets: DatasetCreateResponse[]
|
||||
qualityChecks: QualityCheckRead[]
|
||||
exports: ExportRead[]
|
||||
activeLayerFeatureCount: number
|
||||
selectedAreaHasGeometry: boolean
|
||||
hasAnalysisOutput: boolean
|
||||
sourceFreshness: ReturnType<typeof useSourceFreshness>
|
||||
onOpenWorkspace: (target: WorkspaceKey) => void
|
||||
}
|
||||
|
||||
interface WorkflowStep {
|
||||
step: string
|
||||
title: string
|
||||
detail: string
|
||||
status: string
|
||||
ready: boolean
|
||||
target: WorkspaceKey
|
||||
}
|
||||
|
||||
export function OverviewWorkspace({
|
||||
selectedProject,
|
||||
selectedProjectId,
|
||||
areas,
|
||||
datasets,
|
||||
qualityChecks,
|
||||
exports,
|
||||
activeLayerFeatureCount,
|
||||
selectedAreaHasGeometry,
|
||||
hasAnalysisOutput,
|
||||
sourceFreshness,
|
||||
onOpenWorkspace,
|
||||
}: OverviewWorkspaceProps): JSX.Element {
|
||||
const hasMapContext = activeLayerFeatureCount > 0 || selectedAreaHasGeometry
|
||||
const workflowComplete =
|
||||
Boolean(selectedProjectId)
|
||||
&& datasets.length > 0
|
||||
&& hasMapContext
|
||||
&& hasAnalysisOutput
|
||||
&& exports.length > 0
|
||||
const recommendedTarget: WorkspaceKey = !selectedProjectId || datasets.length === 0
|
||||
? 'data'
|
||||
: !hasMapContext
|
||||
? 'map'
|
||||
: !hasAnalysisOutput
|
||||
? 'analysis'
|
||||
: 'exports'
|
||||
const steps: WorkflowStep[] = [
|
||||
{
|
||||
step: '1',
|
||||
title: 'Werkruimte en gebied',
|
||||
detail: selectedProjectId
|
||||
? `${areas.length} ${areas.length === 1 ? 'gebied' : 'gebieden'} beschikbaar`
|
||||
: 'Laad of maak een werkruimte',
|
||||
status: selectedProjectId ? 'gereed' : 'volgende stap',
|
||||
ready: Boolean(selectedProjectId),
|
||||
target: 'data',
|
||||
},
|
||||
{
|
||||
step: '2',
|
||||
title: 'Databronnen',
|
||||
detail: datasets.length > 0
|
||||
? `${datasets.length} ${datasets.length === 1 ? 'databron' : 'databronnen'} ingeladen`
|
||||
: 'Voeg bron- en referentiegegevens toe',
|
||||
status: datasets.length > 0 ? 'gereed' : 'wachten',
|
||||
ready: datasets.length > 0,
|
||||
target: 'data',
|
||||
},
|
||||
{
|
||||
step: '3',
|
||||
title: 'Kaart',
|
||||
detail: hasMapContext
|
||||
? activeLayerFeatureCount > 0
|
||||
? `${activeLayerFeatureCount.toLocaleString('nl-BE')} objecten op de kaart`
|
||||
: 'Werkgebied ingeladen'
|
||||
: 'Bekijk het werkgebied en kies een kaartlaag',
|
||||
status: hasMapContext ? 'gereed' : 'wachten',
|
||||
ready: hasMapContext,
|
||||
target: 'map',
|
||||
},
|
||||
{
|
||||
step: '4',
|
||||
title: 'Controle en analyse',
|
||||
detail: hasAnalysisOutput
|
||||
? 'Er is een bewaard analyse- of kwaliteitsresultaat'
|
||||
: 'Voer een controle uit zodra de gegevens klaarstaan',
|
||||
status: hasAnalysisOutput ? 'gereed' : 'wachten',
|
||||
ready: hasAnalysisOutput,
|
||||
target: 'analysis',
|
||||
},
|
||||
{
|
||||
step: '5',
|
||||
title: 'Downloads',
|
||||
detail: exports.length > 0
|
||||
? `${exports.length} ${exports.length === 1 ? 'resultaat' : 'resultaten'} bewaard`
|
||||
: 'Bewaar een gecontroleerd resultaat',
|
||||
status: exports.length > 0 ? 'gereed' : 'wachten',
|
||||
ready: exports.length > 0,
|
||||
target: 'exports',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="workspace-stack">
|
||||
<WorkbenchStatusStrip
|
||||
selectedProject={selectedProject}
|
||||
areas={areas}
|
||||
datasets={datasets}
|
||||
qualityChecks={qualityChecks}
|
||||
exports={exports}
|
||||
activeLayerFeatureCount={activeLayerFeatureCount}
|
||||
selectedAreaHasGeometry={selectedAreaHasGeometry}
|
||||
/>
|
||||
<SourceFreshnessPanel
|
||||
report={sourceFreshness.report}
|
||||
loading={sourceFreshness.loading}
|
||||
error={sourceFreshness.error}
|
||||
onRefresh={() => { void sourceFreshness.refresh() }}
|
||||
catalogReport={sourceFreshness.catalogReport}
|
||||
catalogLoading={sourceFreshness.catalogLoading}
|
||||
catalogError={sourceFreshness.catalogError}
|
||||
onProbeCatalogs={(force) => { void sourceFreshness.probeCatalogs(force) }}
|
||||
grbRefreshPlan={sourceFreshness.grbRefreshPlan}
|
||||
grbRefreshPlanLoading={sourceFreshness.grbRefreshPlanLoading}
|
||||
grbRefreshPlanError={sourceFreshness.grbRefreshPlanError}
|
||||
/>
|
||||
<details className="status-details-disclosure">
|
||||
<summary>
|
||||
<span>Volledige workflowstatus</span>
|
||||
<strong>{workflowComplete ? 'voltooid' : 'stappen open'}</strong>
|
||||
</summary>
|
||||
<section className="workflow-guidance-panel" aria-label="Voortgang van de werkstroom">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<p className="eyebrow">Van bron tot resultaat</p>
|
||||
<h2>Voortgang van de werkstroom</h2>
|
||||
</div>
|
||||
<span className="status-badge">
|
||||
{workflowComplete ? 'Klaar om te delen' : 'Ga verder met de gemarkeerde stap'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="workflow-guidance-steps">
|
||||
{steps.map((step) => (
|
||||
<button
|
||||
key={`${step.step}-${step.title}`}
|
||||
type="button"
|
||||
className={
|
||||
step.target === recommendedTarget && !step.ready
|
||||
? 'workflow-guidance-step workflow-guidance-step-active'
|
||||
: step.ready
|
||||
? 'workflow-guidance-step workflow-guidance-step-ready'
|
||||
: 'workflow-guidance-step'
|
||||
}
|
||||
onClick={() => onOpenWorkspace(step.target)}
|
||||
aria-label={`Open stap ${step.title}`}
|
||||
>
|
||||
<span className="workflow-step-status">{step.status}</span>
|
||||
<strong>{step.step}. {step.title}</strong>
|
||||
<small>{step.detail}</small>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
<section className="overview-actions">
|
||||
<div className="overview-action-copy">
|
||||
<p className="eyebrow">Snel verder</p>
|
||||
<h2>Kies je volgende actie</h2>
|
||||
</div>
|
||||
<div className="quick-action-grid overview-quick-actions" aria-label="Aanbevolen acties">
|
||||
<button type="button" className="quick-action-button" onClick={() => onOpenWorkspace('data')}>
|
||||
Gegevens beheren
|
||||
</button>
|
||||
<button type="button" className="quick-action-button" onClick={() => onOpenWorkspace('map')}>
|
||||
Kaart openen
|
||||
</button>
|
||||
<button type="button" className="quick-action-button" onClick={() => onOpenWorkspace('analysis')}>
|
||||
Kwaliteit bekijken
|
||||
</button>
|
||||
<button type="button" className="quick-action-button" onClick={() => onOpenWorkspace('exports')}>
|
||||
Downloads beheren
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</details>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user