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
15 changes: 11 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.0",
"@gridsuite/commons-ui": "0.102.0",
"@gridsuite/commons-ui": "file:../commons-ui/gridsuite-commons-ui-0.102.0.tgz",
"@hookform/resolvers": "^4.0.0",
"@mui/icons-material": "^5.16.14",
"@mui/lab": "5.0.0-alpha.175",
Expand Down
2 changes: 2 additions & 0 deletions src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useNotificationsListener,
UserManagerState,
useSnackMessage,
useYupIntl,
} from '@gridsuite/commons-ui';
import { FormattedMessage } from 'react-intl';
import { Grid } from '@mui/material';
Expand All @@ -35,6 +36,7 @@ import { AppState } from '../redux/types';

export default function App() {
const { snackError } = useSnackMessage();
useYupIntl();

const user = useSelector((state: AppState) => state.user);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { useMemo } from 'react';
import { useIntl } from 'react-intl';
import { useSelector } from 'react-redux';
import {
CustomMuiDialog,
FieldConstants,
getCriteriaBasedSchema,
MAX_CHAR_DESCRIPTION,
useSnackMessage,
yupConfig as yup,
} from '@gridsuite/commons-ui';
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { createContingencyList } from '../../../../utils/rest-api';
import ContingencyListCreationForm from './contingency-list-creation-form';
import {
ContingencyListFormData,
ContingencyListFormDataWithRequiredCriteria,
type ContingencyListFormData,
type ContingencyListFormDataWithRequiredCriteria,
getContingencyListEmptyFormData,
getFormContent,
} from '../contingency-list-utils';
import { ContingencyListType } from '../../../../utils/elementType';
import { useParameterState } from '../../use-parameters-dialog';
import { PARAM_LANGUAGE } from '../../../../utils/config-params';
import { AppState } from '../../../../redux/types';
import type { AppState } from '../../../../redux/types';
import { getExplicitNamingSchema } from '../explicit-naming/explicit-naming-utils';
import { handleNotAllowedError } from '../../../utils/rest-errors';

const schema = yup.object().shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
[FieldConstants.CONTINGENCY_LIST_TYPE]: yup.string().nullable(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().when([FieldConstants.CONTINGENCY_LIST_TYPE], {
is: ContingencyListType.CRITERIA_BASED.id,
then: (schemaThen) => schemaThen.required(),
otherwise: (schemaOtherwise) => schemaOtherwise.nullable(),
}),
...getExplicitNamingSchema(),
...getCriteriaBasedSchema(),
});

const emptyFormData = getContingencyListEmptyFormData();

