diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/index.tsx b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/index.tsx index 971984be02..1e1055aa66 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/index.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/index.tsx @@ -11,6 +11,7 @@ import { RenewableGroup, createRenewableCluster, deleteRenewableClusters, + duplicateRenewableCluster, getRenewableClusters, } from "./utils"; import useAppSelector from "../../../../../../../redux/hooks/useAppSelector"; @@ -113,6 +114,20 @@ function Renewables() { return addCapacity(cluster); }; + const handleDuplicate = async ( + row: RenewableClusterWithCapacity, + newName: string, + ) => { + const cluster = await duplicateRenewableCluster( + study.id, + areaId, + row.id, + newName, + ); + + return { ...row, ...cluster }; + }; + const handleDelete = (rows: RenewableClusterWithCapacity[]) => { const ids = rows.map((row) => row.id); return deleteRenewableClusters(study.id, areaId, ids); @@ -133,6 +148,7 @@ function Renewables() { columns={columns} groups={[...RENEWABLE_GROUPS]} onCreate={handleCreate} + onDuplicate={handleDuplicate} onDelete={handleDelete} onNameClick={handleNameClick} deleteConfirmationMessage={(count) => diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/utils.ts b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/utils.ts index 9ac4a6eb02..e07b113d0a 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/utils.ts +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Renewables/utils.ts @@ -77,9 +77,10 @@ const getClusterUrl = ( async function makeRequest( method: "get" | "post" | "patch" | "delete", url: string, - data?: Partial | { data: Array }, + data?: Partial | { data: Array } | null, + params?: Record, ): Promise { - const res = await client[method](url, data); + const res = await client[method](url, data, params && { params }); return res.data; } @@ -129,6 +130,25 @@ export function createRenewableCluster( ); } +export async function duplicateRenewableCluster( + studyId: StudyMetadata["id"], + areaId: Area["name"], + clusterIdSource: RenewableCluster["id"], + newName: RenewableCluster["name"], +) { + await new Promise((res) => { + setTimeout(() => { + res(1); + }, 5000); + }); + return makeRequest( + "post", + `/v1/studies/${studyId}/areas/${areaId}/renewables/${clusterIdSource}`, + null, + { newName }, + ); +} + export function deleteRenewableClusters( studyId: StudyMetadata["id"], areaId: Area["name"], diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/index.tsx b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/index.tsx index 51acad4243..b11de1aa0d 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/index.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/index.tsx @@ -14,6 +14,7 @@ import { createStorage, STORAGE_GROUPS, StorageGroup, + duplicateStorage, } from "./utils"; import usePromiseWithSnackbarError from "../../../../../../../hooks/usePromiseWithSnackbarError"; import type { TRow } from "../../../../../../common/GroupedDataTable/types"; @@ -161,6 +162,10 @@ function Storages() { return createStorage(study.id, areaId, values); }; + const handleDuplicate = (row: Storage, newName: string) => { + return duplicateStorage(study.id, areaId, row.id, newName); + }; + const handleDelete = (rows: Storage[]) => { const ids = rows.map((row) => row.id); return deleteStorages(study.id, areaId, ids); @@ -181,6 +186,7 @@ function Storages() { columns={columns} groups={[...STORAGE_GROUPS]} onCreate={handleCreate} + onDuplicate={handleDuplicate} onDelete={handleDelete} onNameClick={handleNameClick} deleteConfirmationMessage={(count) => diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/utils.ts b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/utils.ts index 6855ff566c..e26a44f42f 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/utils.ts +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Storages/utils.ts @@ -54,9 +54,10 @@ const getStorageUrl = ( async function makeRequest( method: "get" | "post" | "patch" | "delete", url: string, - data?: Partial | { data: Array }, + data?: Partial | { data: Array } | null, + params?: Record, ): Promise { - const res = await client[method](url, data); + const res = await client[method](url, data, params && { params }); return res.data; } @@ -96,6 +97,25 @@ export function createStorage( return makeRequest("post", getStoragesUrl(studyId, areaId), data); } +export async function duplicateStorage( + studyId: StudyMetadata["id"], + areaId: Area["name"], + clusterIdSource: Storage["id"], + newName: Storage["name"], +) { + await new Promise((res) => { + setTimeout(() => { + res(1); + }, 5000); + }); + return makeRequest( + "post", + `/v1/studies/${studyId}/areas/${areaId}/storages/${clusterIdSource}`, + null, + { newName }, + ); +} + export function deleteStorages( studyId: StudyMetadata["id"], areaId: Area["name"], diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/index.tsx b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/index.tsx index 19e1e0ec5a..f7742c30c9 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/index.tsx +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/index.tsx @@ -12,6 +12,7 @@ import { THERMAL_GROUPS, ThermalCluster, ThermalGroup, + duplicateThermalCluster, } from "./utils"; import useAppSelector from "../../../../../../../redux/hooks/useAppSelector"; import { getCurrentAreaId } from "../../../../../../../redux/selectors"; @@ -127,6 +128,20 @@ function Thermal() { return addCapacity(cluster); }; + const handleDuplicate = async ( + row: ThermalClusterWithCapacity, + newName: string, + ) => { + const cluster = await duplicateThermalCluster( + study.id, + areaId, + row.id, + newName, + ); + + return { ...row, ...cluster }; + }; + const handleDelete = (rows: ThermalClusterWithCapacity[]) => { const ids = rows.map((row) => row.id); return deleteThermalClusters(study.id, areaId, ids); @@ -147,6 +162,7 @@ function Thermal() { columns={columns} groups={[...THERMAL_GROUPS]} onCreate={handleCreate} + onDuplicate={handleDuplicate} onDelete={handleDelete} onNameClick={handleNameClick} deleteConfirmationMessage={(count) => diff --git a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/utils.ts b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/utils.ts index 730ce37db2..81da12768b 100644 --- a/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/utils.ts +++ b/webapp/src/components/App/Singlestudy/explore/Modelization/Areas/Thermal/utils.ts @@ -108,9 +108,10 @@ const getClusterUrl = ( async function makeRequest( method: "get" | "post" | "patch" | "delete", url: string, - data?: Partial | { data: Array }, + data?: Partial | { data: Array } | null, + params?: Record, ): Promise { - const res = await client[method](url, data); + const res = await client[method](url, data, params && { params }); return res.data; } @@ -157,6 +158,25 @@ export function createThermalCluster( ); } +export async function duplicateThermalCluster( + studyId: StudyMetadata["id"], + areaId: Area["name"], + clusterIdSource: ThermalCluster["id"], + newName: ThermalCluster["name"], +) { + await new Promise((res) => { + setTimeout(() => { + res(1); + }, 5000); + }); + return makeRequest( + "post", + `/v1/studies/${studyId}/areas/${areaId}/thermals/${clusterIdSource}`, + null, + { newName }, + ); +} + export function deleteThermalClusters( studyId: StudyMetadata["id"], areaId: Area["name"], diff --git a/webapp/src/components/common/GroupedDataTable/index.tsx b/webapp/src/components/common/GroupedDataTable/index.tsx index da32867271..81940c170a 100644 --- a/webapp/src/components/common/GroupedDataTable/index.tsx +++ b/webapp/src/components/common/GroupedDataTable/index.tsx @@ -40,6 +40,7 @@ export interface GroupedDataTableProps< columns: Array>; groups: TGroups; onCreate?: (values: TRow) => Promise; + onDuplicate?: (row: TData, newName: string) => Promise; onDelete?: (rows: TData[]) => PromiseAny | void; onNameClick?: (row: MRT_Row) => void; isLoading?: boolean; @@ -60,6 +61,7 @@ function GroupedDataTable< columns, groups, onCreate, + onDuplicate, onDelete, onNameClick, isLoading, @@ -220,7 +222,7 @@ function GroupedDataTable< {t("button.add")} )} - {onCreate && ( + {onDuplicate && (