From 1fea873ddf278cfce17fb5054ad09b2e7abdff01 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Wed, 25 Jun 2025 10:32:04 -0500 Subject: [PATCH] web: ThermalUnits: Build table data --- .../components/CaseBuilder/ThermalUnits.tsx | 4 +- .../components/Common/Forms/DataTable.test.ts | 52 +++++++++++++++++++ web/src/components/Common/Forms/DataTable.tsx | 15 +++++- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/web/src/components/CaseBuilder/ThermalUnits.tsx b/web/src/components/CaseBuilder/ThermalUnits.tsx index 90f5b76..c6e9344 100644 --- a/web/src/components/CaseBuilder/ThermalUnits.tsx +++ b/web/src/components/CaseBuilder/ThermalUnits.tsx @@ -62,12 +62,12 @@ export const ThermalUnitsColumnSpec: ColumnSpec[] = [ width: 60, }, { - title: "Min uptime (h)", + title: "Minimum uptime (h)", type: "number", width: 80, }, { - title: "Min downtime (h)", + title: "Minimum downtime (h)", type: "number", width: 100, }, diff --git a/web/src/components/Common/Forms/DataTable.test.ts b/web/src/components/Common/Forms/DataTable.test.ts index 404e533..1c29976 100644 --- a/web/src/components/Common/Forms/DataTable.test.ts +++ b/web/src/components/Common/Forms/DataTable.test.ts @@ -10,11 +10,13 @@ import { floatFormatter, generateCsv, generateTableColumns, + generateTableData, parseCsv, } from "./DataTable"; import { TEST_DATA_1 } from "../../../core/fixtures.test"; import { ProfiledUnitsColumnSpec } from "../../CaseBuilder/ProfiledUnits"; import { ThermalUnitsColumnSpec } from "../../CaseBuilder/ThermalUnits"; +import { getThermalGenerators } from "../../../core/fixtures"; test("generateTableColumns (ProfiledUnits)", () => { const columns = generateTableColumns(TEST_DATA_1, ProfiledUnitsColumnSpec); @@ -72,6 +74,56 @@ test("generateTableColumns (ThermalUnits)", () => { }); }); +test("generateTableData (ThermalUnits)", () => { + const data = generateTableData( + getThermalGenerators(TEST_DATA_1), + ThermalUnitsColumnSpec, + TEST_DATA_1, + ); + assert.deepEqual(data[0], { + Name: "gen1", + Bus: "b1", + "Initial power (MW)": 115, + "Initial status (h)": 12, + "Minimum downtime (h)": 4, + "Minimum uptime (h)": 4, + "Ramp down limit (MW)": 232.68, + "Ramp up limit (MW)": 232.68, + "Shutdown limit (MW)": 232.68, + "Startup limit (MW)": 232.68, + "Production cost curve ($) 1": 1400, + "Production cost curve ($) 2": 1600, + "Production cost curve ($) 3": 2200, + "Production cost curve ($) 4": 2400, + "Production cost curve ($) 5": "", + "Production cost curve ($) 6": "", + "Production cost curve ($) 7": "", + "Production cost curve ($) 8": "", + "Production cost curve ($) 9": "", + "Production cost curve ($) 10": "", + "Production cost curve (MW) 1": 100, + "Production cost curve (MW) 2": 110, + "Production cost curve (MW) 3": 130, + "Production cost curve (MW) 4": 135, + "Production cost curve (MW) 5": "", + "Production cost curve (MW) 6": "", + "Production cost curve (MW) 7": "", + "Production cost curve (MW) 8": "", + "Production cost curve (MW) 9": "", + "Production cost curve (MW) 10": "", + "Startup costs ($) 1": 300, + "Startup costs ($) 2": 400, + "Startup costs ($) 3": "", + "Startup costs ($) 4": "", + "Startup costs ($) 5": "", + "Startup delays (h) 1": 1, + "Startup delays (h) 2": 4, + "Startup delays (h) 3": "", + "Startup delays (h) 4": "", + "Startup delays (h) 5": "", + }); +}); + test("generate CSV", () => { const [data, columns] = generateBusesData(TEST_DATA_1); const actualCsv = generateCsv(data, columns); diff --git a/web/src/components/Common/Forms/DataTable.tsx b/web/src/components/Common/Forms/DataTable.tsx index 25e392c..56d5fb7 100644 --- a/web/src/components/Common/Forms/DataTable.tsx +++ b/web/src/components/Common/Forms/DataTable.tsx @@ -107,6 +107,7 @@ export const generateTableData = ( switch (spec.type) { case "string": case "number": + case "boolean": case "busRef": entry[spec.title] = entryData[spec.title]; break; @@ -115,8 +116,13 @@ export const generateTableData = ( entry[`${spec.title} ${timeslots[i]}`] = entryData[spec.title][i]; } break; + case "number[N]": + for (let i = 0; i < spec.length!; i++) { + entry[`${spec.title} ${i + 1}`] = entryData[spec.title][i] || ""; + } + break; default: - console.error(`Unknown type: ${spec.type}`); + throw Error(`Unknown type: ${spec.type}`); } } data.push(entry); @@ -243,7 +249,12 @@ export const parseCsv = ( }; export const floatFormatter = (cell: CellComponent) => { - return parseFloat(cell.getValue()).toFixed(1); + const v = cell.getValue(); + if (v === "") { + return "—"; + } else { + return parseFloat(cell.getValue()).toFixed(1); + } }; export const generateTimeslots = (scenario: UnitCommitmentScenario) => {