Polish QA and export workspaces
This commit is contained in:
@@ -54,57 +54,103 @@ export function ExportCenter({
|
||||
onDownload,
|
||||
}: ExportCenterProps): JSX.Element {
|
||||
const canExportDataset = Boolean(selectedDataset && isVectorDatasetType(selectedDataset.dataset_type))
|
||||
const geojsonExports = exports.filter((item) => item.export_type.includes('geojson')).length
|
||||
const reportExports = exports.filter((item) => item.export_type === 'project_report_html').length
|
||||
|
||||
return (
|
||||
<section data-testid="export-center">
|
||||
<h2>Export Center</h2>
|
||||
<button type="button" onClick={onRefresh} disabled={!selectedProjectId || loadingExports} data-testid="refresh-exports">
|
||||
Refresh exports
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onExportProjectMetadata}
|
||||
disabled={!selectedProjectId || exporting}
|
||||
data-testid="export-project-metadata"
|
||||
>
|
||||
Export project metadata JSON
|
||||
</button>
|
||||
<button type="button" onClick={onExportProjectReport} disabled={!selectedProjectId || exporting}>
|
||||
Export project report HTML
|
||||
</button>
|
||||
<button type="button" onClick={onExportDataset} disabled={!canExportDataset || exporting}>
|
||||
Export selected vector GeoJSON
|
||||
</button>
|
||||
<button type="button" onClick={onExportDetectionRun} disabled={!selectedDetectionRunId || exporting}>
|
||||
Export selected detection run GeoJSON
|
||||
</button>
|
||||
<button type="button" onClick={onExportSegmentationRun} disabled={!selectedSegmentationRunId || exporting}>
|
||||
Export selected segmentation run GeoJSON
|
||||
</button>
|
||||
<section className="export-center" data-testid="export-center">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<h2>Export Center</h2>
|
||||
<p className="muted">Create handoff artifacts from persisted datasets, AI runs and project metadata.</p>
|
||||
</div>
|
||||
<span className="count-pill">{exports.length} exports</span>
|
||||
</div>
|
||||
<div className="quality-summary-grid">
|
||||
<div>
|
||||
<span>GeoJSON</span>
|
||||
<strong>{geojsonExports}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Reports</span>
|
||||
<strong>{reportExports}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>Selected dataset</span>
|
||||
<strong>{selectedDataset?.name ?? 'none'}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div className="export-action-grid">
|
||||
<button
|
||||
type="button"
|
||||
className="secondary-action"
|
||||
onClick={onRefresh}
|
||||
disabled={!selectedProjectId || loadingExports}
|
||||
data-testid="refresh-exports"
|
||||
>
|
||||
Refresh exports
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="primary-action"
|
||||
onClick={onExportProjectMetadata}
|
||||
disabled={!selectedProjectId || exporting}
|
||||
data-testid="export-project-metadata"
|
||||
>
|
||||
Export project metadata JSON
|
||||
</button>
|
||||
<button type="button" className="secondary-action" onClick={onExportProjectReport} disabled={!selectedProjectId || exporting}>
|
||||
Export project report HTML
|
||||
</button>
|
||||
<button type="button" className="secondary-action" onClick={onExportDataset} disabled={!canExportDataset || exporting}>
|
||||
Export selected vector GeoJSON
|
||||
</button>
|
||||
<button type="button" className="secondary-action" onClick={onExportDetectionRun} disabled={!selectedDetectionRunId || exporting}>
|
||||
Export selected detection run GeoJSON
|
||||
</button>
|
||||
<button type="button" className="secondary-action" onClick={onExportSegmentationRun} disabled={!selectedSegmentationRunId || exporting}>
|
||||
Export selected segmentation run GeoJSON
|
||||
</button>
|
||||
</div>
|
||||
{exportError ? <p className="error">{exportError}</p> : null}
|
||||
{latestExport ? (
|
||||
<p>
|
||||
Latest export: {latestExport.export_type} {'->'} {latestExport.path}
|
||||
</p>
|
||||
<div className="latest-export-card">
|
||||
<span>Latest export</span>
|
||||
<strong>{latestExport.export_type}</strong>
|
||||
<p>{latestExport.path}</p>
|
||||
</div>
|
||||
) : null}
|
||||
{exports.length === 0 ? <p>No exports registered yet.</p> : null}
|
||||
<ul>
|
||||
{exports.length === 0 ? (
|
||||
<div className="empty-state">
|
||||
<strong>No exports registered yet.</strong>
|
||||
<p>Create metadata, GeoJSON or HTML report artifacts once the active project has data to hand off.</p>
|
||||
</div>
|
||||
) : null}
|
||||
<ul className="export-list">
|
||||
{exports.map((item) => (
|
||||
<li key={item.id}>
|
||||
<strong>{item.export_type}</strong>
|
||||
<div>status: {item.status}</div>
|
||||
<div>path: {item.storage_path}</div>
|
||||
<div>export id: {item.id}</div>
|
||||
{canPreviewJson(item) ? (
|
||||
<button type="button" onClick={() => onPreviewContent(item.id)}>
|
||||
Preview JSON content
|
||||
<li className="export-card" key={item.id}>
|
||||
<div className="export-card-header">
|
||||
<div>
|
||||
<strong>{item.export_type}</strong>
|
||||
<div className="entity-meta">
|
||||
<span>export id: {item.id}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span className={item.status === 'ready' ? 'status-badge status-badge-ready' : 'status-badge'}>{item.status}</span>
|
||||
</div>
|
||||
<p>{item.storage_path}</p>
|
||||
<div className="button-row">
|
||||
{canPreviewJson(item) ? (
|
||||
<button type="button" className="secondary-action" onClick={() => onPreviewContent(item.id)}>
|
||||
Preview JSON content
|
||||
</button>
|
||||
) : (
|
||||
<span className="status-badge">download-only HTML artifact</span>
|
||||
)}
|
||||
<button type="button" className="primary-action" onClick={() => onDownload(item.id)}>
|
||||
Download artifact
|
||||
</button>
|
||||
) : (
|
||||
<div>Preview: download-only HTML artifact</div>
|
||||
)}
|
||||
<button type="button" onClick={() => onDownload(item.id)}>
|
||||
Download artifact
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -8,8 +8,14 @@ export function ExportPreview({ content }: ExportPreviewProps): JSX.Element | nu
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<h2>Export Preview</h2>
|
||||
<section className="export-preview-panel">
|
||||
<div className="panel-title-row">
|
||||
<div>
|
||||
<h2>Export Preview</h2>
|
||||
<p className="muted">JSON and GeoJSON content preview for the selected export artifact.</p>
|
||||
</div>
|
||||
<span className="count-pill">preview</span>
|
||||
</div>
|
||||
<pre className="job-result">{JSON.stringify(content, null, 2)}</pre>
|
||||
</section>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user