Add print view, board info card and document logo upload
- Seitenansicht (/projects/:projectId/print): tabular cover page, board overview with supply structure and power sums, one plan per board with a repeating title block; PDF via the browser print dialog with named @page rules (A4 portrait cover, A4/A3 landscape plans, page x of y). - Distribution-board info card (board number, location, fed-from, remark) in the board edit dialog, persisted through the additively extended distribution-board.update command (migration 0008, snapshot schema 6, legacy subtree commands normalized). - Global document logo upload (PNG/JPEG/SVG, max 2 MB) outside project revisions and snapshots. - fed-from stays free text; the overview hierarchy and cumulated sums are preliminary until the feed link is modeled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2e3e85a8e5
commit
4779e4a1a7
40 changed files with 5297 additions and 33 deletions
|
|
@ -387,6 +387,110 @@ describe("distribution-board structure project command", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("updates the info card fields with persisted undo", () => {
|
||||
const context = createTestDatabase();
|
||||
try {
|
||||
const repository =
|
||||
new DistributionBoardStructureProjectCommandRepository(
|
||||
context.db
|
||||
);
|
||||
const structure = createDistributionBoardStructureSnapshot(
|
||||
"project-1",
|
||||
"UV-EG",
|
||||
{ floorId: null, supplyType: "AV" }
|
||||
);
|
||||
const insert = repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 0,
|
||||
source: "user",
|
||||
command: createDistributionBoardInsertProjectCommand(structure),
|
||||
});
|
||||
const readInfo = () =>
|
||||
context.db
|
||||
.select({
|
||||
boardNumber: distributionBoards.boardNumber,
|
||||
location: distributionBoards.location,
|
||||
fedFrom: distributionBoards.fedFrom,
|
||||
remark: distributionBoards.remark,
|
||||
})
|
||||
.from(distributionBoards)
|
||||
.get();
|
||||
assert.deepEqual(readInfo(), {
|
||||
boardNumber: null,
|
||||
location: null,
|
||||
fedFrom: null,
|
||||
remark: null,
|
||||
});
|
||||
|
||||
const forward = repository.executeUpdate({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 1,
|
||||
source: "user",
|
||||
command: createDistributionBoardUpdateProjectCommand(
|
||||
structure.distributionBoard.id,
|
||||
{
|
||||
boardNumber: "UV 0.1",
|
||||
location: "Raum 003 Technik",
|
||||
fedFrom: "HAK",
|
||||
}
|
||||
),
|
||||
});
|
||||
assert.deepEqual(readInfo(), {
|
||||
boardNumber: "UV 0.1",
|
||||
location: "Raum 003 Technik",
|
||||
fedFrom: "HAK",
|
||||
remark: null,
|
||||
});
|
||||
assert.deepEqual(
|
||||
forward.inverse.payload.changes.map((change) => change.field),
|
||||
["boardNumber", "location", "fedFrom"]
|
||||
);
|
||||
|
||||
// A board with info values is no longer the unchanged empty setup.
|
||||
assert.throws(
|
||||
() =>
|
||||
repository.execute({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 2,
|
||||
source: "user",
|
||||
command: insert.inverse,
|
||||
}),
|
||||
/changed before deletion/
|
||||
);
|
||||
|
||||
const undoStep = new ProjectHistoryRepository(
|
||||
context.db
|
||||
).getNextCommand("project-1", "undo");
|
||||
assert.ok(undoStep);
|
||||
repository.executeUpdate({
|
||||
projectId: "project-1",
|
||||
expectedRevision: 2,
|
||||
source: "undo",
|
||||
historyTargetChangeSetId: undoStep.changeSetId,
|
||||
command: forward.inverse,
|
||||
});
|
||||
assert.deepEqual(readInfo(), {
|
||||
boardNumber: null,
|
||||
location: null,
|
||||
fedFrom: null,
|
||||
remark: null,
|
||||
});
|
||||
|
||||
for (const value of ["", " UV 1", "x".repeat(51)]) {
|
||||
assert.throws(
|
||||
() =>
|
||||
createDistributionBoardUpdateProjectCommand(
|
||||
structure.distributionBoard.id,
|
||||
{ boardNumber: value }
|
||||
),
|
||||
/boardNumber/
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("sends distribution-board writes to the revision-safe API", async () => {
|
||||
const requests: Array<{ url: string; method: string; body: unknown }> = [];
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue