Skip to content
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5fbbcdc
change endpoint to get voltage level topology
EtienneLt Oct 6, 2025
715c115
Merge branch 'main' into refactor-voltage-level-topology
EtienneLt Oct 6, 2025
6b0f2a1
remove useless imports
EtienneLt Oct 6, 2025
bab8ef3
fix
EtienneLt Oct 10, 2025
ca4987a
Merge branch 'main' into refactor-voltage-level-topology
EtienneLt Oct 14, 2025
72bb575
reviex with fixes from back
EtienneLt Oct 14, 2025
78668e9
Merge branch 'main' into refactor-voltage-level-topology
ghazwarhili Oct 17, 2025
bc4157b
resolving conflicts
ghazwarhili Oct 21, 2025
3390129
Merge remote-tracking branch 'origin/refactor-voltage-level-topology'…
ghazwarhili Oct 21, 2025
c1cb8a2
Update with new common tabular DTO (#3346)
dbraquart Oct 21, 2025
e59d77a
Bump version to v2.26.0-SNAPSHOT
gridsuite-actions[bot] Oct 21, 2025
618a7e2
Fix spreadsheet global filter (#3336)
Tristan-WorkGH Oct 21, 2025
93fc339
fix control for coupling creation and refactor labels (#3402)
EtienneLt Oct 22, 2025
143852f
add some control on vl and generator creation (#3393)
EtienneLt Oct 22, 2025
427d4f6
fix empty value if value is 0 (#3403)
EtienneLt Oct 22, 2025
3c54616
Support string data in numerical spreadsheet columns (#3401)
dbraquart Oct 22, 2025
f2fe9aa
Refactor diagram card generic (#3369)
sBouzols Oct 23, 2025
32303bc
Fix `useOneBusShortcircuitAnalysisLoader` which must consider `rootNe…
sBouzols Oct 23, 2025
e777daa
Enable row counter spinner when switching of root network (#3408)
Meklo Oct 24, 2025
434ba09
Fix security group compression (#3410)
EstherDarkish Oct 27, 2025
93eeed4
refactor according to map server
EtienneLt Oct 29, 2025
b84d979
Merge branch 'main' into refactor-voltage-level-topology
EtienneLt Oct 31, 2025
895f6c0
fix
EtienneLt Oct 31, 2025
89418e1
review
EtienneLt Oct 31, 2025
880d310
Merge branch 'main' into refactor-voltage-level-topology
EtienneLt Oct 31, 2025
ca10bf4
refacto and typing (#3428)
ghazwarhili Oct 31, 2025
dbed690
Merge branch 'main' into refactor-voltage-level-topology
ghazwarhili Oct 31, 2025
7563855
try to fix sonar
EtienneLt Nov 3, 2025
6da030c
fix sonar
EtienneLt Nov 3, 2025
84b9eba
fix sonar bis
EtienneLt Nov 3, 2025
2a4e0d4
Merge branch 'main' into refactor-voltage-level-topology
EtienneLt Nov 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ const VoltageLevelCreationDialog = ({
voltageLevel.switchKinds?.map((switchKind) => ({
[SWITCH_KIND]: switchKind,
})) || [];

const switchesBetweenSections =
voltageLevel.switchKinds?.map((switchKind) => intl.formatMessage({ id: switchKind })).join(' / ') || '';

Expand Down Expand Up @@ -283,7 +282,7 @@ const VoltageLevelCreationDialog = ({
} else {
setValue(ADD_SUBSTATION_CREATION, false);
}
if (!voltageLevel.isRetrievedBusbarSections && fromCopy) {
if (!voltageLevel.isSymmetrical && fromCopy) {
snackWarning({
messageId: 'BusBarSectionsCopyingNotSupported',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ import {
MoveFeederBayInfos,
MoveVoltageLevelFeederBaysInfos,
} from '../../../../../services/network-modification-types';
import { fetchNetworkElementInfos } from '../../../../../services/study/network';
import { fetchVoltageLevelFeederBaysBusBarSectionsInfos } from '../../../../../services/study/network';
import { EquipmentModificationDialogProps } from '../../../../graph/menus/network-modifications/network-modification-menu.type';
import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES } from '../../../../utils/equipment-types';
import { DeepNullable } from '../../../../utils/ts-utils';
import { FeederBayInfos, FeederBaysFormInfos, FeederBaysInfos } from './move-voltage-level-feeder-bays.type';
import { moveVoltageLevelFeederBays } from '../../../../../services/study/network-modifications';
import { AnyObject, TestFunction } from 'yup';
import { FeederBaysBusBarSectionsInfos } from '../../../../../services/study/network-map.type';

const isActiveRow = (row: FeederBaysFormInfos) => row && !row.isRemoved;
const checkConnectionPositionField: TestFunction<string | undefined, AnyObject> = (currentPosition, context) => {
Expand Down Expand Up @@ -224,10 +224,12 @@ export default function MoveVoltageLevelFeederBaysDialog({
);

const handleVoltageLevelDataFetch = useCallback(
(voltageLevel: any) => {
const busBarSectionInfos = Object.values(voltageLevel?.busBarSectionInfos || {}).flat() as string[];
(feederBaysBusBarSectionsInfo: FeederBaysBusBarSectionsInfos) => {
const busBarSectionInfos = Object.values(
feederBaysBusBarSectionsInfo?.busBarSectionsInfos.busBarSections || {}
).flat() as string[];
const feederBaysInfos: FeederBaysInfos = (
Object.entries(voltageLevel?.feederBaysInfos || {}) as [string, FeederBayInfos[]][]
Object.entries(feederBaysBusBarSectionsInfo?.feederBaysInfos || {}) as [string, FeederBayInfos[]][]
).flatMap(([equipmentId, feederBayInfos]) =>
feederBayInfos.map((feederBay) => ({
equipmentId,
Expand Down Expand Up @@ -255,21 +257,18 @@ export default function MoveVoltageLevelFeederBaysDialog({
);

const onEquipmentIdChange = useCallback(
(equipmentId: string) => {
if (equipmentId) {
(voltageLevelId: string) => {
if (voltageLevelId) {
setDataFetchStatus(FetchStatus.RUNNING);
fetchNetworkElementInfos(
fetchVoltageLevelFeederBaysBusBarSectionsInfos(
studyUuid,
currentNodeUuid,
currentRootNetworkUuid,
EQUIPMENT_TYPES.VOLTAGE_LEVEL,
EQUIPMENT_INFOS_TYPES.FORM.type,
equipmentId,
true
voltageLevelId
)
.then((voltageLevel) => {
if (voltageLevel) {
handleVoltageLevelDataFetch(voltageLevel);
.then((feederBaysBusBarSectionInfo) => {
if (feederBaysBusBarSectionInfo) {
handleVoltageLevelDataFetch(feederBaysBusBarSectionInfo);
}
})
.catch(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ import yup from '../../../../utils/yup-config';
import { FetchStatus } from 'services/utils';
import { EquipmentIdSelector } from 'components/dialogs/equipment-id/equipment-id-selector';
import { CreateVoltageLevelSectionForm } from './create-voltage-level-section-form';
import { BusBarSectionInfos, CreateVoltageLevelSectionDialogSchemaForm } from './voltage-level-section.type';
import { BusBarSections, CreateVoltageLevelSectionDialogSchemaForm } from './voltage-level-section.type';
import { CreateVoltageLevelSectionInfos } from '../../../../../services/network-modification-types';
import { createVoltageLevelSection } from '../../../../../services/study/network-modifications';
import { EQUIPMENT_INFOS_TYPES } from '../../../../utils/equipment-types';
import { fetchNetworkElementInfos } from '../../../../../services/study/network';
import { fetchVoltageLevelBusBarSectionsInfos } from '../../../../../services/study/network';
import { DeepNullable } from '../../../../utils/ts-utils';
import { BusBarSectionsInfos } from '../../../../../services/study/network-map.type';

const getBusBarIndexValue = ({ busbarIndex, allBusbars }: { busbarIndex: string | null; allBusbars: boolean }) => {
if (!busbarIndex) {
Expand Down Expand Up @@ -131,7 +131,7 @@ export default function CreateVoltageLevelSectionDialog({
const [isExtensionNotFoundOrNotSupportedTopology, setIsExtensionNotFoundOrNotSupportedTopology] =
useState<boolean>(false);
const [isSymmetricalNbBusBarSections, setIsSymmetricalNbBusBarSections] = useState<boolean>(false);
const [busBarSectionInfos, setBusBarSectionInfos] = useState<BusBarSectionInfos[]>();
const [busBarSectionInfos, setBusBarSectionInfos] = useState<BusBarSections>();
const [allBusbarSectionsList, setAllBusbarSectionsList] = useState<string[]>([]);
const [dataFetchStatus, setDataFetchStatus] = useState<string>(FetchStatus.IDLE);
const { snackError } = useSnackMessage();
Expand All @@ -152,26 +152,18 @@ export default function CreateVoltageLevelSectionDialog({
(voltageLevelId: string) => {
if (voltageLevelId) {
setDataFetchStatus(FetchStatus.RUNNING);
fetchNetworkElementInfos(
studyUuid,
currentNodeUuid,
currentRootNetworkUuid,
EquipmentType.VOLTAGE_LEVEL,
EQUIPMENT_INFOS_TYPES.FORM.type,
voltageLevelId,
true
)
.then((voltageLevel) => {
if (voltageLevel) {
setBusBarSectionInfos(voltageLevel?.busBarSectionInfos || []);
fetchVoltageLevelBusBarSectionsInfos(studyUuid, currentNodeUuid, currentRootNetworkUuid, voltageLevelId)
.then((busBarSectionsInfos: BusBarSectionsInfos) => {
if (busBarSectionsInfos) {
setBusBarSectionInfos(busBarSectionsInfos?.busBarSections || []);
setAllBusbarSectionsList(
Object.values(voltageLevel?.busBarSectionInfos || {}).flat() as string[]
Object.values(busBarSectionsInfos?.busBarSections || {}).flat() as string[]
);
setIsExtensionNotFoundOrNotSupportedTopology(
!voltageLevel.isBusbarSectionPositionFound ||
voltageLevel?.topologyKind !== 'NODE_BREAKER'
!busBarSectionsInfos.isBusbarSectionPositionFound ||
busBarSectionsInfos?.topologyKind !== 'NODE_BREAKER'
);
setIsSymmetricalNbBusBarSections(voltageLevel.isRetrievedBusbarSections);
setIsSymmetricalNbBusBarSections(busBarSectionsInfos.isSymmetrical);
setDataFetchStatus(FetchStatus.SUCCEED);
}
})
Expand Down Expand Up @@ -233,7 +225,7 @@ export default function CreateVoltageLevelSectionDialog({

const findBusbarKeyForSection = useCallback(
(sectionId: string) => {
const infos = busBarSectionInfos as unknown as BusBarSectionInfos;
const infos = busBarSectionInfos as unknown as BusBarSections;
return Object.keys(infos || {}).find((key) => infos[key]?.includes(sectionId)) || null;
},
[busBarSectionInfos]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import PositionDiagramPane from 'components/grid-layout/cards/diagrams/singleLin
import type { UUID } from 'node:crypto';
import { POSITION_NEW_SECTION_SIDE, SWITCH_TYPE } from '../../../../network/constants';
import { useFormContext, useWatch } from 'react-hook-form';
import { BusBarSectionInfos } from './voltage-level-section.type';
import { areIdsEqual, getObjectId } from '../../../../utils/utils';
import { BusBarSections } from './voltage-level-section.type';

const getArrayPosition = (data: BusBarSectionInfos[], selectedOptionId: string) => {
const getArrayPosition = (data: BusBarSections, selectedOptionId: string) => {
if (!selectedOptionId || !data) {
return { position: -1, length: 0 };
}
Expand All @@ -49,7 +49,7 @@ const getArrayPosition = (data: BusBarSectionInfos[], selectedOptionId: string)
type OptionWithDisabled = Option & { disabled?: boolean };

interface VoltageLevelSectionsCreationFormProps {
busBarSectionInfos?: BusBarSectionInfos[];
busBarSectionInfos?: BusBarSections;
voltageLevelId: string;
allBusbarSectionsList: string[];
studyUuid: UUID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,4 @@ export type CreateVoltageLevelSectionDialogSchemaForm = {
newSwitchStates?: boolean;
};

export type BusBarSectionInfos = {
[key: string]: string[];
};
export type BusBarSections = Record<string, string[]>;
16 changes: 16 additions & 0 deletions src/services/study/network-map.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,28 @@
*/
import { CurrentLimitsData } from '../network-modification-types';
import { Equipment } from '../../components/dialogs/network-modifications/common/properties/property-utils';
import { BusBarSections } from '../../components/dialogs/network-modifications/voltage-level/section/voltage-level-section.type';
import { FeederBayInfos } from '../../components/dialogs/network-modifications/voltage-level/move-feeder-bays/move-voltage-level-feeder-bays.type';

export type SwitchInfos = {
id: string;
open: boolean;
};

export type BusBarSectionsInfos = {
topologyKind: string;
busbarCount: number;
sectionCount: number;
isSymmetrical: boolean;
isBusbarSectionPositionFound: boolean;
busBarSections: BusBarSections;
};

export type FeederBaysBusBarSectionsInfos = {
feederBaysInfos: Record<string, FeederBayInfos[]>;
busBarSectionsInfos: BusBarSectionsInfos;
};

export type BranchInfos = Equipment & {
name: string;
voltageLevelId1: string;
Expand Down
50 changes: 49 additions & 1 deletion src/services/study/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { MapHvdcLine, MapLine, MapSubstation, MapTieLine } from '@powsybl/n
import { getStudyUrlWithNodeUuidAndRootNetworkUuid, PREFIX_STUDY_QUERIES, safeEncodeURIComponent } from './index';
import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES, type VoltageLevel } from '../../components/utils/equipment-types';
import { getQueryParamsList, getUrlWithToken } from '../utils';
import { SwitchInfos } from './network-map.type';
import { BusBarSectionsInfos, FeederBaysBusBarSectionsInfos, SwitchInfos } from './network-map.type';
import type { SpreadsheetEquipmentType } from '../../components/spreadsheet-view/types/spreadsheet.type';
import { JSONSchema4 } from 'json-schema';

Expand Down Expand Up @@ -161,6 +161,54 @@ export function fetchSwitchesOfVoltageLevel(
return backendFetchJson(fetchSwitchesUrl);
}

export function fetchVoltageLevelBusBarSectionsInfos(
studyUuid: UUID,
currentNodeUuid: UUID,
currentRootNetworkUuid: UUID,
voltageLevelId: string
): Promise<BusBarSectionsInfos> {
console.info(
`Fetching bus bar sections information of study '${studyUuid}' on root network '${currentRootNetworkUuid}' and node '${currentNodeUuid}' + ' for voltage level '${voltageLevelId}'...`
);
const urlSearchParams = new URLSearchParams();
urlSearchParams.append('inUpstreamBuiltParentNode', 'true');

const fetchTopologyUrl =
getStudyUrlWithNodeUuidAndRootNetworkUuid(studyUuid, currentNodeUuid, currentRootNetworkUuid) +
'/network/voltage-levels/' +
encodeURIComponent(voltageLevelId) +
'/bus-bar-sections' +
'?' +
urlSearchParams.toString();

console.debug(fetchTopologyUrl);
return backendFetchJson(fetchTopologyUrl);
}

export function fetchVoltageLevelFeederBaysBusBarSectionsInfos(
studyUuid: UUID,
currentNodeUuid: UUID,
currentRootNetworkUuid: UUID,
voltageLevelId: string
): Promise<FeederBaysBusBarSectionsInfos> {
console.info(
`Fetching feeder bays and bus bar sections information of study '${studyUuid}' on root network '${currentRootNetworkUuid}' and node '${currentNodeUuid}' + ' for voltage level '${voltageLevelId}'...`
);
const urlSearchParams = new URLSearchParams();
urlSearchParams.append('inUpstreamBuiltParentNode', 'true');

const fetchTopologyUrl =
getStudyUrlWithNodeUuidAndRootNetworkUuid(studyUuid, currentNodeUuid, currentRootNetworkUuid) +
'/network/voltage-levels/' +
encodeURIComponent(voltageLevelId) +
'/feeder-bays-and-bus-bar-sections' +
'?' +
urlSearchParams.toString();

console.debug(fetchTopologyUrl);
return backendFetchJson(fetchTopologyUrl);
}

/* substations */
export function getSubstationSingleLineDiagram({
studyUuid,
Expand Down
Loading