diff --git a/src/components/directory-content.js b/src/components/directory-content.js
index 36339a71b..b8b9e124e 100644
--- a/src/components/directory-content.js
+++ b/src/components/directory-content.js
@@ -282,6 +282,15 @@ const DirectoryContent = () => {
};
/* User interactions */
+ const contextualMixPolicies = useMemo(
+ () => ({
+ BIG: 'GoogleMicrosoft', // if !selectedUuids.has(selected.Uuid) deselects selectedUuids
+ ALL: 'All', // union of activeElement.Uuid and selectedUuids (currently implemented)
+ }),
+ []
+ );
+ const contextualMixPolicy = contextualMixPolicies.ALL;
+
const onContextMenu = useCallback(
(event) => {
const element = currentChildren.find(
@@ -294,7 +303,34 @@ const DirectoryContent = () => {
if (element && element.uploading !== null) {
if (element.type !== 'DIRECTORY') {
- setActiveElement(element);
+ setActiveElement({
+ hasMetadata:
+ childrenMetadata[event.rowData.elementUuid] !==
+ undefined,
+ ...element,
+ });
+
+ if (contextualMixPolicy === contextualMixPolicies.BIG) {
+ // If some elements were already selected and the active element is not in them, we deselect the already selected elements.
+ if (
+ selectedUuids?.size &&
+ element?.elementUuid &&
+ !selectedUuids.has(element.elementUuid)
+ ) {
+ setSelectedUuids(new Set());
+ }
+ } else {
+ // If some elements were already selected, we add the active element to the selected list if not already in it.
+ if (
+ selectedUuids?.size &&
+ element?.elementUuid &&
+ !selectedUuids.has(element.elementUuid)
+ ) {
+ let updatedSelectedUuids = new Set(selectedUuids);
+ updatedSelectedUuids.add(element.elementUuid);
+ setSelectedUuids(updatedSelectedUuids);
+ }
+ }
}
setMousePosition({
mouseX: event.event.clientX + constants.HORIZONTAL_SHIFT,
@@ -309,7 +345,15 @@ const DirectoryContent = () => {
handleOpenDirectoryMenu(event);
}
},
- [currentChildren, dispatch, selectedDirectory]
+ [
+ currentChildren,
+ dispatch,
+ selectedDirectory,
+ selectedUuids,
+ contextualMixPolicies,
+ contextualMixPolicy,
+ childrenMetadata,
+ ]
);
const abbreviationFromUserName = (name) => {
@@ -728,60 +772,42 @@ const DirectoryContent = () => {
setSelectedUuids(new Set());
}, [handleError, currentChildren, currentChildrenRef]);
- const contextualMixPolicies = {
- BIG: 'GoogleMicrosoft', // if !selectedUuids.has(selected.Uuid) deselects selectedUuids
- ZIMBRA: 'Zimbra', // if !selectedUuids.has(selected.Uuid) just use activeElement
- ALL: 'All', // union of activeElement.Uuid and selectedUuids (actually implemented)
- };
- let contextualMixPolicy = contextualMixPolicies.ALL;
-
- const getSelectedChildren = (mayChange = false) => {
- let acc = [];
- let ctxtUuid = activeElement ? activeElement.elementUuid : null;
- if (activeElement) {
- acc.push(
- Object.assign(
- {
- subtype:
- childrenMetadata[activeElement.elementUuid]
- ?.subtype,
- },
- activeElement
- )
- );
- }
+ const getSelectedChildren = () => {
+ let selectedChildren = [];
+ if (currentChildren?.length > 0) {
+ // Adds the previously selected elements
+ if (selectedUuids?.size) {
+ selectedChildren = currentChildren
+ .filter(
+ (child) =>
+ selectedUuids.has(child.elementUuid) &&
+ child.elementUuid !== activeElement?.elementUuid
+ )
+ .map((child) => {
+ return {
+ subtype:
+ childrenMetadata[child.elementUuid]?.subtype,
+ hasMetadata:
+ childrenMetadata[child.elementUuid] !==
+ undefined,
+ ...child,
+ };
+ });
+ }
- if (selectedUuids && currentChildren) {
- if (
- contextualMixPolicy === contextualMixPolicies.ALL ||
- ctxtUuid === null ||
- selectedUuids.has(ctxtUuid)
- ) {
- acc = acc.concat(
- currentChildren
- .filter(
- (child) =>
- selectedUuids.has(child.elementUuid) &&
- child.elementUuid !== activeElement?.elementUuid
- )
- .map((child2) => {
- return Object.assign(
- {
- subtype:
- childrenMetadata[child2.elementUuid],
- },
- child2
- );
- })
- );
- } else if (
- mayChange &&
- contextualMixPolicy === contextualMixPolicies.BIG
- ) {
- setSelectedUuids(null);
+ // Adds the active element
+ if (activeElement) {
+ selectedChildren.push({
+ ...activeElement,
+ subtype:
+ childrenMetadata[activeElement.elementUuid]?.subtype,
+ hasMetadata:
+ childrenMetadata[activeElement.elementUuid] !==
+ undefined,
+ });
}
}
- return [...new Set(acc)];
+ return [...new Set(selectedChildren)];
};
const rows = useMemo(
diff --git a/src/components/menus/content-contextual-menu.js b/src/components/menus/content-contextual-menu.js
index dce8c73a0..b5ff2e54a 100644
--- a/src/components/menus/content-contextual-menu.js
+++ b/src/components/menus/content-contextual-menu.js
@@ -422,8 +422,8 @@ const ContentContextualMenu = (props) => {
false
);
- const isNotUploadingElement = useCallback(() => {
- return selectedElements.every((el) => !el.uploading);
+ const noCreationInProgress = useCallback(() => {
+ return selectedElements.every((el) => el.hasMetadata);
}, [selectedElements]);
// Allowance
@@ -434,14 +434,14 @@ const ContentContextualMenu = (props) => {
}, [selectedElements, userId]);
const allowsDelete = useCallback(() => {
- return isUserAllowed() && isNotUploadingElement();
- }, [isUserAllowed, isNotUploadingElement]);
+ return isUserAllowed() && noCreationInProgress();
+ }, [isUserAllowed, noCreationInProgress]);
const allowsRename = useCallback(() => {
return (
selectedElements.length === 1 &&
isUserAllowed() &&
- !selectedElements[0].uploading
+ selectedElements[0].hasMetadata
);
}, [isUserAllowed, selectedElements]);
@@ -449,21 +449,22 @@ const ContentContextualMenu = (props) => {
return (
selectedElements.every(
(element) =>
- element.type !== ElementType.DIRECTORY && !element.uploading
+ element.type !== ElementType.DIRECTORY &&
+ element.hasMetadata
) && isUserAllowed()
);
}, [isUserAllowed, selectedElements]);
const allowsDuplicate = useCallback(() => {
return (
+ selectedElements[0].hasMetadata &&
selectedElements.length === 1 &&
(selectedElements[0].type === ElementType.CASE ||
selectedElements[0].type === ElementType.STUDY ||
selectedElements[0].type === ElementType.CONTINGENCY_LIST ||
selectedElements[0].type === ElementType.FILTER ||
selectedElements[0].type ===
- ElementType.VOLTAGE_INIT_PARAMETERS) &&
- !selectedElements[0].uploading
+ ElementType.VOLTAGE_INIT_PARAMETERS)
);
}, [selectedElements]);
@@ -471,7 +472,7 @@ const ContentContextualMenu = (props) => {
return (
selectedElements.length === 1 &&
selectedElements[0].type === ElementType.CASE &&
- !selectedElements[0].uploading
+ selectedElements[0].hasMetadata
);
}, [selectedElements]);
@@ -496,10 +497,12 @@ const ContentContextualMenu = (props) => {
const allowsDownloadCase = useCallback(() => {
//if selectedElements contains at least one case
- return selectedElements.some(
- (element) => element.type === ElementType.CASE
+ return (
+ selectedElements.some(
+ (element) => element.type === ElementType.CASE
+ ) && noCreationInProgress()
);
- }, [selectedElements]);
+ }, [selectedElements, noCreationInProgress]);
const handleDownloadCases = useCallback(async () => {
const casesUuids = selectedElements
@@ -586,6 +589,7 @@ const ContentContextualMenu = (props) => {
icon: ,
});
}
+
if (allowsDownloadCase()) {
// is export allowed
menuItems.push({
@@ -612,9 +616,9 @@ const ContentContextualMenu = (props) => {
if (menuItems.length === 0) {
menuItems.push({
- messageDescriptorId: isNotUploadingElement()
+ messageDescriptorId: noCreationInProgress()
? 'notElementCreator'
- : 'uploadingElement',
+ : 'elementCreationInProgress',
icon: ,
disabled: true,
});
diff --git a/src/components/toolbars/content-toolbar.js b/src/components/toolbars/content-toolbar.js
index 44eba4fc8..5a19ce3d4 100644
--- a/src/components/toolbars/content-toolbar.js
+++ b/src/components/toolbars/content-toolbar.js
@@ -131,22 +131,32 @@ const ContentToolbar = (props) => {
[selectedElements, userId]
);
- const allowsDelete = useMemo(() => isUserAllowed, [isUserAllowed]);
+ const noCreationInProgress = useMemo(
+ () => selectedElements.every((el) => el.hasMetadata),
+ [selectedElements]
+ );
+
+ const allowsDelete = useMemo(
+ () => isUserAllowed && noCreationInProgress,
+ [isUserAllowed, noCreationInProgress]
+ );
const allowsMove = useMemo(
() =>
selectedElements.every(
(element) => element.type !== ElementType.DIRECTORY
- ) && isUserAllowed,
- [isUserAllowed, selectedElements]
+ ) &&
+ isUserAllowed &&
+ noCreationInProgress,
+ [isUserAllowed, selectedElements, noCreationInProgress]
);
const allowsDownloadCases = useMemo(
() =>
- selectedElements.every(
+ selectedElements.some(
(element) => element.type === ElementType.CASE
- ),
- [selectedElements]
+ ) && noCreationInProgress,
+ [selectedElements, noCreationInProgress]
);
const items = useMemo(
diff --git a/src/translations/en.json b/src/translations/en.json
index 2425bb95c..5448cfb80 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -212,7 +212,7 @@
"moveElementNotFoundError": "The element or the targeted folder was not found",
"moveElementNotAllowedError": "You cannot move this element to the targeted folder. Unauthorized action",
"notElementCreator": "You are not the element's creator",
- "uploadingElement": "Upload in progress: no operation permitted",
+ "elementCreationInProgress": "Creation in progress: no operation permitted",
"serverConnectionFailed": "Failed to connect to server. Please retry later.",
"invalidFormatOrName": "Imported file name or format invalid",
"parameterLoadingProblem": "problem of loading parameters",
diff --git a/src/translations/fr.json b/src/translations/fr.json
index 23b568608..0129f0905 100644
--- a/src/translations/fr.json
+++ b/src/translations/fr.json
@@ -212,7 +212,7 @@
"moveElementNotFoundError": "L'élément ou le dossier cible n'a pas été trouvé",
"moveElementNotAllowedError": "Vous ne pouvez pas déplacer cet élément dans le dossier cible. Action non autorisée",
"notElementCreator": "Vous n'êtes pas le créateur de l'élément",
- "uploadingElement": "Téléversement en cours : pas d'opération autorisée",
+ "elementCreationInProgress": "Création en cours : pas d'opération autorisée",
"serverConnectionFailed": "Échec de connexion avec le serveur. Veuillez réessayer ultérieurement",
"invalidFormatOrName": "Format ou nom du fichier importé non valide",
"parameterLoadingProblem": "Problème de chargement des paramètres",