You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
UnitCommitment.jl/web/src/components/CaseBuilder/CaseBuilder.tsx

146 lines
4.2 KiB

/*
* UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
* Copyright (C) 2020-2025, UChicago Argonne, LLC. All rights reserved.
* Released under the modified BSD license. See COPYING.md for more details.
*/
import Header from "./Header";
import Parameters from "./Parameters";
import BusesComponent from "./Buses";
import { BLANK_SCENARIO } from "../../core/Data/fixtures";
import "tabulator-tables/dist/css/tabulator.min.css";
import "../Common/Forms/Tables.css";
import { useState } from "react";
import Footer from "./Footer";
import { offerDownload } from "../Common/io";
import { preprocess } from "../../core/Operations/preprocessing";
import Toast from "../Common/Forms/Toast";
import ProfiledUnitsComponent from "./ProfiledUnits";
import ThermalUnitsComponent from "./ThermalUnits";
import TransmissionLinesComponent from "./TransmissionLines";
import { UnitCommitmentScenario } from "../../core/Data/types";
import StorageComponent from "./StorageUnits";
import PriceSensitiveLoadsComponent from "./Psload";
export interface CaseBuilderSectionProps {
scenario: UnitCommitmentScenario;
onDataChanged: (scenario: UnitCommitmentScenario) => void;
onError: (msg: string) => void;
}
const CaseBuilder = () => {
const [scenario, setScenario] = useState(() => {
const savedScenario = localStorage.getItem("scenario");
if (!savedScenario) return BLANK_SCENARIO;
const [processedScenario, err] = preprocess(JSON.parse(savedScenario));
if (err) {
console.log(err);
return BLANK_SCENARIO;
}
return processedScenario!!;
});
const [undoStack, setUndoStack] = useState<UnitCommitmentScenario[]>([]);
const [toastMessage, setToastMessage] = useState<string>("");
const setAndSaveScenario = (
newScenario: UnitCommitmentScenario,
updateUndoStack = true,
) => {
if (updateUndoStack) {
const newUndoStack = [...undoStack, scenario];
if (newUndoStack.length > 25) {
newUndoStack.splice(0, newUndoStack.length - 25);
}
setUndoStack(newUndoStack);
}
setScenario(newScenario);
localStorage.setItem("scenario", JSON.stringify(newScenario));
};
const onClear = () => {
setAndSaveScenario(BLANK_SCENARIO);
};
const onSave = () => {
offerDownload(
JSON.stringify(scenario, null, 2),
"application/json",
"case.json",
);
};
const onDataChanged = (newScenario: UnitCommitmentScenario) => {
setAndSaveScenario(newScenario);
};
const onLoad = (data: any) => {
const json = JSON.parse(data);
const [scenario, err] = preprocess(json);
if (err) {
setToastMessage(err.message);
return;
}
setAndSaveScenario(scenario!);
setToastMessage("Data loaded successfully");
};
const onUndo = () => {
if (undoStack.length === 0) return;
setUndoStack(undoStack.slice(0, -1));
setAndSaveScenario(undoStack[undoStack.length - 1]!, false);
};
return (
<div>
<Header
onClear={onClear}
onSave={onSave}
onLoad={onLoad}
onUndo={onUndo}
/>
<div className="content">
<Parameters
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<BusesComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<ThermalUnitsComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<ProfiledUnitsComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<StorageComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<PriceSensitiveLoadsComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<TransmissionLinesComponent
scenario={scenario}
onDataChanged={onDataChanged}
onError={setToastMessage}
/>
<Toast message={toastMessage} />
</div>
<Footer />
</div>
);
};
export default CaseBuilder;