51 lines
5.6 KiB
TypeScript
51 lines
5.6 KiB
TypeScript
"use client";
|
|
|
|
import { ArrowLeft, FileSpreadsheet, Settings, Upload } from "lucide-react";
|
|
import { useParams } from "next/navigation";
|
|
import { useEffect, useState } from "react";
|
|
import { IconLink } from "../../../../frontend/components/icon-link";
|
|
import { RevitInitialImportWizard } from "../../../../frontend/components/revit-initial-import-wizard";
|
|
import { RevitObjectTable } from "../../../../frontend/components/revit-object-table";
|
|
import { RevitXlsxSettingsModal } from "../../../../frontend/components/revit-xlsx-settings-modal";
|
|
import type { ExternalModelConfiguration } from "../../../../external-model/configuration/external-model-configuration";
|
|
import { detectExternalModelWorkbook, getExternalInitialImportStatus, getExternalModelConfiguration, getProject, updateExternalModelConfiguration } from "../../../../frontend/utils/api";
|
|
import { createDefaultRevitXlsxConfiguration } from "../../../../frontend/utils/revit-xlsx-settings";
|
|
import type { ExternalInitialImportStatusDto, ExternalModelConfigurationSnapshotDto, ProjectDto } from "../../../../frontend/types";
|
|
|
|
export default function RevitPage() {
|
|
const { projectId } = useParams<{ projectId: string }>();
|
|
const [project, setProject] = useState<ProjectDto | null>(null);
|
|
const [snapshot, setSnapshot] = useState<ExternalModelConfigurationSnapshotDto | null>(null);
|
|
const [importStatus, setImportStatus] = useState<ExternalInitialImportStatusDto | null>(null);
|
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
const [importOpen, setImportOpen] = useState(false);
|
|
const [saving, setSaving] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
Promise.all([getProject(projectId), getExternalModelConfiguration(projectId), getExternalInitialImportStatus(projectId)])
|
|
.then(([loadedProject, configuration, status]) => { setProject(loadedProject); setSnapshot(configuration.configuration); setImportStatus(status); })
|
|
.catch((value: unknown) => setError(value instanceof Error ? value.message : "Revit-Daten konnten nicht geladen werden."));
|
|
}, [projectId]);
|
|
|
|
async function save(configuration: ExternalModelConfiguration) {
|
|
if (!project) return;
|
|
setSaving(true); setError(null);
|
|
try {
|
|
const result = await updateExternalModelConfiguration(projectId, project.currentRevision, configuration);
|
|
setSnapshot(result.configuration);
|
|
setProject({ ...project, currentRevision: result.history.currentRevision });
|
|
setSettingsOpen(false);
|
|
} catch (value) { setError(value instanceof Error ? value.message : "Einstellungen konnten nicht gespeichert werden."); }
|
|
finally { setSaving(false); }
|
|
}
|
|
|
|
return <main className="container py-4">
|
|
<div className="page-header"><div><div className="kicker">Projekt · Revit</div><h1>{project?.name ?? "Revit-Anbindung"}</h1><p className="text-secondary mb-0">Linear-XLSX austauschen und Revit-Objekte verwalten</p></div><div className="d-flex gap-2"><button className="btn btn-success btn-with-icon" disabled={!project || !snapshot || Boolean(importStatus?.imported)} onClick={() => setImportOpen(true)} type="button"><Upload size={16} />Erstimport</button><button className="btn btn-primary btn-with-icon" disabled={!project} onClick={() => setSettingsOpen(true)} type="button"><Settings size={16} />Einstellungen</button><IconLink href={`/projects/${projectId}`} icon={ArrowLeft} label="Zum Projekt" showLabel /></div></div>
|
|
{error ? <div className="alert alert-danger">{error}</div> : null}
|
|
<div className="row g-3 mt-1"><div className="col-md-6"><section className="card h-100"><div className="card-body"><FileSpreadsheet className="mb-3" size={28} /><h2 className="h5">XLSX-Konfiguration</h2><p className="text-secondary">{snapshot ? "Die Linear-Spalten und das Tabellenlayout sind konfiguriert." : "Noch keine XLSX-Konfiguration gespeichert."}</p><span className={`badge ${snapshot ? "text-bg-success" : "text-bg-secondary"}`}>{snapshot ? "Konfiguriert" : "Offen"}</span></div></section></div><div className="col-md-6"><section className="card h-100"><div className="card-body"><h2 className="h5">Importstatus</h2>{importStatus?.imported ? <><p className="mb-1"><strong>{importStatus.objectCount} Revit-Objekte</strong>{importStatus.fileName ? ` aus ${importStatus.fileName}` : ""}</p><p className="text-secondary mb-0">Quelle: {importStatus.sourceName}</p></> : <p className="text-secondary mb-0">Noch kein Linear-XLSX-Import vorhanden.</p>}</div></section></div></div>
|
|
{importStatus?.imported ? <RevitObjectTable projectId={projectId} onRevision={(revision) => setProject((current) => current ? { ...current, currentRevision: revision } : current)} /> : null}
|
|
{settingsOpen ? <RevitXlsxSettingsModal configuration={snapshot?.configuration ?? createDefaultRevitXlsxConfiguration()} isNewConfiguration={snapshot === null} isSaving={saving} onClose={() => setSettingsOpen(false)} onInspectSample={async (file, configuration) => { const result = await detectExternalModelWorkbook(projectId, file, configuration); return `Muster erkannt: ${result.sheetName}, ${result.columnCount} Spalten, ${result.objectCount} Objekte.`; }} onSave={save} /> : null}
|
|
{importOpen && project && snapshot ? <RevitInitialImportWizard projectId={projectId} expectedRevision={project.currentRevision} initialConfiguration={snapshot.configuration} onClose={() => setImportOpen(false)} onImported={({ history }) => { setProject({ ...project, currentRevision: history.currentRevision }); setImportOpen(false); void Promise.all([getExternalInitialImportStatus(projectId), getExternalModelConfiguration(projectId)]).then(([status, configuration]) => { setImportStatus(status); setSnapshot(configuration.configuration); }); }} /> : null}
|
|
</main>;
|
|
}
|