diff --git a/src/components/graph/menus/network-modifications/network-modification-menu.type.ts b/src/components/graph/menus/network-modifications/network-modification-menu.type.ts index 6f43814134..2d53f1b430 100644 --- a/src/components/graph/menus/network-modifications/network-modification-menu.type.ts +++ b/src/components/graph/menus/network-modifications/network-modification-menu.type.ts @@ -54,6 +54,7 @@ export enum NetworkModificationCopyType { export interface NetworkModificationCopyInfo { copyType: NetworkModificationCopyType; + originStudyUuid?: UUID; originNodeUuid?: UUID; } diff --git a/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx b/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx index dd8d026224..e7cd268ceb 100644 --- a/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx +++ b/src/components/graph/menus/network-modifications/network-modification-node-editor.tsx @@ -137,6 +137,11 @@ const isEditableModification = (modif: NetworkModificationMetadata) => { return !nonEditableModificationTypes.has(modif.type); }; +const emptyCopiedModificationsSelection = { + modificationsUuids: [], + copyInfos: null, +}; + const NetworkModificationNodeEditor = () => { const notificationIdList = useSelector((state: AppState) => state.notificationIdList); const studyUuid = useSelector((state: AppState) => state.studyUuid); @@ -181,6 +186,40 @@ const NetworkModificationNodeEditor = () => { const buttonAddRef = useRef(null); const [enableDeveloperMode] = useParameterState(PARAM_DEVELOPER_MODE); + const isInitiatingCopyTab = useRef(false); + + const [broadcastChannel] = useState(() => { + const broadcast = new BroadcastChannel('modificationsCopyChannel'); + broadcast.onmessage = (event) => { + console.info('message received from broadcast channel: ', event.data); + isInitiatingCopyTab.current = false; + if (JSON.stringify(emptyCopiedModificationsSelection) === JSON.stringify(event.data)) { + cleanClipboard(); + } else { + setCopiedModifications(event.data.modificationsUuids); + setCopyInfos({ + copyType: event.data.copyInfos.copyType, + originStudyUuid: event.data.copyInfos.originStudyUuid, + originNodeUuid: event.data.copyInfos.originNodeUuid, + }); + snackInfo({ messageId: 'CopiedModificationUpdateMessageFromAnotherStudy' }); + } + }; + return broadcast; + }); + + useEffect(() => { + //If the tab is closed we want to invalidate the copy on all tabs because we won't able to track the node modification + window.addEventListener('beforeunload', (event) => { + if (true === isInitiatingCopyTab.current) { + broadcastChannel.postMessage(emptyCopiedModificationsSelection); + snackInfo({ + messageId: 'CopiedModificationInvalidationMessageAfterTabClosure', + }); + } + }); + }, [broadcastChannel, snackInfo]); + const cleanClipboard = useCallback( (showSnackInfo: boolean = true) => { setCopyInfos(null); @@ -192,8 +231,12 @@ const NetworkModificationNodeEditor = () => { } return []; }); + if (true === isInitiatingCopyTab.current) { + broadcastChannel.postMessage(emptyCopiedModificationsSelection); + isInitiatingCopyTab.current = false; + } }, - [snackInfo] + [snackInfo, broadcastChannel] ); // TODO this is not complete. @@ -1032,17 +1075,28 @@ const NetworkModificationNodeEditor = () => { setCopiedModifications(selectedModificationsIds()); setCopyInfos({ copyType: NetworkModificationCopyType.MOVE, + originStudyUuid: studyUuid ?? undefined, originNodeUuid: currentNode?.id, }); - }, [currentNode?.id, selectedModificationsIds]); + }, [currentNode?.id, selectedModificationsIds, studyUuid]); const doCopyModifications = useCallback(() => { setCopiedModifications(selectedModificationsIds()); setCopyInfos({ copyType: NetworkModificationCopyType.COPY, + originStudyUuid: studyUuid ?? undefined, originNodeUuid: currentNode?.id, }); - }, [currentNode?.id, selectedModificationsIds]); + broadcastChannel.postMessage({ + modificationsUuids: selectedModificationsIds(), + copyInfos: { + copyType: NetworkModificationCopyType.COPY, + originStudyUuid: studyUuid, + originNodeUuid: currentNode?.id, + }, + }); + isInitiatingCopyTab.current = true; + }, [broadcastChannel, currentNode?.id, selectedModificationsIds, studyUuid]); const doPasteModifications = useCallback(() => { if (!copyInfos || !studyUuid || !currentNode?.id) { diff --git a/src/services/study/index.ts b/src/services/study/index.ts index 813df3b0a4..0a38b00434 100644 --- a/src/services/study/index.ts +++ b/src/services/study/index.ts @@ -216,7 +216,7 @@ export function fetchContingencyCount( export function copyOrMoveModifications( studyUuid: UUID, targetNodeId: UUID, - modificationToCutUuidList: string[], + modificationToCutUuidList: UUID[], copyInfos: NetworkModificationCopyInfo ) { console.info(copyInfos.copyType + ' modifications'); @@ -229,6 +229,7 @@ export function copyOrMoveModifications( '?' + new URLSearchParams({ action: copyInfos.copyType, + originStudyUuid: copyInfos.originStudyUuid ?? '', originNodeUuid: copyInfos.originNodeUuid ?? '', }); diff --git a/src/translations/en.json b/src/translations/en.json index 679eafc98f..cd1264809c 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -26,6 +26,9 @@ "CopiedNodeInvalidationMessage": "As a result of node modification, the contents of the clipboard have been deleted", "CopiedModificationInvalidationMessage": "Following a modification of the hypothesis, the content of the clipboard has been deleted", + "CopiedModificationInvalidationMessageFromAnotherStudy": "Following a change in the modifications in another study, the content of the clipboard has been deleted", + "CopiedModificationUpdateMessageFromAnotherStudy": "As a result of copying modifications from another study, the content of the clipboard has been updated", + "CopiedModificationInvalidationMessageAfterTabClosure": "As a result of closing the tab from another study, the content of the clipboard has been deleted", "exportNetwork": "Export the network", "export": "Export", "download.fileName": "File name", diff --git a/src/translations/fr.json b/src/translations/fr.json index 2eb0a9cd39..99944f20a0 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -26,6 +26,9 @@ "CopiedNodeInvalidationMessage": "Suite à modification de nœud, le contenu du presse papier a été supprimé", "CopiedModificationInvalidationMessage": "Suite à modification d'hypothèse, le contenu du presse papier a été supprimé", + "CopiedModificationInvalidationMessageFromAnotherStudy": "Suite à un changement des modifications dans une autre étude, le contenu du presse papier a été supprimé", + "CopiedModificationUpdateMessageFromAnotherStudy": "Suite à la copie de modifications dans une autre étude, le presse papier a été modifié", + "CopiedModificationInvalidationMessageAfterTabClosure": "Suite à la fermeture de l'onglet d'une autre étude, le presse papier a été supprimé", "exportNetwork": "Exporter le réseau", "export": "Exporter", "download.fileName": "Nom de fichier",