From ca4502d28342e89af41f710c9da6829332951110 Mon Sep 17 00:00:00 2001 From: Samir Kamal <1954121+skamril@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:20:50 +0100 Subject: [PATCH] fix ui --- .../business/timeseries_config_management.py | 6 +- .../test_timeseries_config_manager.py | 6 +- .../TimeSeriesManagement/Fields.tsx | 55 ++++++++++--------- .../TimeSeriesManagement/index.tsx | 18 ++---- .../TimeSeriesManagement/utils.ts | 30 ++++++++++ .../api/studies/timeseries/constants.ts | 17 ++++++ .../services/api/studies/timeseries/index.ts | 9 +-- .../services/api/studies/timeseries/types.ts | 29 +++++----- 8 files changed, 104 insertions(+), 66 deletions(-) create mode 100644 webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/utils.ts create mode 100644 webapp/src/services/api/studies/timeseries/constants.ts diff --git a/antarest/study/business/timeseries_config_management.py b/antarest/study/business/timeseries_config_management.py index 9af99968fb..9d0ed1526d 100644 --- a/antarest/study/business/timeseries_config_management.py +++ b/antarest/study/business/timeseries_config_management.py @@ -18,13 +18,13 @@ from antarest.study.storage.variantstudy.model.command.update_config import UpdateConfig -class TSConfigFields(AntaresBaseModel, extra="forbid", validate_assignment=True, populate_by_name=True): +class TSConfig(AntaresBaseModel, extra="forbid", validate_assignment=True, populate_by_name=True): number: int @all_optional_model class TSConfigDTO(AntaresBaseModel, extra="forbid", validate_assignment=True, populate_by_name=True): - thermal: TSConfigFields + thermal: TSConfig class TimeSeriesConfigManager: @@ -40,7 +40,7 @@ def get_values(self, study: Study) -> TSConfigDTO: url.extend(["general", "nbtimeseriesthermal"]) nb_ts_gen_thermal = file_study.tree.get(url) - args = {"thermal": TSConfigFields(number=nb_ts_gen_thermal)} + args = {"thermal": TSConfig(number=nb_ts_gen_thermal)} return TSConfigDTO.model_validate(args) def set_values(self, study: Study, field_values: TSConfigDTO) -> None: diff --git a/tests/storage/business/test_timeseries_config_manager.py b/tests/storage/business/test_timeseries_config_manager.py index 790ea3b0e5..b6b7511a04 100644 --- a/tests/storage/business/test_timeseries_config_manager.py +++ b/tests/storage/business/test_timeseries_config_manager.py @@ -18,7 +18,7 @@ import pytest -from antarest.study.business.timeseries_config_management import TimeSeriesConfigManager, TSConfigDTO, TSConfigFields +from antarest.study.business.timeseries_config_management import TimeSeriesConfigManager, TSConfigDTO, TSConfig from antarest.study.model import RawStudy from antarest.study.storage.rawstudy.model.filesystem.config.files import build from antarest.study.storage.rawstudy.model.filesystem.factory import FileStudy @@ -53,9 +53,9 @@ def test_nominal_case( study = RawStudy(id="test", path=str(file_study_820.config.path)) # Asserts the get method returns the right value - assert config_manager.get_values(study) == TSConfigDTO(thermal=TSConfigFields(number=1)) + assert config_manager.get_values(study) == TSConfigDTO(thermal=TSConfig(number=1)) # Modifies the value and asserts the get takes the modification into account - new_value = TSConfigDTO(thermal=TSConfigFields(number=2)) + new_value = TSConfigDTO(thermal=TSConfig(number=2)) config_manager.set_values(study, new_value) assert config_manager.get_values(study) == new_value diff --git a/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/Fields.tsx b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/Fields.tsx index 7b8bedd6df..f8325eb314 100644 --- a/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/Fields.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/Fields.tsx @@ -16,16 +16,17 @@ import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from import capitalize from "lodash/capitalize"; import NumberFE from "../../../../../common/fieldEditors/NumberFE"; import { useFormContextPlus } from "../../../../../common/Form"; -import type { TSConfigDTO, TSType } from "@/services/api/studies/timeseries/types.ts"; import BooleanFE from "../../../../../common/fieldEditors/BooleanFE"; import { useTranslation } from "react-i18next"; import { validateNumber } from "@/utils/validation/number"; +import type { TSConfigValues } from "./utils"; +import { TSType } from "@/services/api/studies/timeseries/constants"; const borderStyle = "1px solid rgba(255, 255, 255, 0.12)"; function Fields() { - const { control, watch } = useFormContextPlus(); - const isReadyMade = watch("thermal.stochasticTsStatus") === false; + const { control, watch } = useFormContextPlus(); + const formValues = watch(); const { t } = useTranslation(); //////////////////////////////////////////////////////////////// @@ -59,29 +60,31 @@ function Fields() { }, }} > - - {capitalize(TSType.Thermal)} - - - - - - - + {Object.values(TSType).map((type) => ( + + {capitalize(type)} + + + + + + + + ))} diff --git a/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/index.tsx b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/index.tsx index 5dc108cb9e..6689ee49ef 100644 --- a/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/index.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/index.tsx @@ -21,22 +21,14 @@ import { useTranslation } from "react-i18next"; import usePromiseHandler from "../../../../../../hooks/usePromiseHandler"; import BuildIcon from "@mui/icons-material/Build"; import { useRef, useState } from "react"; -import {setTimeSeriesConfig, generateTimeSeries} from "@/services/api/studies/timeseries"; -import type {TSConfigDTO} from "@/services/api/studies/timeseries/types.ts"; -import {DeepPartial} from "react-hook-form"; - -export const DEFAULT_VALUES: DeepPartial = { - thermal: { - number: 1, - }, -}; - +import { setTimeSeriesConfig, generateTimeSeries } from "@/services/api/studies/timeseries"; +import { DEFAULT_VALUES, toConfigDTO, type TSConfigValues } from "./utils"; function TimeSeriesManagement() { const { study } = useOutletContext<{ study: StudyMetadata }>(); const { t } = useTranslation(); const [launchTaskInProgress, setLaunchTaskInProgress] = useState(false); - const apiRef = useRef>(null); + const apiRef = useRef>(null); const handleGenerateTs = usePromiseHandler({ fn: generateTimeSeries, @@ -48,8 +40,8 @@ function TimeSeriesManagement() { // Event Handlers //////////////////////////////////////////////////////////////// - const handleSubmit = (data: SubmitHandlerPlus) => { - return setTimeSeriesConfig({studyId: study.id, values: data.values}); + const handleSubmit = (data: SubmitHandlerPlus) => { + return setTimeSeriesConfig({ studyId: study.id, values: toConfigDTO(data.values) }); }; const handleSubmitSuccessful = async () => { diff --git a/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/utils.ts b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/utils.ts new file mode 100644 index 0000000000..ddb37ea6f5 --- /dev/null +++ b/webapp/src/components/App/Singlestudy/explore/Configuration/TimeSeriesManagement/utils.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2025, RTE (https://www.rte-france.com) + * + * See AUTHORS.txt + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of the Antares project. + */ + +import { TSType } from "@/services/api/studies/timeseries/constants"; +import type { TSConfig, TSConfigDTO, TTSType } from "@/services/api/studies/timeseries/types"; + +export type TSConfigValues = Record; + +export const DEFAULT_VALUES = Object.values(TSType).reduce((acc, type) => { + acc[type] = { number: 1, stochasticTsStatus: false }; + return acc; +}, {} as TSConfigValues); + +export function toConfigDTO(data: TSConfigValues) { + return Object.entries(data).reduce((acc, [key, { stochasticTsStatus, ...config }]) => { + acc[key as TTSType] = config; + return acc; + }, {} as TSConfigDTO); +} diff --git a/webapp/src/services/api/studies/timeseries/constants.ts b/webapp/src/services/api/studies/timeseries/constants.ts new file mode 100644 index 0000000000..fffc2224da --- /dev/null +++ b/webapp/src/services/api/studies/timeseries/constants.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2025, RTE (https://www.rte-france.com) + * + * See AUTHORS.txt + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * SPDX-License-Identifier: MPL-2.0 + * + * This file is part of the Antares project. + */ + +export const TSType = { + Thermal: "thermal", +} as const; diff --git a/webapp/src/services/api/studies/timeseries/index.ts b/webapp/src/services/api/studies/timeseries/index.ts index c706162c80..ce17d6c19f 100644 --- a/webapp/src/services/api/studies/timeseries/index.ts +++ b/webapp/src/services/api/studies/timeseries/index.ts @@ -12,9 +12,9 @@ * This file is part of the Antares project. */ -import { StudyMetadata } from "../../../../common/types.ts"; +import type { StudyMetadata } from "../../../../common/types.ts"; import client from "../../client.ts"; -import type {SetTimeSeriesConfigParams} from "@/services/api/studies/timeseries/types.ts"; +import type { SetTimeSeriesConfigParams } from "@/services/api/studies/timeseries/types.ts"; /** * Launches time series generation task for the specified study. @@ -28,9 +28,6 @@ export async function generateTimeSeries(params: { studyId: StudyMetadata["id"] return data; } - -export async function setTimeSeriesConfig( - {studyId, values}: SetTimeSeriesConfigParams -) { +export async function setTimeSeriesConfig({ studyId, values }: SetTimeSeriesConfigParams) { await client.put(`v1/studies/${studyId}/timeseries/config`, values); } diff --git a/webapp/src/services/api/studies/timeseries/types.ts b/webapp/src/services/api/studies/timeseries/types.ts index 9671073e31..6a8c87d24e 100644 --- a/webapp/src/services/api/studies/timeseries/types.ts +++ b/webapp/src/services/api/studies/timeseries/types.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024, RTE (https://www.rte-france.com) + * Copyright (c) 2025, RTE (https://www.rte-france.com) * * See AUTHORS.txt * @@ -11,23 +11,22 @@ * * This file is part of the Antares project. */ -import {StudyMetadata} from "@/common/types.ts"; -import {DeepPartial} from "react-hook-form"; -export enum TSType { - Thermal = "thermal" -} +import type { StudyMetadata } from "@/common/types.ts"; +import type { DeepPartial } from "react-hook-form"; +import type { F, O } from "ts-toolbelt"; +import type { TSType } from "./constants"; + +export type TTSType = O.UnionOf; -interface TSConfigFields { +export interface TSConfig { number: number; } -export interface TSConfigDTO - { - [TSType.Thermal]: TSConfigFields; -} +export type TSConfigDTO = Record; -export interface SetTimeSeriesConfigParams { - studyId: StudyMetadata["id"], - values: DeepPartial, -} \ No newline at end of file +export interface SetTimeSeriesConfigParams { + studyId: StudyMetadata["id"]; + // Extra fields not allowed by the API + values: DeepPartial>; +}