export interface ContingencyListCreationDialogProps {
Expand All @@ -59,9 +48,29 @@ export default function ContingencyListCreationDialog({
}: Readonly<ContingencyListCreationDialogProps>) {
const activeDirectory = useSelector((state: AppState) => state.activeDirectory);
const { snackError } = useSnackMessage();

const intl = useIntl();
const [languageLocal] = useParameterState(PARAM_LANGUAGE);

const schema = useMemo(
() =>
yup.object().shape({
[FieldConstants.NAME]: yup
.string()
.trim()
.required(intl.formatMessage({ id: 'nameEmpty' })),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
[FieldConstants.CONTINGENCY_LIST_TYPE]: yup.string().nullable(),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().when([FieldConstants.CONTINGENCY_LIST_TYPE], {
is: ContingencyListType.CRITERIA_BASED.id,
then: (schemaThen) => schemaThen.required(),
otherwise: (schemaOtherwise) => schemaOtherwise.nullable(),
}),
...getExplicitNamingSchema(intl),
...getCriteriaBasedSchema(),
}),
[intl]
);

const methods = useForm<ContingencyListFormData>({
defaultValues: emptyFormData,
resolver: yupResolver<ContingencyListFormData>(schema),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { useIntl } from 'react-intl';
import {
CustomMuiDialog,
FieldConstants,
getCriteriaBasedSchema,
MAX_CHAR_DESCRIPTION,
NO_ITEM_SELECTION_FOR_COPY,
useSnackMessage,
yupConfig as yup,
} from '@gridsuite/commons-ui';
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { getContingencyList, saveCriteriaBasedContingencyList } from 'utils/rest-api';
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from '../../../../../redux/types';
import type { AppState } from '../../../../../redux/types';
import {
getContingencyListEmptyFormData,
getCriteriaBasedFormDataFromFetchedElement,
} from '../../contingency-list-utils';
import CriteriaBasedEditionForm from './criteria-based-edition-form';
import { setItemSelectionForCopy } from '../../../../../redux/actions';
import { useParameterState } from '../../../use-parameters-dialog';
import { CriteriaBasedEditionFormData } from '../../../../../utils/rest-api';
import { type CriteriaBasedEditionFormData } from '../../../../../utils/rest-api';
import { PARAM_LANGUAGE } from '../../../../../utils/config-params';

const schema = yup.object().shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
...getCriteriaBasedSchema(),
});

export interface CriteriaBasedEditionDialogProps {
contingencyListId: string;
contingencyListType: string;
Expand All @@ -63,6 +57,22 @@ export default function CriteriaBasedEditionDialog({
const { snackError } = useSnackMessage();
const itemSelectionForCopy = useSelector((state: AppState) => state.itemSelectionForCopy);
const dispatch = useDispatch();
const intl = useIntl();

const schema = useMemo(
() =>
yup.object().shape({
[FieldConstants.NAME]: yup
.string()
.trim()
.required(intl.formatMessage({ id: 'nameEmpty' })),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().required(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
...getCriteriaBasedSchema(),
}),
[intl]
);

const methods = useForm<CriteriaBasedEditionFormData>({
defaultValues: getContingencyListEmptyFormData(name),
resolver: yupResolver<CriteriaBasedEditionFormData>(schema),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { useIntl } from 'react-intl';
import {
CustomMuiDialog,
FieldConstants,
MAX_CHAR_DESCRIPTION,
NO_ITEM_SELECTION_FOR_COPY,
useSnackMessage,
yupConfig as yup,
} from '@gridsuite/commons-ui';
import * as yup from 'yup';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { getContingencyList, saveExplicitNamingContingencyList } from 'utils/rest-api';
import { prepareContingencyListForBackend } from 'components/dialogs/contingency-list-helper';
import { useDispatch, useSelector } from 'react-redux';
Expand All @@ -25,7 +26,7 @@ import {
} from '../../contingency-list-utils';
import ExplicitNamingEditionForm from './explicit-naming-edition-form';
import { setItemSelectionForCopy } from '../../../../../redux/actions';
import { AppState } from '../../../../../redux/types';
import type { AppState } from '../../../../../redux/types';
import { getExplicitNamingEditSchema } from '../../explicit-naming/explicit-naming-utils';

interface ExplicitNamingEditionFormData {
Expand All @@ -38,13 +39,6 @@ interface ExplicitNamingEditionFormData {
}[];
}

const schema = yup.object().shape({
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().nullable(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
...getExplicitNamingEditSchema(),
});

const emptyFormData = (name?: string) => getContingencyListEmptyFormData(name);

export interface ExplicitNamingEditionDialogProps {
Expand Down Expand Up @@ -72,6 +66,22 @@ export default function ExplicitNamingEditionDialog({
const { snackError } = useSnackMessage();
const itemSelectionForCopy = useSelector((state: AppState) => state.itemSelectionForCopy);
const dispatch = useDispatch();
const intl = useIntl();

const schema = useMemo(
() =>
yup.object().shape({
[FieldConstants.NAME]: yup
.string()
.trim()
.required(intl.formatMessage({ id: 'nameEmpty' })),
[FieldConstants.EQUIPMENT_TYPE]: yup.string().nullable(),
[FieldConstants.DESCRIPTION]: yup.string().max(MAX_CHAR_DESCRIPTION),
...getExplicitNamingEditSchema(intl),
}),
[intl]
);

const methods = useForm({
defaultValues: emptyFormData(name),
resolver: yupResolver(schema),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { FieldConstants, yupConfig as yup } from '@gridsuite/commons-ui';
import { type IntlShape } from 'react-intl';
import * as yup from 'yup';
import type { ArraySchema } from 'yup';
import { FieldConstants } from '@gridsuite/commons-ui';
import { ContingencyListType } from '../../../../utils/elementType';

const getExplicitNamingConditionSchema = (schema: yup.ArraySchema<any, any, any, any>) =>
schema
function getExplicitNamingConditionSchema(intl: IntlShape, schema: ArraySchema<any, any, any, any>) {
return schema
.min(1, 'contingencyTableContainAtLeastOneRowError')
.test(
'rowWithoutName',
'contingencyTablePartiallyDefinedError',
intl.formatMessage({ id: 'contingencyTablePartiallyDefinedError' }),
(array) => !array.some((row: any) => !row[FieldConstants.CONTINGENCY_NAME]?.trim())
)
.test(
'rowWithoutEquipments',
'contingencyTablePartiallyDefinedError',
intl.formatMessage({ id: 'contingencyTablePartiallyDefinedError' }),
(array) => !array.some((row: any) => !row[FieldConstants.EQUIPMENT_IDS]?.length)
);
}

const getSchema = () =>
yup
Expand All @@ -33,15 +37,17 @@ const getSchema = () =>
) // we remove empty lines
.compact((row) => !row[FieldConstants.CONTINGENCY_NAME] && !row[FieldConstants.EQUIPMENT_IDS]?.length);

export const getExplicitNamingSchema = () => ({
[FieldConstants.EQUIPMENT_TABLE]: getSchema().when([FieldConstants.CONTINGENCY_LIST_TYPE], {
is: ContingencyListType.EXPLICIT_NAMING.id,
then: (schema) => getExplicitNamingConditionSchema(schema),
}),
});
export function getExplicitNamingSchema(intl: IntlShape) {
return {
[FieldConstants.EQUIPMENT_TABLE]: getSchema().when([FieldConstants.CONTINGENCY_LIST_TYPE], {
is: ContingencyListType.EXPLICIT_NAMING.id,
then: (schema) => getExplicitNamingConditionSchema(intl, schema),
}),
};
}

export const getExplicitNamingEditSchema = () => {
export function getExplicitNamingEditSchema(intl: IntlShape) {
return {
[FieldConstants.EQUIPMENT_TABLE]: getExplicitNamingConditionSchema(getSchema()),
[FieldConstants.EQUIPMENT_TABLE]: getExplicitNamingConditionSchema(intl, getSchema()),
};
};
}
Loading
Loading