diff --git a/src/components/dialogs/copy-to-script-dialog.js b/src/components/dialogs/copy-to-script-dialog.js deleted file mode 100644 index 24347b58e..000000000 --- a/src/components/dialogs/copy-to-script-dialog.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2021, 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 React, { useEffect } from 'react'; -import Dialog from '@mui/material/Dialog'; -import DialogTitle from '@mui/material/DialogTitle'; -import DialogContent from '@mui/material/DialogContent'; -import InputLabel from '@mui/material/InputLabel'; -import TextField from '@mui/material/TextField'; -import DialogActions from '@mui/material/DialogActions'; -import Button from '@mui/material/Button'; -import { FormattedMessage } from 'react-intl'; -import PropTypes from 'prop-types'; - -/** - * Dialog to copy a filters contingency list to a script contingency list or a filter to a script - * @param id id of list or filter to edit - * @param open Is the dialog open ? - * @param onClose Event to close the dialog - * @param onClick Function to call to perform copy - * @param currentName Name before renaming - * @param title Title of the dialog - */ -const CopyToScriptDialog = ({ - id, - open, - onClose, - onClick, - currentName, - title, -}) => { - const [newNameValue, setNewNameValue] = React.useState(currentName); - - const updateNameValue = (event) => { - setNewNameValue(event.target.value); - }; - const handleClick = () => { - onClick(id, newNameValue); - }; - - const handleClose = () => { - onClose(); - }; - - useEffect(() => { - setNewNameValue(currentName || ''); - }, [currentName]); - - return ( - - {title} - - - - - -
-
-
- - - - -
- ); -}; - -CopyToScriptDialog.propTypes = { - id: PropTypes.string.isRequired, - open: PropTypes.bool.isRequired, - onClose: PropTypes.func.isRequired, - onClick: PropTypes.func.isRequired, - currentName: PropTypes.string, - title: PropTypes.string.isRequired, -}; - -export default CopyToScriptDialog; diff --git a/src/components/dialogs/copy-to-script-dialog.tsx b/src/components/dialogs/copy-to-script-dialog.tsx new file mode 100644 index 000000000..ab5962558 --- /dev/null +++ b/src/components/dialogs/copy-to-script-dialog.tsx @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2023, 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 React, { useCallback, useEffect, useState } from 'react'; +import { useIntl } from 'react-intl'; +import yup from 'components/utils/yup-config'; +import { NAME } from 'components/utils/field-constants'; +import { useForm } from 'react-hook-form'; +import { yupResolver } from '@hookform/resolvers/yup'; +import CustomMuiDialog from './commons/custom-mui-dialog/custom-mui-dialog'; +import { CircularProgress, Grid } from '@mui/material'; +import { UniqueNameInput } from './commons/unique-name-input'; +import { ElementType } from 'utils/elementType'; +import { getNameCandidate } from 'utils/rest-api'; + +const schema = yup.object().shape({ + [NAME]: yup.string().trim().required('nameEmpty'), +}); + +const emptyFormData = { + [NAME]: '', +}; + +interface CopyToScriptDialogProps { + id: string; + open: boolean; + onClose: (...args: any[]) => void; + onValidate: (...args: any[]) => void; + currentName: string; + title: string; + directoryUuid: string; + elementType: ElementType; + handleError: (...args: any[]) => void; +} + +interface FormData { + [NAME]: string; +} + +/** + * Dialog to copy a filters contingency list to a script contingency list or a filter to a script + * @param id id of list or filter to edit + * @param open Is the dialog open ? + * @param onClose Event to close the dialog + * @param onValidate Function to call to perform copy + * @param currentName Name before renaming + * @param title Title of the dialog + * @param directoryUuid Directory uuid of the list or filter to copy + * @param elementType Type of the element to copy + * @param handleError Function to call to handle error + */ +const CopyToScriptDialog: React.FunctionComponent = ({ + id, + open, + onClose, + onValidate, + currentName, + title, + directoryUuid, + elementType, + handleError, +}) => { + const [loading, setLoading] = useState(false); + const intl = useIntl(); + const methods = useForm({ + defaultValues: emptyFormData, + resolver: yupResolver(schema), + }); + + const { + formState: { errors }, + setValue, + } = methods; + + const nameError = errors[NAME]; + const isValidating = errors.root?.isValidating; + + const onSubmit = (data: FormData) => { + onValidate(id, data[NAME]); + }; + + const handleClose = () => { + onClose(); + }; + + const handleGenerateNameError = useCallback(() => { + return handleError( + intl.formatMessage( + { id: 'generateCopyScriptNameError' }, + { + itemName: currentName, + } + ) + ); + }, [currentName, handleError, intl]); + + useEffect(() => { + setLoading(true); + getNameCandidate(directoryUuid, currentName, elementType) + .then((newName) => { + let generatedName: string = newName || ''; + setValue(NAME, generatedName, { shouldDirty: true }); + }) + .catch(() => { + handleGenerateNameError(); + }) + .finally(() => { + setLoading(false); + }); + }, [ + handleGenerateNameError, + setValue, + currentName, + elementType, + directoryUuid, + ]); + + return ( + + + + {loading ? ( + + ) : ( + + )} + + + + ); +}; + +export default CopyToScriptDialog; diff --git a/src/components/menus/content-contextual-menu.js b/src/components/menus/content-contextual-menu.js index a2c3fa9cd..edfdf8c81 100644 --- a/src/components/menus/content-contextual-menu.js +++ b/src/components/menus/content-contextual-menu.js @@ -558,7 +558,7 @@ const ContentContextualMenu = (props) => { id={activeElement ? activeElement.elementUuid : ''} open={true} onClose={handleCloseDialog} - onClick={(id, newName) => + onValidate={(id, newName) => newScriptFromFiltersContingencyListCB( id, newName, @@ -568,9 +568,10 @@ const ContentContextualMenu = (props) => { currentName={ activeElement ? activeElement.elementName : '' } - title={intl.formatMessage({ - id: 'copyToScriptList', - })} + title={'copyToScriptList'} + directoryUuid={selectedDirectory?.elementUuid} + elementType={activeElement?.type} + handleError={handleLastError} /> ); case DialogsId.REPLACE_FILTER_BY_SCRIPT: @@ -594,7 +595,7 @@ const ContentContextualMenu = (props) => { id={activeElement ? activeElement.elementUuid : ''} open={true} onClose={handleCloseDialog} - onClick={(id, newName) => + onValidate={(id, newName) => newScriptFromFilterCB( id, newName, @@ -604,7 +605,10 @@ const ContentContextualMenu = (props) => { currentName={ activeElement ? activeElement.elementName : '' } - title={intl.formatMessage({ id: 'copyToScriptList' })} + title={'copyToScriptList'} + directoryUuid={selectedDirectory?.elementUuid} + elementType={activeElement?.type} + handleError={handleLastError} /> ); case DialogsId.ADD_NEW_STUDY_FROM_CASE: diff --git a/src/translations/en.json b/src/translations/en.json index 9325ac2a5..5945d58ca 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -27,6 +27,7 @@ "deleteElementsFailure": "Problem encountered while deleting {stn, plural, one {an element} other {elements}}. Not deleted : {problematic}", "moveElementsFailure": "Problem encountered while moving {stn, plural, one {an element} other {elements}}. Not moved : {problematic}", "duplicateElementFailure": "An error occured while duplicating the element {itemName} : {errorMessage}", + "generateCopyScriptNameError" : "An error occured while generating the copy script name of the element {itemName}", "caseName": "case name", "uploadCase": "Upload case", "uploadErrorMsg": "Please upload the case file", diff --git a/src/translations/fr.json b/src/translations/fr.json index 3f74616d9..be2276fab 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -27,6 +27,7 @@ "deleteElementsFailure": "Problème à la destruction {stn, plural, one {d'un élément} other {d'éléments}}. Pas {pbn, plural, one {détruit} other {détruits}} : {problematic}", "moveElementsFailure": "Problème au déplacement {stn, plural, one {d'un élément} other {d'éléments}}. Pas {pbn, plural, one {déplacé} other {déplacés}} : {problematic}", "duplicateElementFailure": "Une erreur est survenue lors de la duplication de l'élément {itemName} : {errorMessage}", + "generateCopyScriptNameError" : "Une erreur s'est produite lors de la génération du nom du script de copie de l'élément {itemName}", "caseName": "nom de la situation", "uploadCase": "télécharger la situation", "uploadErrorMsg": "Veuillez télécharger la situation",