-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Visualize composite modifications #538
Changes from 12 commits
208daf7
79600b0
0f08acd
75e8df4
86831c6
5cca28c
8be793a
0982dfa
19b39f1
a3b92e0
00b9ff9
62703c9
9a373bc
e212512
dd6c719
14107da
f263799
ab6cad7
68d5494
ca1f475
618d372
0e06eeb
2ae94b8
cd382e5
3a62a60
068a7c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/** | ||
* Copyright (c) 2024, 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 { FunctionComponent, SyntheticEvent, useEffect, useState } from 'react'; | ||
import { useParameterState } from '../../use-parameters-dialog'; | ||
import { PARAM_LANGUAGE } from '../../../../utils/config-params'; | ||
import { | ||
CustomMuiDialog, | ||
FieldConstants, | ||
NetworkModificationMetadata, | ||
NO_SELECTION_FOR_COPY, | ||
unscrollableDialogStyles, | ||
useModificationLabelComputer, | ||
useSnackMessage, | ||
yupConfig as yup, | ||
} from '@gridsuite/commons-ui'; | ||
import { useForm } from 'react-hook-form'; | ||
import { yupResolver } from '@hookform/resolvers/yup'; | ||
import { getCompositeModificationContent, saveCompositeModification } from '../../../../utils/rest-api'; | ||
import CompositeModificationEditionForm from './composite-modification-edition-form'; | ||
import { List, ListItem } from '@mui/material'; | ||
import { useIntl } from 'react-intl'; | ||
import Divider from '@mui/material/Divider'; | ||
import Box from '@mui/material/Box'; | ||
import { setSelectionForCopy } from '../../../../redux/actions'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import { AppState } from '../../../../redux/reducer'; | ||
|
||
const schema = yup.object().shape({ | ||
[FieldConstants.NAME]: yup.string().trim().required('nameEmpty'), | ||
}); | ||
|
||
const emptyFormData = (name?: string) => ({ | ||
[FieldConstants.NAME]: name, | ||
}); | ||
|
||
interface FormData { | ||
[FieldConstants.NAME]: string; | ||
} | ||
|
||
interface CompositeModificationEditionDialogProps { | ||
compositeModificationId: string; | ||
open: boolean; | ||
onClose: (event?: SyntheticEvent) => void; | ||
titleId: string; | ||
name: string; | ||
broadcastChannel: BroadcastChannel; | ||
} | ||
|
||
export const CompositeModificationEditionDialog: FunctionComponent<CompositeModificationEditionDialogProps> = ({ | ||
compositeModificationId, | ||
open, | ||
onClose, | ||
titleId, | ||
name, | ||
broadcastChannel, | ||
}: Readonly<CompositeModificationEditionDialogProps>) => { | ||
const intl = useIntl(); | ||
const [languageLocal] = useParameterState(PARAM_LANGUAGE); | ||
const [isFetching, setIsFetching] = useState(!!compositeModificationId); | ||
const { snackError } = useSnackMessage(); | ||
const selectionForCopy = useSelector((state: AppState) => state.selectionForCopy); | ||
const [modifications, setModifications] = useState<NetworkModificationMetadata[]>([]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useState<NetworkCompositeModificationMetadata[]>([]); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually no : those are the "metadata" from regular network modifications, not from composite network modification. |
||
const dispatch = useDispatch(); | ||
|
||
const methods = useForm<FormData>({ | ||
defaultValues: emptyFormData(name), | ||
resolver: yupResolver(schema), | ||
}); | ||
|
||
const { computeLabel } = useModificationLabelComputer(); | ||
const getModificationLabel = (modif: NetworkModificationMetadata) => { | ||
if (!modif) { | ||
return null; | ||
} | ||
return intl.formatMessage( | ||
{ id: 'network_modifications.' + modif.type }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes done. eslint is forcing me to do it now anyway ! |
||
{ | ||
...modif, | ||
...computeLabel(modif), | ||
} | ||
); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
const renderNetworkModificationsList = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. render.. could be improved, it doesn't clearly convey what the function does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a copy paste. Maybe the original author used "render" because it contains jsx anchor code ? |
||
return ( | ||
<> | ||
{modifications && ( | ||
<List sx={unscrollableDialogStyles.scrollableContent}> | ||
{modifications.map((modification: NetworkModificationMetadata) => ( | ||
<> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are missing keys. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and then you have to remove the key from the ListItem as the React.Fragment managing the key There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, done. |
||
<ListItem key={modification.uuid}> | ||
<Box>{getModificationLabel(modification)}</Box> | ||
</ListItem> | ||
<Divider component="li" /> | ||
</> | ||
))} | ||
</List> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
useEffect(() => { | ||
setIsFetching(true); | ||
getCompositeModificationContent(compositeModificationId) | ||
.then((response) => { | ||
if (response) { | ||
setModifications(response); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setCompositeModifications(response); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can change this to |
||
} | ||
}) | ||
.catch((error) => { | ||
snackError({ | ||
messageTxt: error.message, | ||
headerId: 'cannotRetrieveCompositeModification', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RetrieveCompositeModificationError ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK done. |
||
}); | ||
}) | ||
.finally(() => setIsFetching(false)); | ||
}, [compositeModificationId, name, snackError]); | ||
|
||
const closeAndClear = (event?: SyntheticEvent) => { | ||
onClose(event); | ||
}; | ||
|
||
const onSubmit = (formData: FormData) => { | ||
saveCompositeModification(compositeModificationId, formData[FieldConstants.NAME]) | ||
.then(() => { | ||
if (selectionForCopy.sourceItemUuid === compositeModificationId) { | ||
dispatch(setSelectionForCopy(NO_SELECTION_FOR_COPY)); | ||
broadcastChannel.postMessage({ | ||
NO_SELECTION_FOR_COPY, | ||
}); | ||
} | ||
closeAndClear(); | ||
}) | ||
.catch((errorMessage) => { | ||
snackError({ | ||
messageTxt: errorMessage, | ||
headerId: 'contingencyListEditingError', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. contingencyListEditingError ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops ! Well seen thank you. Done. |
||
headerValues: { name }, | ||
}); | ||
}); | ||
}; | ||
|
||
return ( | ||
<CustomMuiDialog | ||
open={open} | ||
onClose={closeAndClear} | ||
titleId={titleId} | ||
onSave={onSubmit} | ||
removeOptional={true} | ||
isDataFetching={isFetching} | ||
language={languageLocal} | ||
formSchema={schema} | ||
formMethods={methods} | ||
unscrollableFullHeight | ||
> | ||
{!isFetching && ( | ||
<Box sx={unscrollableDialogStyles.unscrollableContainer}> | ||
<CompositeModificationEditionForm /> | ||
{renderNetworkModificationsList()} | ||
</Box> | ||
)} | ||
</CustomMuiDialog> | ||
); | ||
}; | ||
Mathieu-Deharbe marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* Copyright (c) 2024, 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 { UniqueNameInput, ElementType, FieldConstants } from '@gridsuite/commons-ui'; | ||
import { elementExists } from 'utils/rest-api'; | ||
import { useSelector } from 'react-redux'; | ||
import { AppState } from 'redux/reducer'; | ||
import Box from '@mui/material/Box'; | ||
|
||
const CompositeModificationEditionForm = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CompositeModificationForm ? |
||
const activeDirectory = useSelector((state: AppState) => state.activeDirectory); | ||
return ( | ||
<Box> | ||
<UniqueNameInput | ||
name={FieldConstants.NAME} | ||
label={'nameProperty'} | ||
elementType={ElementType.MODIFICATION} | ||
activeDirectory={activeDirectory} | ||
elementExists={elementExists} | ||
/> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default CompositeModificationEditionForm; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; | |
import * as constants from '../utils/UIconstants'; | ||
import CircularProgress from '@mui/material/CircularProgress'; | ||
|
||
import { ContingencyListType, FilterType } from '../utils/elementType'; | ||
import { ContingencyListType, FilterType, NetworkModificationType } from '../utils/elementType'; | ||
import { | ||
CriteriaBasedFilterEditionDialog, | ||
DescriptionModificationDialog, | ||
|
@@ -54,6 +54,7 @@ import AddIcon from '@mui/icons-material/Add'; | |
import { AppState } from '../redux/reducer'; | ||
import { AgGridReact } from 'ag-grid-react'; | ||
import { SelectionForCopy } from '@gridsuite/commons-ui/dist/components/filter/filter.type'; | ||
import CompositeModificationEditionDialog from './dialogs/network-modification/composite-modification/composite-modification-edition-dialog'; | ||
|
||
const circularProgressSize = '70px'; | ||
|
||
|
@@ -209,6 +210,14 @@ const DirectoryContent = () => { | |
}; | ||
const [currentExplicitNamingFilterId, setCurrentExplicitNamingFilterId] = useState(null); | ||
|
||
const handleCloseCompositeModificationDialog = () => { | ||
setOpenDialog(constants.DialogsId.NONE); | ||
setCurrentNetworkModificationId(null); | ||
setActiveElement(null); | ||
setElementName(''); | ||
}; | ||
const [currentNetworkModificationId, setCurrentNetworkModificationId] = useState(null); | ||
|
||
/** | ||
* Filters dialog: window status value to edit Expert filters | ||
*/ | ||
|
@@ -392,6 +401,12 @@ const DirectoryContent = () => { | |
setOpenDialog(subtype); | ||
} | ||
break; | ||
case ElementType.MODIFICATION: | ||
if (subtype === NetworkModificationType.COMPOSITE.id) { | ||
setCurrentNetworkModificationId(event.data.elementUuid); | ||
setOpenDialog(subtype); | ||
} | ||
break; | ||
default: | ||
break; | ||
} | ||
|
@@ -529,6 +544,18 @@ const DirectoryContent = () => { | |
// TODO openDialog should also be aware of the dialog's type, not only its subtype, because | ||
// if/when two different dialogs have the same subtype, this function will display the wrong dialog. | ||
switch (openDialog) { | ||
case NetworkModificationType.COMPOSITE.id: | ||
return ( | ||
<CompositeModificationEditionDialog | ||
open={true} | ||
titleId={'compositeModification'} | ||
// @ts-expect-error TODO: manage null case(s) here | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in a very simple and straightforward way. If it ever happens it will cause a regular error during the fetch. I didn't change the other TODOs on the same subject that are in the same switch. |
||
compositeModificationId={currentNetworkModificationId} | ||
onClose={handleCloseCompositeModificationDialog} | ||
name={name} | ||
broadcastChannel={broadcastChannel} | ||
/> | ||
); | ||
case ContingencyListType.CRITERIA_BASED.id: | ||
return ( | ||
<CriteriaBasedEditionDialog | ||
|
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only Edition ? it could be just CompositeModificationDialog
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. It should be enough, at least for now. And I am tired of those huge names.