Render protected circuit structure

This commit is contained in:
2026-07-31 07:22:26 +02:00
parent ac21d6eb5d
commit 31589875b5
11 changed files with 254 additions and 29 deletions
@@ -11,6 +11,7 @@ import {
} from "../../domain/services/project-voltage.service";
import {
getInsertionSortOrder,
isGridInsertionRowType,
resolveGridInsertionIntent,
} from "../utils/circuit-grid-insertion";
import {
@@ -53,7 +54,7 @@ import type {
RowType,
} from "../utils/circuit-grid-model";
import {
buildVisibleGridRows,
buildVisibleGridRowsWithStructure,
filterAndSortCircuitSections,
getDistinctFilterValues,
} from "../utils/circuit-grid-projection";
@@ -386,8 +387,11 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
// visibleRows is the single normalized grid used by render + navigation + editability.
// This avoids selected/rendered/editable state drifting apart after filters/sorts/reloads.
const visibleRows = useMemo(() => {
return buildVisibleGridRows(filteredSortedSections);
}, [filteredSortedSections]);
return buildVisibleGridRowsWithStructure(filteredSortedSections, {
headerComponents: data?.headerComponents ?? [],
footerComponents: data?.footerComponents ?? [],
});
}, [data, filteredSortedSections]);
function clearColumnFilter(key: CellKey) {
setColumnFilters((current) => {
@@ -1660,7 +1664,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
const row = selectedCell ? findRow(selectedCell.rowKey) : null;
const cell = row?.cells.find((entry) => entry.cellKey === selectedCell?.cellKey);
const selection =
row && cell && row.rowType !== "section"
row && cell && isGridInsertionRowType(row.rowType)
? {
rowType: row.rowType,
cellKind: cell.kind,
@@ -2351,7 +2355,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
const row = selectedCell ? findRow(selectedCell.rowKey) : null;
const cell = row?.cells.find((entry) => entry.cellKey === selectedCell?.cellKey);
const intent = resolveGridDeleteIntent(
row && cell && row.rowType !== "section"
row && cell && isGridInsertionRowType(row.rowType)
? {
rowType: row.rowType,
cellKind: cell.kind,
@@ -2986,6 +2990,54 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
</thead>
<tbody>
{visibleRows.map((row) => {
if (
row.rowType === "headerComponent" ||
row.rowType === "groupComponent" ||
row.rowType === "footerComponent"
) {
const component = row.component!;
const protection = component.protectionDevice;
const protectionSummary = protection
? [
protection.type,
`${formatValue(
protection.ratedCurrentA,
"protectionRatedCurrent"
)} A`,
protection.fuseUtilizationCategory,
protection.tripCharacteristic,
protection.rcdType
? `Typ ${protection.rcdType}`
: undefined,
protection.ratedResidualCurrentMa !== undefined
? `${formatValue(
protection.ratedResidualCurrentMa,
"protectionRatedCurrent"
)} mA`
: undefined,
]
.filter(Boolean)
.join(" · ")
: null;
return (
<tr
key={row.rowKey}
className={`structure-component-row ${row.rowType}`}
>
<td colSpan={visibleColumns.length + 1}>
<div className="structure-component-content">
<strong>{component.equipmentIdentifier}</strong>
<span>{component.name}</span>
{protectionSummary ? (
<span className="structure-component-protection">
{protectionSummary}
</span>
) : null}
</div>
</td>
</tr>
);
}
if (row.rowType === "section") {
const section = data.sections.find((entry) => entry.id === row.sectionId)!;
return (