Skip to content

Commit 9cd9848

Browse files
authored
Copy paste network modifications from different studies (#3357)
Permits to copy and paste network modifications from one study to antoher one
1 parent 775cc4e commit 9cd9848

File tree

5 files changed

+66
-4
lines changed

5 files changed

+66
-4
lines changed

src/components/graph/menus/network-modifications/network-modification-menu.type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export enum NetworkModificationCopyType {
5454

5555
export interface NetworkModificationCopyInfo {
5656
copyType: NetworkModificationCopyType;
57+
originStudyUuid?: UUID;
5758
originNodeUuid?: UUID;
5859
}
5960

src/components/graph/menus/network-modifications/network-modification-node-editor.tsx

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ const isEditableModification = (modif: NetworkModificationMetadata) => {
137137
return !nonEditableModificationTypes.has(modif.type);
138138
};
139139

140+
const emptyCopiedModificationsSelection = {
141+
modificationsUuids: [],
142+
copyInfos: null,
143+
};
144+
140145
const NetworkModificationNodeEditor = () => {
141146
const notificationIdList = useSelector((state: AppState) => state.notificationIdList);
142147
const studyUuid = useSelector((state: AppState) => state.studyUuid);
@@ -181,6 +186,40 @@ const NetworkModificationNodeEditor = () => {
181186
const buttonAddRef = useRef<HTMLButtonElement>(null);
182187
const [enableDeveloperMode] = useParameterState(PARAM_DEVELOPER_MODE);
183188

189+
const isInitiatingCopyTab = useRef(false);
190+
191+
const [broadcastChannel] = useState(() => {
192+
const broadcast = new BroadcastChannel('modificationsCopyChannel');
193+
broadcast.onmessage = (event) => {
194+
console.info('message received from broadcast channel: ', event.data);
195+
isInitiatingCopyTab.current = false;
196+
if (JSON.stringify(emptyCopiedModificationsSelection) === JSON.stringify(event.data)) {
197+
cleanClipboard();
198+
} else {
199+
setCopiedModifications(event.data.modificationsUuids);
200+
setCopyInfos({
201+
copyType: event.data.copyInfos.copyType,
202+
originStudyUuid: event.data.copyInfos.originStudyUuid,
203+
originNodeUuid: event.data.copyInfos.originNodeUuid,
204+
});
205+
snackInfo({ messageId: 'CopiedModificationUpdateMessageFromAnotherStudy' });
206+
}
207+
};
208+
return broadcast;
209+
});
210+
211+
useEffect(() => {
212+
//If the tab is closed we want to invalidate the copy on all tabs because we won't able to track the node modification
213+
window.addEventListener('beforeunload', (event) => {
214+
if (true === isInitiatingCopyTab.current) {
215+
broadcastChannel.postMessage(emptyCopiedModificationsSelection);
216+
snackInfo({
217+
messageId: 'CopiedModificationInvalidationMessageAfterTabClosure',
218+
});
219+
}
220+
});
221+
}, [broadcastChannel, snackInfo]);
222+
184223
const cleanClipboard = useCallback(
185224
(showSnackInfo: boolean = true) => {
186225
setCopyInfos(null);
@@ -192,8 +231,12 @@ const NetworkModificationNodeEditor = () => {
192231
}
193232
return [];
194233
});
234+
if (true === isInitiatingCopyTab.current) {
235+
broadcastChannel.postMessage(emptyCopiedModificationsSelection);
236+
isInitiatingCopyTab.current = false;
237+
}
195238
},
196-
[snackInfo]
239+
[snackInfo, broadcastChannel]
197240
);
198241

199242
// TODO this is not complete.
@@ -1032,17 +1075,28 @@ const NetworkModificationNodeEditor = () => {
10321075
setCopiedModifications(selectedModificationsIds());
10331076
setCopyInfos({
10341077
copyType: NetworkModificationCopyType.MOVE,
1078+
originStudyUuid: studyUuid ?? undefined,
10351079
originNodeUuid: currentNode?.id,
10361080
});
1037-
}, [currentNode?.id, selectedModificationsIds]);
1081+
}, [currentNode?.id, selectedModificationsIds, studyUuid]);
10381082

10391083
const doCopyModifications = useCallback(() => {
10401084
setCopiedModifications(selectedModificationsIds());
10411085
setCopyInfos({
10421086
copyType: NetworkModificationCopyType.COPY,
1087+
originStudyUuid: studyUuid ?? undefined,
10431088
originNodeUuid: currentNode?.id,
10441089
});
1045-
}, [currentNode?.id, selectedModificationsIds]);
1090+
broadcastChannel.postMessage({
1091+
modificationsUuids: selectedModificationsIds(),
1092+
copyInfos: {
1093+
copyType: NetworkModificationCopyType.COPY,
1094+
originStudyUuid: studyUuid,
1095+
originNodeUuid: currentNode?.id,
1096+
},
1097+
});
1098+
isInitiatingCopyTab.current = true;
1099+
}, [broadcastChannel, currentNode?.id, selectedModificationsIds, studyUuid]);
10461100

10471101
const doPasteModifications = useCallback(() => {
10481102
if (!copyInfos || !studyUuid || !currentNode?.id) {

src/services/study/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ export function fetchContingencyCount(
216216
export function copyOrMoveModifications(
217217
studyUuid: UUID,
218218
targetNodeId: UUID,
219-
modificationToCutUuidList: string[],
219+
modificationToCutUuidList: UUID[],
220220
copyInfos: NetworkModificationCopyInfo
221221
) {
222222
console.info(copyInfos.copyType + ' modifications');
@@ -229,6 +229,7 @@ export function copyOrMoveModifications(
229229
'?' +
230230
new URLSearchParams({
231231
action: copyInfos.copyType,
232+
originStudyUuid: copyInfos.originStudyUuid ?? '',
232233
originNodeUuid: copyInfos.originNodeUuid ?? '',
233234
});
234235

src/translations/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
"CopiedNodeInvalidationMessage": "As a result of node modification, the contents of the clipboard have been deleted",
2828
"CopiedModificationInvalidationMessage": "Following a modification of the hypothesis, the content of the clipboard has been deleted",
29+
"CopiedModificationInvalidationMessageFromAnotherStudy": "Following a change in the modifications in another study, the content of the clipboard has been deleted",
30+
"CopiedModificationUpdateMessageFromAnotherStudy": "As a result of copying modifications from another study, the content of the clipboard has been updated",
31+
"CopiedModificationInvalidationMessageAfterTabClosure": "As a result of closing the tab from another study, the content of the clipboard has been deleted",
2932
"exportNetwork": "Export the network",
3033
"export": "Export",
3134
"download.fileName": "File name",

src/translations/fr.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
"CopiedNodeInvalidationMessage": "Suite à modification de nœud, le contenu du presse papier a été supprimé",
2828
"CopiedModificationInvalidationMessage": "Suite à modification d'hypothèse, le contenu du presse papier a été supprimé",
29+
"CopiedModificationInvalidationMessageFromAnotherStudy": "Suite à un changement des modifications dans une autre étude, le contenu du presse papier a été supprimé",
30+
"CopiedModificationUpdateMessageFromAnotherStudy": "Suite à la copie de modifications dans une autre étude, le presse papier a été modifié",
31+
"CopiedModificationInvalidationMessageAfterTabClosure": "Suite à la fermeture de l'onglet d'une autre étude, le presse papier a été supprimé",
2932
"exportNetwork": "Exporter le réseau",
3033
"export": "Exporter",
3134
"download.fileName": "Nom de fichier",

0 commit comments

Comments
 (0)