Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -16,6 +16,7 @@ type DirectoryItemsInputLineProps = {
equipmentTypes?: string[];
elementType: string;
hideErrorMessage: boolean;
allowMultiSelect?: boolean;
};

export function ParameterLineDirectoryItemsInput({
Expand All @@ -24,6 +25,7 @@ export function ParameterLineDirectoryItemsInput({
equipmentTypes,
elementType,
hideErrorMessage,
allowMultiSelect = true,
}: Readonly<DirectoryItemsInputLineProps>) {
return (
<Grid item container spacing={1} paddingTop={1} paddingBottom={1}>
Expand All @@ -39,6 +41,7 @@ export function ParameterLineDirectoryItemsInput({
hideErrorMessage={hideErrorMessage}
label={undefined}
itemFilter={undefined}
allowMultiSelect={allowMultiSelect}
/>
</Grid>
</Grid>
Expand Down
1 change: 1 addition & 0 deletions src/components/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export * from './network-visualizations';
export * from './loadflow';
export * from './short-circuit';
export * from './voltage-init';
export * from './pcc-min';
export * from './security-analysis';
export * from './sensi';
8 changes: 8 additions & 0 deletions src/components/parameters/pcc-min/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* 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 https://mozilla.org/MPL/2.0/.
*/

export * from './pcc-min-parameters-inline';
34 changes: 34 additions & 0 deletions src/components/parameters/pcc-min/pcc-min-form-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* 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/.
*/

import { PccMinParameters } from '../../../services';
import { FILTER_ID, FILTER_NAME, FILTERS, ID } from '../../../utils/constants/filterConstant';
import { NAME } from '../../inputs';

export const fromPccMinParametersFormToParamValues = (newParams: Record<string, any>): PccMinParameters | null => ({
filters:
newParams[FILTERS]?.map((filter: any) => ({
filterId: filter[ID],
filterName: filter[NAME],
})) ?? [],
});

export const fromPccMinParamsDataToFormValues = (parameters: PccMinParameters | null): Record<string, any> => ({
[FILTERS]:
parameters?.[FILTERS]?.map((filter) => ({
[ID]: filter[FILTER_ID],
[NAME]: filter[FILTER_NAME],
})) ?? [],
});

export const fromStudyPccMinParamsDataToFormValues = (parameters: PccMinParameters | null): Record<string, any> => ({
[FILTERS]:
parameters?.[FILTERS]?.map((filter) => ({
[ID]: filter[FILTER_ID],
[NAME]: filter[FILTER_NAME],
})) ?? [],
});
101 changes: 101 additions & 0 deletions src/components/parameters/pcc-min/pcc-min-parameters-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* 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 https://mozilla.org/MPL/2.0/.
*/

import { Box, Grid, LinearProgress } from '@mui/material';
import { ReactNode } from 'react';
import { CustomFormProvider } from '../../inputs';
import { ParameterLineDirectoryItemsInput } from '../common';
import type { MuiStyles } from '../../../utils/styles';
import { ElementType, EquipmentType } from '../../../utils';
import { UsePccMinParametersFormReturn } from './use-pcc-min-parameters-form';
import { FILTERS } from '../../../utils/constants/filterConstant';

export const styles = {
gridWithActions: (theme) => ({
overflowY: 'auto',
overflowX: 'hidden',
paddingRight: theme.spacing(2),
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(1),
flexGrow: 1,
maxHeight: '85%',
}),
gridWithoutActions: (theme) => ({
overflowY: 'auto',
overflowX: 'hidden',
paddingRight: theme.spacing(2),
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(1),
flexGrow: 1,
maxHeight: '100%',
}),
} as const satisfies MuiStyles;

interface PccMinParametersFormProps {
pccMinMethods: UsePccMinParametersFormReturn;
renderTitleFields?: () => ReactNode;
renderActions?: () => ReactNode;
}

export function PccMinParametersForm({
pccMinMethods,
renderTitleFields,
renderActions,
}: Readonly<PccMinParametersFormProps>) {
const { formMethods, formSchema, paramsLoading } = pccMinMethods;

return (
<CustomFormProvider validationSchema={formSchema} {...formMethods} removeOptional>
<Box
sx={{
height: '100%',
position: 'relative',
}}
>
<Grid item container sx={renderActions ? styles.gridWithActions : styles.gridWithoutActions}>
<Grid item container direction="column">
{renderTitleFields?.()}
</Grid>
{paramsLoading ? (
<LinearProgress />
) : (
<Box
sx={{
height: '100%',
width: '100%',
}}
>
<Grid item container direction="column">
<ParameterLineDirectoryItemsInput
name={FILTERS}
equipmentTypes={[EquipmentType.VOLTAGE_LEVEL]}
elementType={ElementType.FILTER}
label="pccMinParamFilter"
hideErrorMessage
allowMultiSelect={false}
/>
</Grid>
</Box>
)}
</Grid>
{renderActions && (
<Grid
item
container
direction="column"
sx={{
position: 'fixed',
bottom: '15px',
}}
>
{renderActions()}
</Grid>
)}
</Box>
</CustomFormProvider>
);
}
94 changes: 94 additions & 0 deletions src/components/parameters/pcc-min/pcc-min-parameters-inline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* 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/.
*/

import { useCallback, useEffect, useState } from 'react';
import { Box, Grid } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import type { UUID } from 'node:crypto';
import { useSnackMessage } from '../../../hooks';
import { SubmitButton } from '../../inputs';
import { LabelledButton } from '../common';
import { PopupConfirmationDialog } from '../../dialogs';
import { UsePccMinParametersForm } from './use-pcc-min-parameters-form';
import { PccMinParametersForm } from './pcc-min-parameters-form';
import { PccMinParameters, updatePccMinParameters } from '../../../services/pcc-min';

export function PccMinParametersInLine({
studyUuid,
setHaveDirtyFields,
pccMinParameters,
}: Readonly<{
studyUuid: UUID | null;
setHaveDirtyFields: (isDirty: boolean) => void;
pccMinParameters: PccMinParameters | null;
}>) {
const pccMinMethods = UsePccMinParametersForm({
parametersUuid: null,
name: null,
description: null,
studyUuid,
parameters: pccMinParameters,
});

const [openResetConfirmation, setOpenResetConfirmation] = useState(false);
const { snackError } = useSnackMessage();

const { formState, handleSubmit } = pccMinMethods.formMethods;

const resetPccMinParameters = useCallback(() => {
updatePccMinParameters(studyUuid, null) // null means Reset
.catch((error) => {
snackError({
messageTxt: error.message,
headerId: 'updatePccMinParametersError',
});
});

setOpenResetConfirmation(false);
}, [studyUuid, snackError]);

const handleResetClick = useCallback(() => {
setOpenResetConfirmation(true);
}, []);

const handleCancelReset = useCallback(() => {
setOpenResetConfirmation(false);
}, []);

useEffect(() => {
setHaveDirtyFields(!!Object.keys(formState.dirtyFields).length);
}, [formState, setHaveDirtyFields]);

return (
<PccMinParametersForm
pccMinMethods={pccMinMethods}
renderActions={() => {
return (
<Box>
<Grid container item>
<LabelledButton callback={handleResetClick} label="resetToDefault" />
<SubmitButton onClick={handleSubmit(pccMinMethods.onSaveInline)} variant="outlined">
<FormattedMessage id="validate" />
</SubmitButton>
</Grid>

{/* Reset Confirmation Dialog */}
{openResetConfirmation && (
<PopupConfirmationDialog
message="resetParamsConfirmation"
validateButtonLabel="validate"
openConfirmationPopup={openResetConfirmation}
setOpenConfirmationPopup={handleCancelReset}
handlePopupConfirmation={resetPccMinParameters}
/>
)}
</Box>
);
}}
/>
);
}
117 changes: 117 additions & 0 deletions src/components/parameters/pcc-min/use-pcc-min-parameters-form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* 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 https://mozilla.org/MPL/2.0/.
*/

import { useForm, UseFormReturn } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { ObjectSchema } from 'yup';
import type { UUID } from 'node:crypto';
import yup from '../../../utils/yupConfig';
import {
fromPccMinParametersFormToParamValues,
fromPccMinParamsDataToFormValues,
fromStudyPccMinParamsDataToFormValues,
} from './pcc-min-form-utils';
import { useSnackMessage } from '../../../hooks';
import { NAME } from '../../inputs';
import { FILTERS, ID } from '../../../utils/constants/filterConstant';
import { getPccMinStudyParameters, PccMinParameters, updatePccMinParameters } from '../../../services/pcc-min';

export interface UsePccMinParametersFormReturn {
formMethods: UseFormReturn;
formSchema: ObjectSchema<any>;
paramsLoading: boolean;
onSaveInline: (formData: Record<string, any>) => void;
}

type UsePccMinParametersFormProps = {
parametersUuid: UUID | null;
name: string | null;
description: string | null;
studyUuid: UUID | null;
parameters: PccMinParameters | null;
};

export const UsePccMinParametersForm = ({
parametersUuid,
studyUuid,
parameters,
}: UsePccMinParametersFormProps): UsePccMinParametersFormReturn => {
const [paramsLoading, setParamsLoading] = useState<boolean>(false);
const { snackError } = useSnackMessage();

const formSchema = useMemo(() => {
return yup.object({
[FILTERS]: yup.array().of(
yup.object().shape({
[ID]: yup.string().required(),
[NAME]: yup.string().required(),
})
),
});
}, []);

const formMethods = useForm({
defaultValues: {
[FILTERS]: [],
},
resolver: yupResolver(formSchema as unknown as yup.ObjectSchema<any>),
});

const { reset } = formMethods;

const onSaveInline = useCallback(
(formData: Record<string, any>) => {
if (studyUuid) {
updatePccMinParameters(studyUuid, fromPccMinParametersFormToParamValues(formData)).catch((error) => {
snackError({
messageTxt: error.message,
headerId: 'updatePccMinParametersError',
});
});
}
},
[snackError, studyUuid]
);

// GridExplore init case
useEffect(() => {
if (parametersUuid) {
const timer = setTimeout(() => {
setParamsLoading(true);
}, 700);
Comment on lines +84 to +86
Copy link
Contributor

Choose a reason for hiding this comment

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

Why ? Why do we need to wait 700ms to set that params are loading ?

getPccMinStudyParameters(parametersUuid)
.then((params) => {
reset(fromPccMinParamsDataToFormValues(params));
})
.catch((error: Error) => {
snackError({
messageTxt: error.message,
headerId: 'paramsRetrievingError',
});
})
.finally(() => {
clearTimeout(timer);
setParamsLoading(false);
});
}
}, [parametersUuid, reset, snackError]);

// GridStudy init case
useEffect(() => {
if (parameters) {
reset(fromStudyPccMinParamsDataToFormValues(parameters));
}
}, [parameters, reset]);

return {
formMethods,
formSchema,
paramsLoading,
onSaveInline,
};
};
2 changes: 1 addition & 1 deletion src/components/parameters/sensi/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { DistributionType, SensitivityType } from '../../../utils';
import { PROVIDER } from '../common';
import { getNameElementEditorSchema } from '../common/name-element-editor';
import { NAME } from '../../inputs';
import { ID } from '../voltage-init';
import { ID } from '../../../utils/constants/filterConstant';

const getMonitoredBranchesSchema = () => {
return {
Expand Down
Loading
Loading