forked from jappel/leistungsbilanz-ts
Compact single-board feeder circuit rows
This commit is contained in:
parent
ade21fe386
commit
9165b8238c
11 changed files with 181 additions and 14 deletions
11
AGENTS.md
11
AGENTS.md
|
|
@ -476,6 +476,17 @@ downstream board's demand after its own board simultaneity factor to the chosen
|
||||||
feeding circuit as a read-only virtual row. Recursive chains and several boards
|
feeding circuit as a read-only virtual row. Recursive chains and several boards
|
||||||
on one circuit are supported. A board-only link affects hierarchy but adds no
|
on one circuit are supported. A board-only link affects hierarchy but adds no
|
||||||
load until a feeding circuit is selected.
|
load until a feeding circuit is selected.
|
||||||
|
The distribution-board dialog can create one empty feeder circuit and link it
|
||||||
|
in the same `distribution-board.create-feeder-circuit` project command. Its
|
||||||
|
history inverse restores the complete previous board update before removing
|
||||||
|
only the unchanged generated circuit; Redo reuses its UUID and BMK. No
|
||||||
|
CircuitDeviceRow is created. The three-phase group is suggested, the optional
|
||||||
|
circuit display name stays empty by default, and protection remains open for
|
||||||
|
planner sizing. A circuit with exactly one downstream board and no device rows
|
||||||
|
is rendered as one compact row using the live board number/name; several
|
||||||
|
downstream boards or additional devices retain summary and child rows. Editing
|
||||||
|
the name or remark of an empty reserve circuit changes the circuit itself and
|
||||||
|
does not implicitly create a device row.
|
||||||
Distribution-board floor assignment and a project-enabled supply type use
|
Distribution-board floor assignment and a project-enabled supply type use
|
||||||
`distribution-board.update`; both values are snapshot/export fields and one
|
`distribution-board.update`; both values are snapshot/export fields and one
|
||||||
persistent undo step.
|
persistent undo step.
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,13 @@ commands. Endpoints, payloads and calculation rules: `docs/estimate-balance.md`.
|
||||||
submitted info fields, are restored together by persistent Undo/Redo
|
submitted info fields, are restored together by persistent Undo/Redo
|
||||||
- `fedFrom` remains free text for external feeds such as HAK, metering,
|
- `fedFrom` remains free text for external feeds such as HAK, metering,
|
||||||
transformer or generator and for supplementary notes
|
transformer or generator and for supplementary notes
|
||||||
|
- The project-command endpoint additionally accepts
|
||||||
|
`distribution-board.create-feeder-circuit` with an empty complete circuit
|
||||||
|
snapshot and an embedded version-2 `distribution-board.update`. Both writes
|
||||||
|
are one transaction, revision and Undo step. The generated circuit has no
|
||||||
|
device row; Redo keeps its UUID and BMK. The history-only inverse
|
||||||
|
`distribution-board.remove-feeder-circuit` restores the previous board values
|
||||||
|
and removes only the unchanged circuit.
|
||||||
- `POST /projects/:projectId/distribution-boards/:distributionBoardId/copy`
|
- `POST /projects/:projectId/distribution-boards/:distributionBoardId/copy`
|
||||||
- body: `{ "name": "UV-02 Kopie", "expectedRevision": 14 }`
|
- body: `{ "name": "UV-02 Kopie", "expectedRevision": 14 }`
|
||||||
- duplicates the complete distribution-board subtree with new owning UUIDs
|
- duplicates the complete distribution-board subtree with new owning UUIDs
|
||||||
|
|
@ -346,7 +353,9 @@ commands. Endpoints, payloads and calculation rules: `docs/estimate-balance.md`.
|
||||||
footer components. Circuit and component protection devices use their
|
footer components. Circuit and component protection devices use their
|
||||||
separate one-to-one DTOs. Calculated row, circuit, section and board totals
|
separate one-to-one DTOs. Calculated row, circuit, section and board totals
|
||||||
remain included. Circuit totals contain the demand of linked downstream
|
remain included. Circuit totals contain the demand of linked downstream
|
||||||
boards. `downstreamBoardLoads` exposes those contributions as read-only rows;
|
boards. `downstreamBoardLoads` exposes those contributions as read-only
|
||||||
|
values; the grid combines exactly one downstream board without device rows
|
||||||
|
into the circuit row and keeps child rows for mixed or multiple loads.
|
||||||
`feedingReference` resolves the current board/circuit labels by id.
|
`feedingReference` resolves the current board/circuit labels by id.
|
||||||
|
|
||||||
Response sketch:
|
Response sketch:
|
||||||
|
|
|
||||||
|
|
@ -477,6 +477,21 @@ Verweise nicht. Der speisende Stromkreis muss zur speisenden Verteilung gehören
|
||||||
Selbstverweise und Zyklen werden abgelehnt. Löschbefehle für referenzierte
|
Selbstverweise und Zyklen werden abgelehnt. Löschbefehle für referenzierte
|
||||||
Verteilungen und Stromkreise, einschließlich Unterbaum- und Undo-Pfaden, werden
|
Verteilungen und Stromkreise, einschließlich Unterbaum- und Undo-Pfaden, werden
|
||||||
vor der Datenbankänderung fachlich gesperrt.
|
vor der Datenbankänderung fachlich gesperrt.
|
||||||
|
Im Bearbeiten-Dialog kann nach Auswahl der speisenden Verteilung direkt ein
|
||||||
|
neuer Einspeiseabgang geplant werden. Die Oberfläche schlägt die dreiphasige
|
||||||
|
Gruppe und das nächste BMK vor. Der Befehl
|
||||||
|
`distribution-board.create-feeder-circuit` legt den leeren Stromkreis an und
|
||||||
|
wendet die vollständige Verteilungsänderung in derselben Transaktion und
|
||||||
|
Revision an; es entsteht keine Gerätezeile. Schutz und Leitung bleiben bewusst
|
||||||
|
offen, weil sie aus Last und Verlegebedingungen geplant werden müssen. Undo
|
||||||
|
stellt zuerst die vorherigen Verteilungswerte wieder her und entfernt danach
|
||||||
|
nur den unveränderten erzeugten Stromkreis; Redo verwendet UUID und BMK erneut.
|
||||||
|
Bei genau einer gespeisten Unterverteilung ohne Gerätezeilen projiziert das
|
||||||
|
Grid nur eine kompakte Stromkreiszeile mit dem über die ID aufgelösten
|
||||||
|
Verteilernamen. Erst mehrere Unterverteilungen oder zusätzliche Geräte erzeugen
|
||||||
|
Sammel- und Unterzeilen. Anzeigename und Bemerkung eines leeren
|
||||||
|
Reservestromkreises gehören zum Stromkreis und erzeugen beim Bearbeiten keine
|
||||||
|
Gerätezeile.
|
||||||
Die projektweite Circuit-Tree-Projektion berechnet rekursiv die Lasten aller
|
Die projektweite Circuit-Tree-Projektion berechnet rekursiv die Lasten aller
|
||||||
Verteilungen. Die Leistung einer Unterverteilung nach ihrem eigenen
|
Verteilungen. Die Leistung einer Unterverteilung nach ihrem eigenen
|
||||||
Verteiler-GZF wird als virtuelle, schreibgeschützte Zeile genau dem gewählten
|
Verteiler-GZF wird als virtuelle, schreibgeschützte Zeile genau dem gewählten
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,9 @@ automatisch bei späteren Änderungen in einem anderen Tab.
|
||||||
3. **Verteilerpläne (quer, je Verteiler)** – Titelleiste mit
|
3. **Verteilerpläne (quer, je Verteiler)** – Titelleiste mit
|
||||||
Verteilernummer, Bezeichnung, Örtlichkeit, Netzart, „Gespeist von“ und
|
Verteilernummer, Bezeichnung, Örtlichkeit, Netzart, „Gespeist von“ und
|
||||||
P<sub>gl</sub>; darunter Kopfkomponenten, Gruppen, Stromkreise
|
P<sub>gl</sub>; darunter Kopfkomponenten, Gruppen, Stromkreise
|
||||||
(mehrzeilige mit Sammelzeile, eingerückten Gerätezeilen und
|
(reine 1:1-Einspeiseabgänge kompakt in einer Zeile; sonst mehrzeilig mit
|
||||||
schreibgeschützten Unterverteilungszeilen),
|
Sammelzeile, eingerückten Gerätezeilen und schreibgeschützten
|
||||||
|
Unterverteilungszeilen),
|
||||||
Gruppensummen und Verteilersumme. Fehlende Kabelangaben sind als „offen“
|
Gruppensummen und Verteilersumme. Fehlende Kabelangaben sind als „offen“
|
||||||
markiert. Die Titelleiste steht im Tabellenkopf und wiederholt sich beim
|
markiert. Die Titelleiste steht im Tabellenkopf und wiederholt sich beim
|
||||||
Drucken auf Folgeseiten.
|
Drucken auf Folgeseiten.
|
||||||
|
|
|
||||||
|
|
@ -1537,6 +1537,10 @@ a.kpi:hover {
|
||||||
background: var(--panel-bg-subtle);
|
background: var(--panel-bg-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tree-grid .feeder-circuit-row td:nth-child(2) {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.tree-grid .device-row td:first-child {
|
.tree-grid .device-row td:first-child {
|
||||||
color: var(--text-faint);
|
color: var(--text-faint);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1766,7 +1766,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
||||||
const currentDisplay =
|
const currentDisplay =
|
||||||
mode === "replaceWithTypedChar" && cell.cellKey !== "phaseType"
|
mode === "replaceWithTypedChar" && cell.cellKey !== "phaseType"
|
||||||
? typedChar ?? ""
|
? typedChar ?? ""
|
||||||
: String(visibleCell.value ?? "");
|
: String(visibleCell.editValue ?? visibleCell.value ?? "");
|
||||||
focusTokenRef.current += 1;
|
focusTokenRef.current += 1;
|
||||||
setEditingCell({
|
setEditingCell({
|
||||||
...cell,
|
...cell,
|
||||||
|
|
@ -4077,7 +4077,9 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
||||||
key={row.rowKey}
|
key={row.rowKey}
|
||||||
className={`${
|
className={`${
|
||||||
row.rowType === "circuitSummary"
|
row.rowType === "circuitSummary"
|
||||||
? "summary-row"
|
? row.downstreamBoardLoad
|
||||||
|
? "feeder-circuit-row"
|
||||||
|
: "summary-row"
|
||||||
: row.rowType === "deviceRow"
|
: row.rowType === "deviceRow"
|
||||||
? "device-row"
|
? "device-row"
|
||||||
: row.rowType === "downstreamBoardLoad"
|
: row.rowType === "downstreamBoardLoad"
|
||||||
|
|
@ -4708,11 +4710,19 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={isSaving}
|
disabled={
|
||||||
|
isSaving ||
|
||||||
|
(row.circuit.downstreamBoardLoads?.length ?? 0) > 0
|
||||||
|
}
|
||||||
icon={Trash2}
|
icon={Trash2}
|
||||||
label="Stromkreis löschen"
|
label="Stromkreis löschen"
|
||||||
onClick={() => void handleDeleteCircuit(row.circuit!.id)}
|
onClick={() => void handleDeleteCircuit(row.circuit!.id)}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
|
title={
|
||||||
|
(row.circuit.downstreamBoardLoads?.length ?? 0) > 0
|
||||||
|
? "Speist eine Unterverteilung – zuerst deren Einspeisung ändern"
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
variant="danger"
|
variant="danger"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -431,6 +431,25 @@ function CircuitRows({ circuit }: { circuit: CircuitTreeCircuitDto }) {
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (rows.length === 0 && downstreamBoards.length === 1) {
|
||||||
|
const boardLabel =
|
||||||
|
downstreamBoards[0].boardNumber ?? downstreamBoards[0].name;
|
||||||
|
return (
|
||||||
|
<tr className="pd-circuit">
|
||||||
|
<td className="pd-bmk">{circuit.equipmentIdentifier}</td>
|
||||||
|
<td>
|
||||||
|
{boardLabel}
|
||||||
|
{circuit.displayName ? (
|
||||||
|
<span className="pd-sub"> · {circuit.displayName}</span>
|
||||||
|
) : null}
|
||||||
|
</td>
|
||||||
|
<td>–</td>
|
||||||
|
<td /><td /><td />
|
||||||
|
<td className="pd-r"><strong>{formatKilowatt(circuit.circuitTotalPower)}</strong></td>
|
||||||
|
{circuitCells}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
if (rows.length === 1 && downstreamBoards.length === 0) {
|
if (rows.length === 1 && downstreamBoards.length === 0) {
|
||||||
const row = rows[0];
|
const row = rows[0];
|
||||||
const title = circuit.displayName ?? row.displayName;
|
const title = circuit.displayName ?? row.displayName;
|
||||||
|
|
|
||||||
|
|
@ -617,7 +617,11 @@ export function getCellKind(rowType: RowType, key: CellKey): CellKind {
|
||||||
if (rowType === "deviceRow") return deviceFieldKeys.has(key) ? "deviceField" : "readonly";
|
if (rowType === "deviceRow") return deviceFieldKeys.has(key) ? "deviceField" : "readonly";
|
||||||
if (rowType === "downstreamBoardLoad") return "readonly";
|
if (rowType === "downstreamBoardLoad") return "readonly";
|
||||||
if (rowType === "circuitSummary") return circuitFieldKeys.has(key) ? "circuitField" : "readonly";
|
if (rowType === "circuitSummary") return circuitFieldKeys.has(key) ? "circuitField" : "readonly";
|
||||||
if (rowType === "reserveCircuit" || rowType === "circuitCompact") {
|
if (rowType === "reserveCircuit") {
|
||||||
|
if (circuitFieldKeys.has(key)) return "circuitField";
|
||||||
|
if (deviceFieldKeys.has(key)) return "deviceField";
|
||||||
|
}
|
||||||
|
if (rowType === "circuitCompact") {
|
||||||
if (deviceFieldKeys.has(key)) return "deviceField";
|
if (deviceFieldKeys.has(key)) return "deviceField";
|
||||||
if (circuitFieldKeys.has(key)) return "circuitField";
|
if (circuitFieldKeys.has(key)) return "circuitField";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ export interface VisibleGridCell {
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
kind: CellKind;
|
kind: CellKind;
|
||||||
value: GridValue;
|
value: GridValue;
|
||||||
|
/** Separate persisted value when the displayed value is derived. */
|
||||||
|
editValue?: GridValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VisibleGridRow {
|
export interface VisibleGridRow {
|
||||||
|
|
@ -144,6 +146,7 @@ function makeVisibleGridRow(
|
||||||
const kind = getCellKind(rowType, column.key);
|
const kind = getCellKind(rowType, column.key);
|
||||||
const editable = kind === "circuitField" || kind === "deviceField";
|
const editable = kind === "circuitField" || kind === "deviceField";
|
||||||
let value: GridValue;
|
let value: GridValue;
|
||||||
|
let editValue: GridValue | undefined;
|
||||||
|
|
||||||
if (rowType === "downstreamBoardLoad" && downstreamBoardLoad) {
|
if (rowType === "downstreamBoardLoad" && downstreamBoardLoad) {
|
||||||
value = column.key === "displayName"
|
value = column.key === "displayName"
|
||||||
|
|
@ -155,6 +158,35 @@ function makeVisibleGridRow(
|
||||||
: column.key === "remark"
|
: column.key === "remark"
|
||||||
? "Automatisch aus der verknüpften Verteilung"
|
? "Automatisch aus der verknüpften Verteilung"
|
||||||
: undefined;
|
: undefined;
|
||||||
|
} else if (
|
||||||
|
rowType === "circuitSummary" &&
|
||||||
|
circuit &&
|
||||||
|
downstreamBoardLoad &&
|
||||||
|
circuit.deviceRows.length === 0
|
||||||
|
) {
|
||||||
|
if (column.key === "displayName") {
|
||||||
|
const boardLabel =
|
||||||
|
downstreamBoardLoad.boardNumber ?? downstreamBoardLoad.name;
|
||||||
|
value = circuit.displayName
|
||||||
|
? `${boardLabel} · ${circuit.displayName}`
|
||||||
|
: boardLabel;
|
||||||
|
editValue = circuit.displayName ?? "";
|
||||||
|
} else if (column.key === "cosPhi") {
|
||||||
|
value = circuit.circuitCosPhi;
|
||||||
|
} else if (
|
||||||
|
kind === "computed" &&
|
||||||
|
circuitOnlyColumns.has(column.key)
|
||||||
|
) {
|
||||||
|
value = getCircuitValue(circuit, column.key);
|
||||||
|
} else if (kind === "circuitField") {
|
||||||
|
value = getCircuitValue(circuit, column.key);
|
||||||
|
} else if (column.key === "rowTotalPower") {
|
||||||
|
value = circuit.circuitTotalPower;
|
||||||
|
} else if (column.key === "circuitTotalPower") {
|
||||||
|
value = circuit.circuitTotalPower;
|
||||||
|
} else if (column.key === "voltage") {
|
||||||
|
value = circuit.voltage;
|
||||||
|
}
|
||||||
} else if (rowType === "placeholder") {
|
} else if (rowType === "placeholder") {
|
||||||
value = column.key === "equipmentIdentifier" ? "-frei-" : undefined;
|
value = column.key === "equipmentIdentifier" ? "-frei-" : undefined;
|
||||||
} else if (kind === "deviceField" && device) {
|
} else if (kind === "deviceField" && device) {
|
||||||
|
|
@ -178,7 +210,7 @@ function makeVisibleGridRow(
|
||||||
value = circuit.voltage;
|
value = circuit.voltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { cellKey: column.key, editable, kind, value };
|
return { cellKey: column.key, editable, kind, value, editValue };
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -247,6 +279,19 @@ export function buildVisibleGridRowsWithStructure(
|
||||||
const downstreamLoads = circuit.downstreamBoardLoads ?? [];
|
const downstreamLoads = circuit.downstreamBoardLoads ?? [];
|
||||||
if (circuit.deviceRows.length === 0 && downstreamLoads.length === 0) {
|
if (circuit.deviceRows.length === 0 && downstreamLoads.length === 0) {
|
||||||
rows.push(makeVisibleGridRow("reserveCircuit", section.id, circuit));
|
rows.push(makeVisibleGridRow("reserveCircuit", section.id, circuit));
|
||||||
|
} else if (
|
||||||
|
circuit.deviceRows.length === 0 &&
|
||||||
|
downstreamLoads.length === 1
|
||||||
|
) {
|
||||||
|
rows.push(
|
||||||
|
makeVisibleGridRow(
|
||||||
|
"circuitSummary",
|
||||||
|
section.id,
|
||||||
|
circuit,
|
||||||
|
undefined,
|
||||||
|
downstreamLoads[0]
|
||||||
|
)
|
||||||
|
);
|
||||||
} else if (circuit.deviceRows.length === 1 && downstreamLoads.length === 0) {
|
} else if (circuit.deviceRows.length === 1 && downstreamLoads.length === 0) {
|
||||||
rows.push(makeVisibleGridRow("circuitCompact", section.id, circuit, circuit.deviceRows[0]));
|
rows.push(makeVisibleGridRow("circuitCompact", section.id, circuit, circuit.deviceRows[0]));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,9 @@ describe("circuit grid model", () => {
|
||||||
assert.equal(getCellKind("circuitCompact", "equipmentIdentifier"), "circuitField");
|
assert.equal(getCellKind("circuitCompact", "equipmentIdentifier"), "circuitField");
|
||||||
assert.equal(getCellKind("circuitSummary", "displayName"), "circuitField");
|
assert.equal(getCellKind("circuitSummary", "displayName"), "circuitField");
|
||||||
assert.equal(getCellKind("deviceRow", "displayName"), "deviceField");
|
assert.equal(getCellKind("deviceRow", "displayName"), "deviceField");
|
||||||
assert.equal(getCellKind("reserveCircuit", "remark"), "deviceField");
|
assert.equal(getCellKind("reserveCircuit", "displayName"), "circuitField");
|
||||||
|
assert.equal(getCellKind("reserveCircuit", "remark"), "circuitField");
|
||||||
|
assert.equal(getCellKind("reserveCircuit", "powerPerUnit"), "deviceField");
|
||||||
assert.equal(getCellKind("placeholder", "displayName"), "deviceField");
|
assert.equal(getCellKind("placeholder", "displayName"), "deviceField");
|
||||||
assert.equal(getCellKind("deviceRow", "equipmentIdentifier"), "readonly");
|
assert.equal(getCellKind("deviceRow", "equipmentIdentifier"), "readonly");
|
||||||
assert.equal(getCellKind("circuitSummary", "controlRequirement"), "circuitField");
|
assert.equal(getCellKind("circuitSummary", "controlRequirement"), "circuitField");
|
||||||
|
|
|
||||||
|
|
@ -179,9 +179,10 @@ describe("circuit grid projection", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders linked downstream boards as separate read-only rows", () => {
|
it("renders one linked downstream board as one compact editable circuit row", () => {
|
||||||
const feeder = {
|
const feeder = {
|
||||||
...reserveCircuit,
|
...reserveCircuit,
|
||||||
|
displayName: undefined,
|
||||||
isReserve: false,
|
isReserve: false,
|
||||||
circuitTotalPower: 4,
|
circuitTotalPower: 4,
|
||||||
circuitApparentPower: 5,
|
circuitApparentPower: 5,
|
||||||
|
|
@ -202,19 +203,65 @@ describe("circuit grid projection", () => {
|
||||||
assert.deepEqual(rows.map((row) => row.rowType), [
|
assert.deepEqual(rows.map((row) => row.rowType), [
|
||||||
"section",
|
"section",
|
||||||
"circuitSummary",
|
"circuitSummary",
|
||||||
"downstreamBoardLoad",
|
|
||||||
"placeholder",
|
"placeholder",
|
||||||
]);
|
]);
|
||||||
const loadRow = rows[2];
|
const loadRow = rows[1];
|
||||||
assert.equal(
|
assert.equal(
|
||||||
loadRow.cells.find((cell) => cell.cellKey === "displayName")?.value,
|
loadRow.cells.find((cell) => cell.cellKey === "displayName")?.value,
|
||||||
"Unterverteilung UV-02"
|
"UV-02"
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
loadRow.cells.find((cell) => cell.cellKey === "displayName")?.editValue,
|
||||||
|
""
|
||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
loadRow.cells.find((cell) => cell.cellKey === "rowTotalPower")?.value,
|
loadRow.cells.find((cell) => cell.cellKey === "rowTotalPower")?.value,
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
assert.equal(loadRow.cells.every((cell) => !cell.editable), true);
|
assert.equal(
|
||||||
|
loadRow.cells.find((cell) => cell.cellKey === "displayName")?.kind,
|
||||||
|
"circuitField"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps separate read-only rows for several linked downstream boards", () => {
|
||||||
|
const feeder = {
|
||||||
|
...reserveCircuit,
|
||||||
|
isReserve: false,
|
||||||
|
circuitTotalPower: 6,
|
||||||
|
circuitApparentPower: 7,
|
||||||
|
circuitCosPhi: 6 / 7,
|
||||||
|
downstreamBoardLoads: [
|
||||||
|
{
|
||||||
|
distributionBoardId: "board-a",
|
||||||
|
name: "Unterverteilung A",
|
||||||
|
boardNumber: "UV-A",
|
||||||
|
activePowerKw: 4,
|
||||||
|
apparentPowerKva: 5,
|
||||||
|
cosPhi: 0.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
distributionBoardId: "board-b",
|
||||||
|
name: "Unterverteilung B",
|
||||||
|
boardNumber: "UV-B",
|
||||||
|
activePowerKw: 2,
|
||||||
|
apparentPowerKva: 2,
|
||||||
|
cosPhi: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const rows = buildVisibleGridRowsWithStructure(
|
||||||
|
[{ ...sections[0], circuits: [feeder] }],
|
||||||
|
{ headerComponents: [], footerComponents: [] }
|
||||||
|
);
|
||||||
|
assert.deepEqual(rows.map((row) => row.rowType), [
|
||||||
|
"section",
|
||||||
|
"circuitSummary",
|
||||||
|
"downstreamBoardLoad",
|
||||||
|
"downstreamBoardLoad",
|
||||||
|
"placeholder",
|
||||||
|
]);
|
||||||
|
assert.equal(rows[2].cells.every((cell) => !cell.editable), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shows circuit protection once on each visible circuit row", () => {
|
it("shows circuit protection once on each visible circuit row", () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue