Support decimal commas and cell units

This commit is contained in:
2026-07-31 14:33:47 +02:00
parent 734a2bcfc4
commit 5fb81bab04
4 changed files with 36 additions and 10 deletions
@@ -27,6 +27,7 @@ import {
buildDeviceRowEditPatch,
defaultVisibleColumnKeys,
deviceFieldKeys,
formatCellValue,
formatPhaseTypeLabel,
formatValue,
getCircuitSectionLabel,
@@ -4392,7 +4393,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
}}
/>
) : (
formatValue(cell.value, column.key)
formatCellValue(cell.value, column.key)
)}
</td>
);
@@ -5,6 +5,7 @@ import { Fragment } from "react";
import { getCircuitTree } from "../utils/api";
import type { CircuitTreeCircuitDto, CircuitTreeResponseDto } from "../types";
import {
formatCellValue,
formatValue,
getCircuitSectionLabel,
} from "../utils/circuit-grid-model";
@@ -112,7 +113,7 @@ function SectionRows(props: { section: CircuitTreeResponseDto["sections"][number
<td>{circuit.displayName?.trim() || "Reserve"}</td>
<td colSpan={11}>-</td>
<td className="text-end">
{formatValue(circuit.circuitTotalPower, "circuitTotalPower")}
{formatCellValue(circuit.circuitTotalPower, "circuitTotalPower")}
</td>
<td>{circuit.protectionDevice?.type ?? "-"}</td>
<td className="text-end">
@@ -140,13 +141,13 @@ function SectionRows(props: { section: CircuitTreeResponseDto["sections"][number
<td>{row.level ?? "-"}</td>
<td>{row.roomNumberSnapshot ?? "-"}</td>
<td>{row.roomNameSnapshot ?? "-"}</td>
<td className="text-end">{formatValue(row.quantity, "quantity")}</td>
<td className="text-end">{formatValue(row.powerPerUnit, "powerPerUnit")}</td>
<td className="text-end">{formatCellValue(row.quantity, "quantity")}</td>
<td className="text-end">{formatCellValue(row.powerPerUnit, "powerPerUnit")}</td>
<td className="text-end">
{formatValue(row.simultaneityFactor, "simultaneityFactor")}
</td>
<td className="text-end">{formatValue(row.cosPhi, "cosPhi")}</td>
<td className="text-end">{formatValue(row.rowTotalPower, "rowTotalPower")}</td>
<td className="text-end">{formatCellValue(row.rowTotalPower, "rowTotalPower")}</td>
<td>{circuit.protectionDevice?.type ?? "-"}</td>
<td className="text-end">
{formatValue(circuit.protectionDevice?.ratedCurrentA, "protectionRatedCurrent")}
@@ -167,7 +168,7 @@ function SectionRows(props: { section: CircuitTreeResponseDto["sections"][number
<td>{renderCircuitSummaryLabel(circuit)}</td>
<td colSpan={11}>-</td>
<td className="text-end">
{formatValue(circuit.circuitTotalPower, "circuitTotalPower")}
{formatCellValue(circuit.circuitTotalPower, "circuitTotalPower")}
</td>
<td>{circuit.protectionDevice?.type ?? "-"}</td>
<td className="text-end">
@@ -190,13 +191,13 @@ function SectionRows(props: { section: CircuitTreeResponseDto["sections"][number
<td>{row.level ?? "-"}</td>
<td>{row.roomNumberSnapshot ?? "-"}</td>
<td>{row.roomNameSnapshot ?? "-"}</td>
<td className="text-end">{formatValue(row.quantity, "quantity")}</td>
<td className="text-end">{formatValue(row.powerPerUnit, "powerPerUnit")}</td>
<td className="text-end">{formatCellValue(row.quantity, "quantity")}</td>
<td className="text-end">{formatCellValue(row.powerPerUnit, "powerPerUnit")}</td>
<td className="text-end">
{formatValue(row.simultaneityFactor, "simultaneityFactor")}
</td>
<td className="text-end">{formatValue(row.cosPhi, "cosPhi")}</td>
<td className="text-end">{formatValue(row.rowTotalPower, "rowTotalPower")}</td>
<td className="text-end">{formatCellValue(row.rowTotalPower, "rowTotalPower")}</td>
<td>-</td>
<td className="text-end">-</td>
<td>-</td>
+19 -1
View File
@@ -351,6 +351,24 @@ export function formatValue(value: GridValue, key?: CellKey): string {
return String(value);
}
export function formatCellValue(value: GridValue, key: CellKey): string {
const formatted = formatValue(value, key);
if (formatted === "-" || typeof value !== "number") {
return formatted;
}
if (key === "quantity") {
return `${formatted} St.`;
}
if (
key === "powerPerUnit" ||
key === "rowTotalPower" ||
key === "circuitTotalPower"
) {
return `${formatted} kW`;
}
return formatted;
}
export function formatPhaseTypeLabel(value: string): string {
if (value === "single_phase") {
return "1-phasig";
@@ -378,7 +396,7 @@ export function parseNumeric(cellKey: CellKey, draft: string): number | undefine
if (trimmed === "") {
return undefined;
}
const parsed = Number(trimmed);
const parsed = Number(trimmed.replace(",", "."));
if (Number.isNaN(parsed)) {
throw new Error(`Ungültiger Zahlenwert in ${cellKey}`);
}
+6
View File
@@ -5,6 +5,7 @@ import {
buildCircuitEditPatch,
buildDeviceRowEditPatch,
formatValue,
formatCellValue,
getCircuitSectionLabel,
getProjectColumnLayoutStorageKey,
isGridEditorControlTarget,
@@ -173,6 +174,10 @@ describe("circuit grid model", () => {
assert.equal(formatValue(16, "protectionRatedCurrent"), "16");
assert.equal(formatValue("single_phase", "phaseType"), "1-phasig");
assert.equal(formatValue("three_phase", "phaseType"), "3-phasig");
assert.equal(formatCellValue(2, "quantity"), "2 St.");
assert.equal(formatCellValue(0.123456, "powerPerUnit"), "0,123 kW");
assert.equal(formatCellValue(1.25, "rowTotalPower"), "1,25 kW");
assert.equal(formatCellValue(undefined, "circuitTotalPower"), "-");
});
it("uses circuit display values for block sorting and falls back to the first device", () => {
@@ -183,6 +188,7 @@ describe("circuit grid model", () => {
it("parses numeric drafts and rejects invalid values", () => {
assert.equal(parseNumeric("quantity", " 2.5 "), 2.5);
assert.equal(parseNumeric("powerPerUnit", " 1,25 "), 1.25);
assert.equal(parseNumeric("quantity", ""), undefined);
assert.throws(() => parseNumeric("quantity", "two"), /Ungültiger Zahlenwert/);
});