|
| 1 | +/* |
| 2 | + * Copyright © 2024, RTE (http://www.rte-france.com) |
| 3 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 6 | + */ |
| 7 | + |
| 8 | +import type { UUID } from 'crypto'; |
| 9 | +import { type Dispatch, type SetStateAction, useCallback, useEffect, useState } from 'react'; |
| 10 | +import { |
| 11 | + DescriptionModificationDialog, |
| 12 | + type ElementAttributes, |
| 13 | + ElementType, |
| 14 | + ExpertFilterEditionDialog, |
| 15 | + ExplicitNamingFilterEditionDialog, |
| 16 | + isStudyMetadata, |
| 17 | + useSnackMessage, |
| 18 | +} from '@gridsuite/commons-ui'; |
| 19 | +import type { CellClickedEvent } from 'ag-grid-community'; |
| 20 | +import { useDispatch, useSelector } from 'react-redux'; |
| 21 | +import { useIntl } from 'react-intl'; |
| 22 | +import { elementExists, getFilterById, updateElement } from '../utils/rest-api'; |
| 23 | +import { ContingencyListType, FilterType, NetworkModificationType } from '../utils/elementType'; |
| 24 | +import CompositeModificationDialog from './dialogs/network-modification/composite-modification/composite-modification-dialog'; |
| 25 | +import CriteriaBasedEditionDialog from './dialogs/contingency-list/edition/criteria-based/criteria-based-edition-dialog'; |
| 26 | +import ScriptEditionDialog from './dialogs/contingency-list/edition/script/script-edition-dialog'; |
| 27 | +import ExplicitNamingEditionDialog from './dialogs/contingency-list/edition/explicit-naming/explicit-naming-edition-dialog'; |
| 28 | +import { setActiveDirectory, setItemSelectionForCopy } from '../redux/actions'; |
| 29 | +import * as constants from '../utils/UIconstants'; |
| 30 | +import type { AppState } from '../redux/types'; |
| 31 | +import { useParameterState } from './dialogs/use-parameters-dialog'; |
| 32 | +import { PARAM_LANGUAGE } from '../utils/config-params'; |
| 33 | +import type { useDirectoryContent } from '../hooks/useDirectoryContent'; |
| 34 | + |
| 35 | +export type DirectoryContentDialogProps = { |
| 36 | + cellClicked?: CellClickedEvent; |
| 37 | + setCellClicked: Dispatch<SetStateAction<CellClickedEvent | undefined>>; |
| 38 | + broadcastChannel: BroadcastChannel; |
| 39 | + setOpenDialog: Dispatch<SetStateAction<string>>; |
| 40 | + activeElement?: ElementAttributes; |
| 41 | + setActiveElement: Dispatch<SetStateAction<ElementAttributes | undefined>>; |
| 42 | + selectedDirectoryElementUuid?: UUID; |
| 43 | + childrenMetadata: ReturnType<typeof useDirectoryContent>[1]; |
| 44 | +}; |
| 45 | + |
| 46 | +export default function DirectoryContentDialog({ |
| 47 | + cellClicked: event, |
| 48 | + setCellClicked: setEvent, |
| 49 | + setOpenDialog, |
| 50 | + activeElement, |
| 51 | + setActiveElement, |
| 52 | + broadcastChannel, |
| 53 | + selectedDirectoryElementUuid, |
| 54 | + childrenMetadata, |
| 55 | +}: Readonly<DirectoryContentDialogProps>) { |
| 56 | + const intl = useIntl(); |
| 57 | + const dispatch = useDispatch(); |
| 58 | + const { snackError } = useSnackMessage(); |
| 59 | + const itemSelectionForCopy = useSelector((state: AppState) => state.itemSelectionForCopy); |
| 60 | + const activeDirectory = useSelector((state: AppState) => state.activeDirectory); |
| 61 | + const [languageLocal] = useParameterState(PARAM_LANGUAGE); |
| 62 | + const [elementName, setElementName] = useState(''); |
| 63 | + |
| 64 | + const appsAndUrls = useSelector((state: AppState) => state.appsAndUrls); |
| 65 | + const getStudyUrl = useCallback( |
| 66 | + (elementUuid: string) => { |
| 67 | + const appStudy = appsAndUrls.find(isStudyMetadata); |
| 68 | + if (appStudy) { |
| 69 | + const studyResource = appStudy.resources?.find((resource) => |
| 70 | + resource.types.includes(ElementType.STUDY) |
| 71 | + ); |
| 72 | + if (studyResource) { |
| 73 | + return appStudy.url + studyResource.path.replace('{elementUuid}', elementUuid); |
| 74 | + } |
| 75 | + } |
| 76 | + return null; |
| 77 | + }, |
| 78 | + [appsAndUrls] |
| 79 | + ); |
| 80 | + |
| 81 | + const [openDescModificationDialog, setOpenDescModificationDialog] = useState(false); |
| 82 | + const handleDescDialogClose = useCallback(() => { |
| 83 | + setActiveElement(undefined); |
| 84 | + setOpenDescModificationDialog(false); |
| 85 | + }, [setActiveElement]); |
| 86 | + |
| 87 | + /* Filters contingency list dialog: window status value for editing a filters contingency list */ |
| 88 | + const [currentFiltersContingencyListId, setCurrentFiltersContingencyListId] = useState<UUID>(); |
| 89 | + const handleCloseFiltersContingency = useCallback(() => { |
| 90 | + setOpenDialog(constants.DialogsId.NONE); |
| 91 | + setCurrentFiltersContingencyListId(undefined); |
| 92 | + setActiveElement(undefined); |
| 93 | + setElementName(''); |
| 94 | + }, [setActiveElement, setOpenDialog]); |
| 95 | + |
| 96 | + /* Explicit Naming contingency list dialog: window status value for editing an explicit naming contingency list */ |
| 97 | + const [currentExplicitNamingContingencyListId, setCurrentExplicitNamingContingencyListId] = useState<UUID>(); |
| 98 | + const handleCloseExplicitNamingContingency = useCallback(() => { |
| 99 | + setOpenDialog(constants.DialogsId.NONE); |
| 100 | + setCurrentExplicitNamingContingencyListId(undefined); |
| 101 | + setActiveElement(undefined); |
| 102 | + setElementName(''); |
| 103 | + }, [setActiveElement, setOpenDialog]); |
| 104 | + |
| 105 | + const [currentExplicitNamingFilterId, setCurrentExplicitNamingFilterId] = useState<UUID>(); |
| 106 | + /* Filters dialog: window status value to edit ExplicitNaming filters */ |
| 107 | + const handleCloseExplicitNamingFilterDialog = useCallback(() => { |
| 108 | + setOpenDialog(constants.DialogsId.NONE); |
| 109 | + setCurrentExplicitNamingFilterId(undefined); |
| 110 | + setActiveElement(undefined); |
| 111 | + setElementName(''); |
| 112 | + }, [setActiveElement, setOpenDialog]); |
| 113 | + |
| 114 | + const [currentNetworkModificationId, setCurrentNetworkModificationId] = useState<UUID>(); |
| 115 | + const handleCloseCompositeModificationDialog = useCallback(() => { |
| 116 | + setOpenDialog(constants.DialogsId.NONE); |
| 117 | + setCurrentNetworkModificationId(undefined); |
| 118 | + setActiveElement(undefined); |
| 119 | + setElementName(''); |
| 120 | + }, [setActiveElement, setOpenDialog]); |
| 121 | + |
| 122 | + /* Filters dialog: window status value to edit Expert filters */ |
| 123 | + const [currentExpertFilterId, setCurrentExpertFilterId] = useState<UUID>(); |
| 124 | + const handleCloseExpertFilterDialog = useCallback(() => { |
| 125 | + setOpenDialog(constants.DialogsId.NONE); |
| 126 | + setCurrentExpertFilterId(undefined); |
| 127 | + setActiveElement(undefined); |
| 128 | + setElementName(''); |
| 129 | + }, [setActiveElement, setOpenDialog]); |
| 130 | + |
| 131 | + /* Script contingency list dialog: window status value for editing a script contingency list */ |
| 132 | + const [currentScriptContingencyListId, setCurrentScriptContingencyListId] = useState<UUID>(); |
| 133 | + const handleCloseScriptContingency = useCallback(() => { |
| 134 | + setOpenDialog(constants.DialogsId.NONE); |
| 135 | + setCurrentScriptContingencyListId(undefined); |
| 136 | + setActiveElement(undefined); |
| 137 | + setElementName(''); |
| 138 | + }, [setActiveElement, setOpenDialog]); |
| 139 | + |
| 140 | + useEffect(() => { |
| 141 | + if (event !== undefined) { |
| 142 | + if (event.colDef.field === 'description') { |
| 143 | + setActiveElement(event.data); |
| 144 | + setOpenDescModificationDialog(true); |
| 145 | + } else if (childrenMetadata[event.data.elementUuid] !== undefined) { |
| 146 | + setElementName(childrenMetadata[event.data.elementUuid].elementName); |
| 147 | + const subtype = childrenMetadata[event.data.elementUuid].specificMetadata.type as unknown as string; |
| 148 | + /** set active directory on the store because it will be used while editing the contingency name */ |
| 149 | + dispatch(setActiveDirectory(selectedDirectoryElementUuid)); |
| 150 | + switch (event.data.type) { |
| 151 | + case ElementType.STUDY: { |
| 152 | + const url = getStudyUrl(event.data.elementUuid); |
| 153 | + if (url) { |
| 154 | + window.open(url, '_blank'); |
| 155 | + } else { |
| 156 | + snackError({ |
| 157 | + messageTxt: intl.formatMessage({ id: 'getAppLinkError' }, { type: event.data.type }), |
| 158 | + }); |
| 159 | + } |
| 160 | + break; |
| 161 | + } |
| 162 | + case ElementType.CONTINGENCY_LIST: |
| 163 | + if (subtype === ContingencyListType.CRITERIA_BASED.id) { |
| 164 | + setCurrentFiltersContingencyListId(event.data.elementUuid); |
| 165 | + setOpenDialog(subtype); |
| 166 | + } else if (subtype === ContingencyListType.SCRIPT.id) { |
| 167 | + setCurrentScriptContingencyListId(event.data.elementUuid); |
| 168 | + setOpenDialog(subtype); |
| 169 | + } else if (subtype === ContingencyListType.EXPLICIT_NAMING.id) { |
| 170 | + setCurrentExplicitNamingContingencyListId(event.data.elementUuid); |
| 171 | + setOpenDialog(subtype); |
| 172 | + } |
| 173 | + break; |
| 174 | + case ElementType.FILTER: |
| 175 | + if (subtype === FilterType.EXPLICIT_NAMING.id) { |
| 176 | + setCurrentExplicitNamingFilterId(event.data.elementUuid); |
| 177 | + setOpenDialog(subtype); |
| 178 | + } else if (subtype === FilterType.EXPERT.id) { |
| 179 | + setCurrentExpertFilterId(event.data.elementUuid); |
| 180 | + setOpenDialog(subtype); |
| 181 | + } |
| 182 | + break; |
| 183 | + case ElementType.MODIFICATION: |
| 184 | + if (subtype === NetworkModificationType.COMPOSITE.id) { |
| 185 | + setCurrentNetworkModificationId(event.data.elementUuid); |
| 186 | + setOpenDialog(subtype); |
| 187 | + } |
| 188 | + break; |
| 189 | + default: |
| 190 | + break; |
| 191 | + } |
| 192 | + } |
| 193 | + setEvent(undefined); // acknowledge parent event |
| 194 | + } |
| 195 | + }, [ |
| 196 | + childrenMetadata, |
| 197 | + dispatch, |
| 198 | + event, |
| 199 | + getStudyUrl, |
| 200 | + intl, |
| 201 | + selectedDirectoryElementUuid, |
| 202 | + setActiveElement, |
| 203 | + setEvent, |
| 204 | + setOpenDialog, |
| 205 | + snackError, |
| 206 | + ]); |
| 207 | + |
| 208 | + if (openDescModificationDialog && activeElement) { |
| 209 | + return ( |
| 210 | + <DescriptionModificationDialog |
| 211 | + open |
| 212 | + description={activeElement.description} |
| 213 | + elementUuid={activeElement.elementUuid} |
| 214 | + onClose={handleDescDialogClose} |
| 215 | + // @ts-expect-error TODO: set UUID as parameter type in commons-ui |
| 216 | + updateElement={updateElement} |
| 217 | + /> |
| 218 | + ); |
| 219 | + } |
| 220 | + if (currentNetworkModificationId !== undefined) { |
| 221 | + return ( |
| 222 | + <CompositeModificationDialog |
| 223 | + open |
| 224 | + titleId="MODIFICATION" |
| 225 | + compositeModificationId={currentNetworkModificationId} |
| 226 | + onClose={handleCloseCompositeModificationDialog} |
| 227 | + name={elementName} |
| 228 | + broadcastChannel={broadcastChannel} |
| 229 | + /> |
| 230 | + ); |
| 231 | + } |
| 232 | + if (currentFiltersContingencyListId !== undefined) { |
| 233 | + return ( |
| 234 | + <CriteriaBasedEditionDialog |
| 235 | + open |
| 236 | + titleId="editContingencyList" |
| 237 | + contingencyListId={currentFiltersContingencyListId} |
| 238 | + contingencyListType={ContingencyListType.CRITERIA_BASED.id} |
| 239 | + onClose={handleCloseFiltersContingency} |
| 240 | + name={elementName} |
| 241 | + broadcastChannel={broadcastChannel} |
| 242 | + /> |
| 243 | + ); |
| 244 | + } |
| 245 | + if (currentScriptContingencyListId !== undefined) { |
| 246 | + return ( |
| 247 | + <ScriptEditionDialog |
| 248 | + open |
| 249 | + titleId="editContingencyList" |
| 250 | + contingencyListId={currentScriptContingencyListId} |
| 251 | + contingencyListType={ContingencyListType.SCRIPT.id} |
| 252 | + onClose={handleCloseScriptContingency} |
| 253 | + name={elementName} |
| 254 | + broadcastChannel={broadcastChannel} |
| 255 | + /> |
| 256 | + ); |
| 257 | + } |
| 258 | + if (currentExplicitNamingContingencyListId !== undefined) { |
| 259 | + return ( |
| 260 | + <ExplicitNamingEditionDialog |
| 261 | + open |
| 262 | + titleId="editContingencyList" |
| 263 | + contingencyListId={currentExplicitNamingContingencyListId} |
| 264 | + contingencyListType={ContingencyListType.EXPLICIT_NAMING.id} |
| 265 | + onClose={handleCloseExplicitNamingContingency} |
| 266 | + name={elementName} |
| 267 | + broadcastChannel={broadcastChannel} |
| 268 | + /> |
| 269 | + ); |
| 270 | + } |
| 271 | + if (currentExplicitNamingFilterId !== undefined) { |
| 272 | + return ( |
| 273 | + <ExplicitNamingFilterEditionDialog |
| 274 | + id={currentExplicitNamingFilterId} |
| 275 | + open |
| 276 | + onClose={handleCloseExplicitNamingFilterDialog} |
| 277 | + titleId="editFilter" |
| 278 | + name={elementName} |
| 279 | + broadcastChannel={broadcastChannel} |
| 280 | + itemSelectionForCopy={itemSelectionForCopy} |
| 281 | + setItemSelectionForCopy={setItemSelectionForCopy} |
| 282 | + getFilterById={getFilterById} |
| 283 | + activeDirectory={activeDirectory} |
| 284 | + elementExists={elementExists} |
| 285 | + language={languageLocal} |
| 286 | + /> |
| 287 | + ); |
| 288 | + } |
| 289 | + if (currentExpertFilterId !== undefined) { |
| 290 | + return ( |
| 291 | + <ExpertFilterEditionDialog |
| 292 | + id={currentExpertFilterId} |
| 293 | + open |
| 294 | + onClose={handleCloseExpertFilterDialog} |
| 295 | + titleId="editFilter" |
| 296 | + name={elementName} |
| 297 | + broadcastChannel={broadcastChannel} |
| 298 | + itemSelectionForCopy={itemSelectionForCopy} |
| 299 | + setItemSelectionForCopy={setItemSelectionForCopy} |
| 300 | + getFilterById={getFilterById} |
| 301 | + activeDirectory={activeDirectory} |
| 302 | + elementExists={elementExists} |
| 303 | + language={languageLocal} |
| 304 | + /> |
| 305 | + ); |
| 306 | + } |
| 307 | +} |
0 commit comments