diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index ad57dd355..4735dda13 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -84,6 +84,7 @@ Now it has been fixed in Sirius Web 2025.8.4, `SysONUpdateLibraryExecutor` has b - https://github.com/eclipse-syson/syson/issues/1545[#1545] [diagrams] Add _interconnection_ compartment to `PartDefinition` nodes in the standard diagrams. - https://github.com/eclipse-syson/syson/issues/1546[#1546] [diagrams] Fix drag and drop of a graphical node from the diagram background into a _Package_ graphical node. - https://github.com/eclipse-syson/syson/issues/1550[#1550] [diagrams] Fix an issue where the _action flow_ compartment was not revealed when the _New Start Action_ was executed. +- https://github.com/eclipse-syson/syson/issues/1547[#1547] [diagrams] Fix an issue where the _Delete from diagram_ action did nothing on elements inside a _Package_ in diagrams. === Improvements diff --git a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVViewUsageExposedElementsTests.java b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVViewUsageExposedElementsTests.java index 87c106e7f..77de02256 100644 --- a/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVViewUsageExposedElementsTests.java +++ b/backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVViewUsageExposedElementsTests.java @@ -13,6 +13,7 @@ package org.eclipse.syson.application.controllers.diagrams.general.view; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.sirius.components.diagrams.tests.DiagramEventPayloadConsumer.assertRefreshedDiagramThat; import static org.junit.jupiter.api.Assertions.assertEquals; import java.time.Duration; @@ -36,6 +37,7 @@ import org.eclipse.sirius.components.diagrams.Diagram; import org.eclipse.sirius.components.diagrams.Node; import org.eclipse.sirius.components.diagrams.tests.graphql.LayoutDiagramMutationRunner; +import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator; import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionInput; import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionRunner; import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionSuccessPayload; @@ -213,7 +215,7 @@ public void addExistingElementsToolShouldUpdateExposedElements() { this.verifier.then(semanticChecker); } - @DisplayName("GIVEN a GV diagram on a ViewUsage, WHEN Add existing element(s) (recursive) tool is executed, THEN a the ViewUsage#exposedElements is updated with partA and partB") + @DisplayName("GIVEN a GV diagram on a ViewUsage, WHEN Add existing element(s) (recursive) tool is executed, THEN the ViewUsage#exposedElements is updated with partA and partB") @Sql(scripts = { ViewUsageExposedElementsTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) @Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) @@ -303,4 +305,47 @@ public void updateExposedElementsShouldUpdateTheDiagram() { this.diagramCheckerService.checkDiagram(diagramChecker, this.diagram, this.verifier); } + + @DisplayName("GIVEN a GV diagram on a ViewUsage, WHEN an element is created inside a Package, THEN the element should only be visible inside the Package") + @Sql(scripts = { ViewUsageExposedElementsTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, + config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)) + @Test + public void exposePackageChildShouldDisplayChildOnlyinPAckage() { + var newPackageToolId = this.diagramDescriptionIdProvider.getDiagramCreationToolId("New Package"); + assertThat(newPackageToolId).as("The tool 'New Package' should exist on the diagram").isNotNull(); + var newInterfaceToolId = this.diagramDescriptionIdProvider.getNodeCreationToolId(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getPackage()), "New Interface"); + assertThat(newInterfaceToolId).as("The tool 'New Interface' should exist on the Package").isNotNull(); + + Runnable newPackageTool = () -> this.toolTester.invokeTool(ViewUsageExposedElementsTestProjectData.EDITING_CONTEXT_ID, this.diagram, newPackageToolId); + + var packageNodeId = new AtomicReference(); + + Consumer updatedDiagramWithPackage = assertRefreshedDiagramThat(diag -> { + int diagramRootNodesCount = diag.getNodes().size(); + assertThat(diagramRootNodesCount).isEqualTo(1); + var packageNode = new DiagramNavigator(diag).nodeWithLabel("Package1").getNode(); + assertThat(packageNode).isNotNull(); + assertThat(packageNode.getChildNodes()).hasSize(0); + packageNodeId.set(packageNode.getId()); + }); + + Runnable newInterfaceTool = () -> this.toolTester.invokeTool(ViewUsageExposedElementsTestProjectData.EDITING_CONTEXT_ID, this.diagram.get().getId(), packageNodeId.get(), newInterfaceToolId, + List.of()); + + Consumer updatedDiagramWithInterface = assertRefreshedDiagramThat(diag -> { + int diagramRootNodesCount = diag.getNodes().size(); + assertThat(diagramRootNodesCount).isEqualTo(1); + var packageNode = new DiagramNavigator(diag).nodeWithLabel("Package1").getNode(); + assertThat(packageNode.getChildNodes()).hasSize(1); + var interfaceNode = new DiagramNavigator(diag).nodeWithLabel("Package1").childNodeWithLabel("\u00ABinterface\u00BB\ninterface1").getNode(); + assertThat(interfaceNode).isNotNull(); + }); + + this.verifier + .then(newPackageTool) + .consumeNextWith(updatedDiagramWithPackage) + .then(newInterfaceTool) + .consumeNextWith(updatedDiagramWithInterface); + } } diff --git a/backend/services/syson-services/src/main/java/org/eclipse/syson/services/ToolService.java b/backend/services/syson-services/src/main/java/org/eclipse/syson/services/ToolService.java index 2e160cc7b..10a75aaf0 100644 --- a/backend/services/syson-services/src/main/java/org/eclipse/syson/services/ToolService.java +++ b/backend/services/syson-services/src/main/java/org/eclipse/syson/services/ToolService.java @@ -133,9 +133,6 @@ public Element expose(Element element, IEditingContext editingContext, DiagramCo var membershipExpose = SysmlFactory.eINSTANCE.createMembershipExpose(); membershipExpose.setImportedMembership(element.getOwningMembership()); viewUsage.getOwnedRelationship().add(membershipExpose); - if (element instanceof Package) { - membershipExpose.setIsRecursive(true); - } } } return element; diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java index 5b7d24660..7c40b35b2 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewNodeService.java @@ -56,6 +56,7 @@ import org.eclipse.syson.sysml.Type; import org.eclipse.syson.sysml.ViewDefinition; import org.eclipse.syson.sysml.ViewUsage; +import org.eclipse.syson.sysml.helper.EMFUtils; import org.eclipse.syson.sysml.util.ElementUtil; import org.eclipse.syson.util.NodeFinder; import org.slf4j.Logger; @@ -512,21 +513,21 @@ public boolean showAnnotatingNode(Element element, DiagramContext diagramContext */ protected Set getDirectExposedElements(ViewUsage viewUsage) { var directExposedElements = new HashSet(); - List exposes = viewUsage.getOwnedRelationship().stream() + List exposedElements = viewUsage.getOwnedRelationship().stream() .filter(Expose.class::isInstance) .map(Expose.class::cast) .toList(); - for (Expose expose : exposes) { - Element importedElement = expose.getImportedElement(); + for (Expose exposedElement : exposedElements) { + Element importedElement = exposedElement.getImportedElement(); if (importedElement instanceof Package) { directExposedElements.add(importedElement); - } else if (expose instanceof MembershipExpose membershipExpose) { + } else if (exposedElement instanceof MembershipExpose membershipExpose) { var importedMembership = membershipExpose.getImportedMembership(); if (importedMembership != null) { var memberElement = importedMembership.getMemberElement(); - if (memberElement != null) { + if (memberElement != null && !this.isChildOfExposedPackage(memberElement, exposedElements)) { directExposedElements.add(memberElement); - if (expose.isIsRecursive()) { + if (exposedElement.isIsRecursive()) { directExposedElements.addAll(this.getRecursiveContents(memberElement)); } } @@ -537,6 +538,29 @@ protected Set getDirectExposedElements(ViewUsage viewUsage) { return directExposedElements; } + /** + * Check if the given {@link Element} is a child of an exposed Package. In this case, we don't want to display it on + * the diagram background, or as a ViewUsage child node. It will be displayed inside another node. + * + * @param element + * the element that could be a child of an exposed element + * @param exposedElements + * the list of exposed elements + * @return true if the given {@link Element} is a child of an exposed element, false + * otherwise. + */ + protected boolean isChildOfExposedPackage(Element element, List exposedElements) { + boolean isChildOfExposedElement = false; + for (Expose exposedElement : exposedElements) { + Element importedElement = exposedElement.getImportedElement(); + if (importedElement instanceof Package && !Objects.equals(element, importedElement) && EMFUtils.isAncestor(importedElement, element)) { + isChildOfExposedElement = true; + break; + } + } + return isChildOfExposedElement; + } + protected List getRecursiveContents(Element element) { var contents = new ArrayList(); var ownedElements = element.getOwnedElement().stream().filter(Objects::nonNull).toList(); diff --git a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java index f0279c2ee..117ee54de 100644 --- a/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java +++ b/backend/views/syson-diagram-common-view/src/main/java/org/eclipse/syson/diagram/common/view/services/ViewToolService.java @@ -154,7 +154,7 @@ public Element addToExposedElements(Element element, boolean recursive, IEditing var membershipExpose = SysmlFactory.eINSTANCE.createMembershipExpose(); membershipExpose.setImportedMembership(childElement.getOwningMembership()); viewUsage.getOwnedRelationship().add(membershipExpose); - if (childElement instanceof Package || recursive) { + if (recursive) { membershipExpose.setIsRecursive(true); } } diff --git a/doc/content/modules/user-manual/pages/release-notes/2025.10.0.adoc b/doc/content/modules/user-manual/pages/release-notes/2025.10.0.adoc index 9ce82c83c..c785a79ea 100644 --- a/doc/content/modules/user-manual/pages/release-notes/2025.10.0.adoc +++ b/doc/content/modules/user-manual/pages/release-notes/2025.10.0.adoc @@ -75,6 +75,7 @@ Now it is only available on SysML model elements. - Fix an issue where diagrams' edges were blinking when refreshing a diagram. - Fix drag and drop of a graphical node from the diagram background into a _Package_ graphical node. - Fix an issue where the _action flow_ compartment was not revealed when the _New Start Action_ was executed. +- Fix an issue where the _Delete from diagram_ action did nothing on elements inside a _Package_ in diagrams. == Improvements