Add Revit initial import wizard

This commit is contained in:
2026-08-02 17:52:21 +02:00
parent 8646f346e6
commit ab2449419b
10 changed files with 481 additions and 32 deletions
+94 -2
View File
@@ -2,17 +2,23 @@ import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { RevitCsvModal } from "../src/frontend/components/revit-csv-modal.js";
import {
RevitCsvImportPlan,
RevitCsvModal,
} from "../src/frontend/components/revit-csv-modal.js";
import {
applyExternalInitialImport,
getExternalCsvConfiguration,
planExternalInitialImport,
previewExternalCsv,
updateExternalCsvConfiguration,
} from "../src/frontend/utils/api.js";
import type { ExternalInitialImportPlanDto } from "../src/frontend/types.js";
import { createDefaultExternalCsvConfiguration } from "../src/external-model/csv/external-csv-contracts.js";
import { externalCsvTestColumns } from "./fixtures/revit-csv-fixtures.js";
describe("Revit CSV frontend API", () => {
it("uses the project-scoped configuration and preview endpoints", async () => {
it("uses the project-scoped configuration, preview and import endpoints", async () => {
const requests: Array<{ url: string; method: string; body: unknown }> = [];
const originalFetch = globalThis.fetch;
globalThis.fetch = async (input, init) => {
@@ -32,6 +38,17 @@ describe("Revit CSV frontend API", () => {
await getExternalCsvConfiguration("project-1");
await updateExternalCsvConfiguration("project-1", 7, configuration);
await previewExternalCsv("project-1", "revit.csv", "YWJj");
await planExternalInitialImport("project-1", "revit.csv", "YWJj");
await applyExternalInitialImport("project-1", {
expectedRevision: 8,
expectedConfigurationVersion: 2,
expectedSha256: "sha",
fileName: "revit.csv",
contentBase64: "YWJj",
sourceName: "Revit-Gesamtmodell",
roomDecisions: [{ sourceRoomKey: "101|büro", roomId: "room-1", defaultDistributionBoardId: "board-1" }],
familyProjectDeviceDecisions: [{ familyAndType: "Steckdose : Standard", projectDeviceId: "device-1" }],
});
} finally {
globalThis.fetch = originalFetch;
}
@@ -52,6 +69,25 @@ describe("Revit CSV frontend API", () => {
method: "POST",
body: { fileName: "revit.csv", contentBase64: "YWJj" },
},
{
url: "/api/projects/project-1/external-csv/initial-import/plan",
method: "POST",
body: { fileName: "revit.csv", contentBase64: "YWJj" },
},
{
url: "/api/projects/project-1/external-csv/initial-import/apply",
method: "POST",
body: {
expectedRevision: 8,
expectedConfigurationVersion: 2,
expectedSha256: "sha",
fileName: "revit.csv",
contentBase64: "YWJj",
sourceName: "Revit-Gesamtmodell",
roomDecisions: [{ sourceRoomKey: "101|büro", roomId: "room-1", defaultDistributionBoardId: "board-1" }],
familyProjectDeviceDecisions: [{ familyAndType: "Steckdose : Standard", projectDeviceId: "device-1" }],
},
},
]);
});
});
@@ -70,4 +106,60 @@ describe("Revit CSV modal presentation", () => {
assert.match(markup, /max-width:calc\(100vw - 2rem\)/);
assert.doesNotMatch(markup, /modal-lg/);
});
it("renders the initial import decisions without individual object rows", () => {
const plan: ExternalInitialImportPlanDto = {
configurationVersion: 2,
fileName: "revit.csv",
sha256: "sha",
byteLength: 100,
rowCount: 2,
objectCount: 1,
passthroughCount: 1,
suspectObjectCount: 0,
suspectRowNumbers: [],
sourceRooms: [{
sourceRoomKey: "101|büro",
roomNumber: "101",
roomName: "Büro",
objectCount: 1,
suggestedRoomId: "room-1",
matchStatus: "exact-number",
candidateRoomIds: ["room-1"],
}],
familyGroups: [{
familyAndType: "Steckdose : Standard",
objectCount: 1,
classified: true,
category: "single_phase",
connectionKind: null,
internalDeviceType: "socket",
}],
issueCounts: { unknownFamilyAndType: 0, invalidPower: 0, invalidQuantity: 0, missingRoom: 0 },
objects: [],
existing: {
floors: [{ id: "floor-1", name: "EG", sortOrder: 0 }],
rooms: [{ id: "room-1", floorId: "floor-1", roomNumber: "101", roomName: "Büro" }],
distributionBoards: [{ id: "board-1", name: "UV-01", floorId: "floor-1" }],
projectDevices: [{ id: "device-1", name: "Steckdose", displayName: "Steckdose", category: "single_phase", connectionKind: null, powerPerUnit: 100 }],
},
};
const markup = renderToStaticMarkup(createElement(RevitCsvImportPlan, {
familyLinks: { "Steckdose : Standard": "device-1" },
isApplying: false,
onApply: () => undefined,
onFamilyLinkChange: () => undefined,
onRoomDecisionChange: () => undefined,
plan,
roomDecisions: { "101|büro": { roomId: "room-1", defaultDistributionBoardId: "board-1" } },
setSourceName: () => undefined,
sourceName: "Revit-Gesamtmodell",
}));
assert.match(markup, /Erstimport vorbereiten/);
assert.match(markup, /101 · Büro/);
assert.match(markup, /Steckdose : Standard/);
assert.match(markup, /Erstimport übernehmen/);
assert.doesNotMatch(markup, /IFC-GUID/);
});
});