Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b470abb
Add filter by substation or VL to contingency list
flomillot Oct 10, 2025
f3da51a
Merge branch 'main' into filter-based-contingency-list
flomillot Oct 13, 2025
65e8221
Update translations for contingency list table column labels in Engli…
flomillot Oct 13, 2025
ce12ae9
Replace `crypto` import with `node:crypto` and mark `VisualizationPan…
flomillot Oct 13, 2025
aed876d
Refactor contingency list filter-related functions to simplify parame…
flomillot Oct 14, 2025
960d90f
Adapt contingency list filters to use `FiltersWithEquipmentTypes` typ…
flomillot Oct 14, 2025
002d49b
Cast values returned by `useWatch` to `unknown` before applying speci…
flomillot Oct 14, 2025
87287ef
Rename `id` to `filterId` in `FilterBasedContingencyList` for clarity…
flomillot Oct 15, 2025
1693f1c
Improve clarity and consistency in `FilterBasedContingencyListVisuali…
flomillot Oct 15, 2025
df1ed00
Rename `id` to `filterId` in `selectedEquipmentTypesByFilter` for con…
flomillot Oct 15, 2025
05e2e88
Adjust grid and dialog layout for improved UI responsiveness
flomillot Oct 15, 2025
3c0f304
Fix grid layout in `FilterBasedContingencyListVisualizationPanel`
flomillot Oct 15, 2025
961aafc
Adjust grid container in `ContingencyListFilterBasedForm` for consist…
flomillot Oct 15, 2025
7dfb84d
Fix `shouldDisplayRefreshButton` logic in `FilterBasedContingencyList…
flomillot Oct 15, 2025
353545d
Fix grid layout in `FilterBasedContingencyListVisualizationPanel`
flomillot Oct 15, 2025
90545ad
Fix grid layout in `FilterBasedContingencyListVisualizationPanel`
flomillot Oct 15, 2025
f8f6d74
Refactor overlay logic in `FilterBasedContingencyListVisualizationPanel`
flomillot Oct 15, 2025
5136b69
Add warning alert for missing equipments in `FilterBasedContingencyLi…
flomillot Oct 15, 2025
c04a50f
Adjust grid margins in `ContingencyListFilterBasedForm` for improved …
flomillot Oct 15, 2025
cf1d7ef
Fine-tune grid margins in `ContingencyListFilterBasedForm` for better…
flomillot Oct 15, 2025
fca40f5
Enhance `FilterBasedContingencyListVisualizationPanel` functionality …
flomillot Oct 16, 2025
703ef78
Rename `focusOnRowById` to `scrollOnRowById` in `FilterBasedContingen…
flomillot Oct 16, 2025
7023282
Update button layout for missing equipment warning in `FilterBasedCon…
flomillot Oct 16, 2025
5d1f576
Refactor separator row rendering in `FilterBasedContingencyListVisual…
flomillot Oct 16, 2025
38cf1d3
Update `@gridsuite/commons-ui` dependency to v0.132.0 in `package.json`
flomillot Oct 16, 2025
7c794bf
Refactor and enhance UI components in `ContingencyListFilterBasedForm…
flomillot Oct 16, 2025
1f142f0
Ensure separator row is scrolled into 'top' position in `FilterBasedC…
flomillot Oct 17, 2025
8228ea7
Handle nullish values for `name` and `equipmentType` in `contingency-…
flomillot Oct 17, 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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@gridsuite/commons-ui": "0.131.0",
"@gridsuite/commons-ui": "0.132.0",
"@hookform/resolvers": "^4.1.3",
"@mui/icons-material": "^5.18.0",
"@mui/lab": "5.0.0-alpha.175",
Expand Down
30 changes: 27 additions & 3 deletions src/components/dialogs/contingency-list/contingency-list-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
import type { SetRequired } from 'type-fest';
import { prepareContingencyListForBackend } from '../contingency-list-helper';
import { ContingencyListType } from '../../../utils/elementType';
import { FilterAttributes } from '../../../utils/contingency-list.type';
import {
ContingencyFieldConstants,
FilterAttributes,
FilterBasedContingencyList,
FilterElement,
} from '../../../utils/contingency-list.type';

export interface Identifier {
type: 'ID_BASED';
Expand Down Expand Up @@ -72,13 +77,25 @@ export const getCriteriaBasedFormDataFromFetchedElement = (response: any, name:
...getCriteriaBasedFormData(response),
});

