From 5b7bb5c93a4946fab72d997e7c92feec06fb661c Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 18 Aug 2026 17:33:27 +0200 Subject: [PATCH 1/4] Warn about shared elements in the delete confirmation dialog Display the sharing links of the selected elements in the deletion confirmation, so that permanently deleting an element used elsewhere is not done unknowingly. A single selected element gets a plain sentence, a multiple selection gets the list of the shared elements with their number of sharing links. Signed-off-by: Florent MILLOT --- src/components/dialogs/delete-dialog.tsx | 62 +++++++++++++++++++++++- src/translations/en.json | 3 ++ src/translations/fr.json | 3 ++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/components/dialogs/delete-dialog.tsx b/src/components/dialogs/delete-dialog.tsx index b58ba4da5..9ca5bad7e 100644 --- a/src/components/dialogs/delete-dialog.tsx +++ b/src/components/dialogs/delete-dialog.tsx @@ -4,9 +4,20 @@ * 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 { Alert, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle } from '@mui/material'; +import { + Alert, + Box, + Button, + CircularProgress, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + List, + ListItem, +} from '@mui/material'; import { FormattedMessage } from 'react-intl'; -import { type CSSProperties, type SyntheticEvent, useEffect, useRef, useState } from 'react'; +import { type CSSProperties, type SyntheticEvent, useEffect, useMemo, useRef, useState } from 'react'; import { CancelButton, type ElementAttributes, type MuiStyles, OverflowableText } from '@gridsuite/commons-ui'; export interface DeleteDialogProps { @@ -23,6 +34,14 @@ const styles = { tooltip: { maxWidth: '1000px', }, + sharedItemsList: { + listStyleType: 'disc', + marginTop: 0.5, + paddingLeft: 3, + }, + sharedItem: { + display: 'list-item', + }, } as const satisfies MuiStyles; /** @@ -50,6 +69,9 @@ export default function DeleteDialog({ const openRef = useRef(null); + // an element is shared as soon as another element references it, each reference being a "sharing link" + const sharedItems = useMemo(() => itemsState.filter((item) => (item.references?.length ?? 0) > 0), [itemsState]); + useEffect(() => { if ((open && !openRef.current) || error !== '') { setItemsState(items); @@ -104,6 +126,41 @@ export default function DeleteDialog({ /> )); + const buildSharedItems = () => { + if (sharedItems.length === 0) { + return false; + } + // a single shared element needs no list + if (sharedItems.length === 1) { + return ( + + + + ); + } + return ( + + + + {sharedItems.map((item) => ( + + + + + + + ))} + + + ); + }; + return ( @@ -111,6 +168,7 @@ export default function DeleteDialog({ {buildItemsToDeleteGrid(itemsState, multipleDeleteFormatMessageId, simpleDeleteFormatMessageId)} + {buildSharedItems()} {error !== '' && {error}} diff --git a/src/translations/en.json b/src/translations/en.json index a44ddad6a..edf7c11a4 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -51,6 +51,7 @@ "displaySharingLinks": "Display sharing links", "sharingLinksOf": "Sharing links of", "sharingLinksError": "An error occurred while fetching the sharing links", + "sharingLinksCount": "{count, plural, one {# sharing link} other {# sharing links}}", "path": "Path", "node": "Node", "createFolder": "Create folder", @@ -70,6 +71,8 @@ "deleteItemDialogMessage": "The selected item will be deleted permanently.", "deleteMultipleItemsDialogMessage": "All selected items will be deleted permanently.", "deleteDialogTitle": "Confirmation", + "deleteDialogSharedItemMessage": "This item is shared with {count, plural, one {# sharing link} other {# sharing links}}.", + "deleteDialogSharedItemsMessage": "Following items are shared:", "renameDirectoryDialogTitle": "Rename the folder", "edit": "Edit", "createNewContingencyList": "Create a contingency list", diff --git a/src/translations/fr.json b/src/translations/fr.json index 49a08f308..8c2ab42a7 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -50,6 +50,7 @@ "displaySharingLinks": "Voir les liens de partage", "sharingLinksOf": "Liens de partage de", "sharingLinksError": "Une erreur est survenue lors de la récupération des liens de partage", + "sharingLinksCount": "{count, plural, one {# lien de partage} other {# liens de partage}}", "path": "Chemin", "node": "Noeud", "createNewStudyFromImportedCase": "Créer étude", @@ -69,6 +70,8 @@ "deleteItemDialogMessage": "L'élement sélectionné va être supprimé définitivement.", "deleteMultipleItemsDialogMessage": "Tous les éléments sélectionnés vont être supprimés définitivement.", "deleteDialogTitle": "Confirmation", + "deleteDialogSharedItemMessage": "Cet élément est partagé avec {count, plural, one {# lien de partage} other {# liens de partage}}.", + "deleteDialogSharedItemsMessage": "Les éléments suivants sont partagés :", "renameDirectoryDialogTitle": "Renommer le dossier", "edit": "Modifier", "createNewContingencyList": "Créer une liste d'aléas", From e43000b27847c38c34e0644f24d8a0c004a9b6dd Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 18 Aug 2026 17:35:43 +0200 Subject: [PATCH 2/4] Disable the delete button when the selection holds shared elements Deleting an element still referenced elsewhere breaks the referencing elements, so the confirmation only informs about the sharing links and no longer allows the deletion. Signed-off-by: Florent MILLOT --- src/components/dialogs/delete-dialog.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/dialogs/delete-dialog.tsx b/src/components/dialogs/delete-dialog.tsx index 9ca5bad7e..ccc904c57 100644 --- a/src/components/dialogs/delete-dialog.tsx +++ b/src/components/dialogs/delete-dialog.tsx @@ -173,7 +173,13 @@ export default function DeleteDialog({ - From 12314b41130e3ee064536a2a0dff1f39f10cb6b4 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 18 Aug 2026 17:42:40 +0200 Subject: [PATCH 3/4] Fix typo in TODO comment within delete dialog component Signed-off-by: Florent MILLOT --- src/components/dialogs/delete-dialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dialogs/delete-dialog.tsx b/src/components/dialogs/delete-dialog.tsx index ccc904c57..b4154af97 100644 --- a/src/components/dialogs/delete-dialog.tsx +++ b/src/components/dialogs/delete-dialog.tsx @@ -176,7 +176,7 @@ export default function DeleteDialog({