export const getFilterBasedFormDataFromFetchedElement = (response: any, name: string, description: string) => ({
export const getFilterBasedFormDataFromFetchedElement = (
response: FilterBasedContingencyList,
name: string,
description: string
) => ({
[FieldConstants.NAME]: name,
[FieldConstants.DESCRIPTION]: description,
[FieldConstants.CONTINGENCY_LIST_TYPE]: ContingencyListType.FILTERS.id,
[FieldConstants.FILTERS]: response.filters.map((filter: FilterAttributes) => {
return { id: filter.id, name: filter.name, specificMetadata: { equipmentType: filter.equipmentType } };
return {
id: filter.id,
name: filter.name ?? '',
specificMetadata: { equipmentType: filter.equipmentType ?? '' },
};
}),
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER]: response.selectedEquipmentTypesByFilter.map((value) => ({
[ContingencyFieldConstants.FILTER_ID]: value.filterId,
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES]: value.equipmentTypes,
})),
});

export const getExplicitNamingFormDataFromFetchedElement = (response: any, name: string, description: string) => {
Expand Down Expand Up @@ -141,3 +158,10 @@ export const SUPPORTED_CONTINGENCY_LIST_EQUIPMENTS = Object.fromEntries(
([key]) => !excludedEquipmentTypes.includes(key as EquipmentType)
)
);

export function isSubstationOrVoltageLevelFilter(filter: FilterElement) {
return (
filter.specificMetadata.equipmentType === EquipmentType.SUBSTATION ||
filter.specificMetadata.equipmentType === EquipmentType.VOLTAGE_LEVEL
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ import {
CustomMuiDialog,
FieldConstants,
MAX_CHAR_DESCRIPTION,
TreeViewFinderNodeProps,
useSnackMessage,
yupConfig as yup,
} from '@gridsuite/commons-ui';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useSelector } from 'react-redux';
import { useCallback, useEffect, useState } from 'react';
import { UUID } from 'crypto';
import { UUID } from 'node:crypto';
import { ObjectSchema } from 'yup';
import {
ContingencyFieldConstants,
FilterBasedContingencyList,
FilterElement,
FilterSubEquipments,
} from '../../../../utils/contingency-list.type';
import ContingencyListFilterBasedForm from './contingency-list-filter-based-form';
import { AppState } from '../../../../redux/types';
import {
Expand All @@ -29,24 +34,34 @@ import {
import { handleNotAllowedError } from '../../../utils/rest-errors';
import { ContingencyListType } from '../../../../utils/elementType';
import { getFilterBasedFormDataFromFetchedElement } from '../contingency-list-utils';
import { FilterBasedContingencyList } from '../../../../utils/contingency-list.type';

const schema: ObjectSchema<ContingencyListFilterBasedFormData> = yup.object().shape({
[FieldConstants.NAME]: yup.string().required(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
[FieldConstants.FILTERS]: yup.array().required(),
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER]: yup
.array()
.required()
.of(
yup.object().shape({
[ContingencyFieldConstants.FILTER_ID]: yup.string().required(),
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES]: yup.array().required().of(yup.string().required()),
})
),
});

export interface ContingencyListFilterBasedFormData {
[FieldConstants.NAME]: string;
[FieldConstants.DESCRIPTION]?: string;
[FieldConstants.FILTERS]: TreeViewFinderNodeProps[];
[FieldConstants.FILTERS]: FilterElement[];
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER]: FilterSubEquipments[];
}

const getContingencyListEmptyFormData = (name = '') => ({
[FieldConstants.NAME]: name,
[FieldConstants.DESCRIPTION]: '',
[FieldConstants.FILTERS]: [],
[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER]: [],
});

const emptyFormData = (name?: string) => getContingencyListEmptyFormData(name);
Expand Down Expand Up @@ -111,11 +126,17 @@ export default function FilterBasedContingencyListDialog({
const onSubmit = useCallback(
(data: ContingencyListFilterBasedFormData) => {
const filterBaseContingencyList: FilterBasedContingencyList = {
filters: data[FieldConstants.FILTERS]?.map((item: TreeViewFinderNodeProps) => {
filters: data[FieldConstants.FILTERS]?.map((filter) => {
return {
id: item.id,
id: filter.id,
};
}),
selectedEquipmentTypesByFilter: data[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER]?.map(
(filterSubEquipments) => ({
filterId: filterSubEquipments[ContingencyFieldConstants.FILTER_ID],
equipmentTypes: filterSubEquipments[ContingencyFieldConstants.SUB_EQUIPMENT_TYPES],
})
),
};

if (id) {
Expand Down Expand Up @@ -170,9 +191,14 @@ export default function FilterBasedContingencyListDialog({
onSave={onSubmit}
formSchema={schema}
formMethods={methods}
unscrollableFullHeight
disabledSave={Boolean(!!nameError || isValidating)}
isDataFetching={isFetching}
sx={{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

height are width are not correct. Height should be 90vh and width: 50vw.
if not possible keep unscrollableFullHeight and we'll try to fix it in another PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As said by @thangqp this morning, apparently it's pretty flexible, so I think I will stay like this

'.MuiDialog-paper': {
minWidth: '60vw',
height: '95vh',
},
}}
>
<ContingencyListFilterBasedForm />
</CustomMuiDialog>
Expand Down
Loading
Loading