Skip to content

Commit a85a012

Browse files
mcharfadiAxelRICHARD
authored andcommitted
[1363] Add a menu action that will hide empty compartments.
Bug: #1363 Signed-off-by: Michaël Charfadi <michael.charfadi@obeosoft.com>
1 parent 305bdf3 commit a85a012

File tree

8 files changed

+400
-1
lines changed

8 files changed

+400
-1
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ All existing SysON _DiagramDescriptions_ (i.g. _General View_, _Interconnection
9898
- https://github.com/eclipse-syson/syson/issues/1310[#1310] [metamodel] Revert remove derived flag for `ViewUsage#exposedElement` feature.
9999
- https://github.com/eclipse-syson/syson/issues/1359[#1359] [export] Implement textual export of `ViewUsage`.
100100
- https://github.com/eclipse-syson/syson/issues/1350[#1350] [general-view] Improve _direct edit_ tool on `Feature` to be able to edit `FeatureValue` with basic expressions.
101+
- https://github.com/eclipse-syson/syson/issues/1363[#1363] [general-view] Add a reveal only valued content action on the manage visibility node action that will hide empty graphical compartments and will reveal the others.
101102

102103
=== New features
103104

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.controllers.diagrams.general.view;
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
import static org.assertj.core.api.Assertions.fail;
16+
17+
import com.jayway.jsonpath.JsonPath;
18+
19+
import java.time.Duration;
20+
import java.util.List;
21+
import java.util.Map;
22+
import java.util.Optional;
23+
import java.util.UUID;
24+
import java.util.concurrent.atomic.AtomicReference;
25+
import java.util.function.Consumer;
26+
27+
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput;
28+
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload;
29+
import org.eclipse.sirius.components.collaborative.diagrams.dto.managevisibility.InvokeManageVisibilityActionInput;
30+
import org.eclipse.sirius.components.core.api.SuccessPayload;
31+
import org.eclipse.sirius.components.diagrams.ViewModifier;
32+
import org.eclipse.sirius.components.diagrams.tests.graphql.GetManageVisibilityActionsQueryRunner;
33+
import org.eclipse.sirius.components.diagrams.tests.graphql.InvokeManageVisibilityActionMutationRunner;
34+
import org.eclipse.sirius.web.application.nodeaction.managevisibility.ManageVisibilityHideAllAction;
35+
import org.eclipse.sirius.web.application.nodeaction.managevisibility.ManageVisibilityRevealAllAction;
36+
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
37+
import org.eclipse.syson.AbstractIntegrationTests;
38+
import org.eclipse.syson.application.data.GeneralViewManageVisibilityTestsProjectData;
39+
import org.eclipse.syson.diagram.general.view.services.nodeactions.managevisibility.GeneralViewManageVisibilityRevealValuedContentAction;
40+
import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription;
41+
import org.junit.jupiter.api.BeforeEach;
42+
import org.junit.jupiter.api.DisplayName;
43+
import org.junit.jupiter.api.Test;
44+
import org.springframework.beans.factory.annotation.Autowired;
45+
import org.springframework.boot.test.context.SpringBootTest;
46+
import org.springframework.test.context.jdbc.Sql;
47+
import org.springframework.test.context.jdbc.SqlConfig;
48+
import org.springframework.transaction.annotation.Transactional;
49+
50+
import reactor.core.publisher.Flux;
51+
import reactor.test.StepVerifier;
52+
53+
/**
54+
* Tests the manage visibility node action.
55+
*
56+
* @author mcharfadi
57+
*/
58+
@Transactional
59+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
60+
public class GVManageVisibilityTests extends AbstractIntegrationTests {
61+
62+
@Autowired
63+
private IGivenInitialServerState givenInitialServerState;
64+
65+
@Autowired
66+
private IGivenDiagramSubscription givenDiagramSubscription;
67+
68+
@Autowired
69+
private GetManageVisibilityActionsQueryRunner getActionsQueryRunner;
70+
71+
@Autowired
72+
private InvokeManageVisibilityActionMutationRunner invokeActionMutationRunner;
73+
74+
@BeforeEach
75+
public void setUp() {
76+
this.givenInitialServerState.initialize();
77+
}
78+
79+
private Flux<DiagramRefreshedEventPayload> givenSubscriptionToGeneralViewDiagram() {
80+
var diagramEventInput = new DiagramEventInput(
81+
UUID.randomUUID(),
82+
GeneralViewManageVisibilityTestsProjectData.EDITING_CONTEXT_ID,
83+
GeneralViewManageVisibilityTestsProjectData.GraphicalIds.DIAGRAM_ID);
84+
return this.givenDiagramSubscription.subscribe(diagramEventInput);
85+
}
86+
87+
@Sql(scripts = { GeneralViewManageVisibilityTestsProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
88+
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
89+
@Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
90+
@DisplayName("GIVEN a graphical node with some children hidden and some revealed, WHEN invoking the show valued content only, THEN only the children that have children are visible")
91+
@Test
92+
public void invokeShowOnlyValuedContent() {
93+
var flux = this.givenSubscriptionToGeneralViewDiagram();
94+
var nodeId = new AtomicReference<String>();
95+
Consumer<DiagramRefreshedEventPayload> initialDiagramContentConsumer = payload -> Optional.of(payload)
96+
.ifPresentOrElse(diagramRefreshedEventPayload -> {
97+
var diagram = diagramRefreshedEventPayload.diagram();
98+
assertThat(diagram.getNodes()).hasSize(1);
99+
nodeId.set(diagram.getNodes().get(0).getId());
100+
assertThat(diagram.getNodes().get(0).getChildNodes()).hasSize(5);
101+
var children = diagram.getNodes().get(0).getChildNodes();
102+
assertThat(children.stream().filter(node -> node.getState().equals(ViewModifier.Hidden))).hasSize(5);
103+
assertThat(children.stream().filter(node -> node.getState().equals(ViewModifier.Normal))).hasSize(0);
104+
}, () -> fail("Missing diagram"));
105+
106+
Runnable getActions = () -> {
107+
Map<String, Object> variables = Map.of(
108+
"editingContextId", GeneralViewManageVisibilityTestsProjectData.EDITING_CONTEXT_ID,
109+
"diagramId", GeneralViewManageVisibilityTestsProjectData.GraphicalIds.DIAGRAM_ID,
110+
"diagramElementId", nodeId.get()
111+
);
112+
var result = this.getActionsQueryRunner.run(variables);
113+
List<String> actionsIds = JsonPath.read(result, "$.data.viewer.editingContext.representation.description.manageVisibilityActions[*].id");
114+
List<String> actionsLabels = JsonPath.read(result, "$.data.viewer.editingContext.representation.description.manageVisibilityActions[*].label");
115+
116+
assertThat(actionsIds)
117+
.isNotEmpty()
118+
.contains(ManageVisibilityRevealAllAction.ACTION_ID)
119+
.contains(ManageVisibilityHideAllAction.ACTION_ID)
120+
.contains(GeneralViewManageVisibilityRevealValuedContentAction.ACTION_ID);
121+
122+
assertThat(actionsLabels)
123+
.isNotEmpty()
124+
.contains("Hide all")
125+
.contains("Reveal all")
126+
.contains("Reveal valued content only");
127+
};
128+
129+
Runnable invokeRevealValuedContentAction = () -> {
130+
var input = new InvokeManageVisibilityActionInput(UUID.randomUUID(), GeneralViewManageVisibilityTestsProjectData.EDITING_CONTEXT_ID, GeneralViewManageVisibilityTestsProjectData.GraphicalIds.DIAGRAM_ID, nodeId.get(), GeneralViewManageVisibilityRevealValuedContentAction.ACTION_ID);
131+
var result = this.invokeActionMutationRunner.run(input);
132+
String typename = JsonPath.read(result, "$.data.invokeManageVisibilityAction.__typename");
133+
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
134+
};
135+
136+
Consumer<DiagramRefreshedEventPayload> updatedAfterRevealDiagramContentMatcher = payload -> Optional.of(payload)
137+
.ifPresentOrElse(diagramRefreshedEventPayload -> {
138+
var diagram = diagramRefreshedEventPayload.diagram();
139+
assertThat(diagram.getNodes()).hasSize(1);
140+
nodeId.set(diagram.getNodes().get(0).getId());
141+
assertThat(diagram.getNodes().get(0).getChildNodes()).hasSize(5);
142+
var children = diagram.getNodes().get(0).getChildNodes();
143+
assertThat(children.stream().filter(node -> node.getState().equals(ViewModifier.Hidden))).hasSize(3);
144+
assertThat(children.stream().filter(node -> node.getState().equals(ViewModifier.Normal))).hasSize(1);
145+
assertThat(children.stream().filter(node -> node.getState().equals(ViewModifier.Faded))).hasSize(1);
146+
}, () -> fail("Missing diagram"));
147+
148+
StepVerifier.create(flux)
149+
.consumeNextWith(initialDiagramContentConsumer)
150+
.then(getActions)
151+
.then(invokeRevealValuedContentAction)
152+
.consumeNextWith(updatedAfterRevealDiagramContentMatcher)
153+
.thenCancel()
154+
.verify(Duration.ofSeconds(10));
155+
}
156+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.application.data;
14+
15+
/**
16+
* Project data for the "GVManageVisibilityTests" project.
17+
*
18+
* @author mcharfadi
19+
*/
20+
public class GeneralViewManageVisibilityTestsProjectData {
21+
22+
public static final String SCRIPT_PATH = "/scripts/database-content/GeneralView-ManageVisibility.sql";
23+
24+
public static final String EDITING_CONTEXT_ID = "b01d9a82-7f04-46f9-9b49-d69b291ae105";
25+
26+
/**
27+
* Ids of graphical elements.
28+
*/
29+
public static class GraphicalIds {
30+
31+
public static final String DIAGRAM_ID = "621aded7-5bd5-4966-9526-7ff0816dbb63";
32+
33+
}
34+
}

backend/application/syson-application/src/test/resources/scripts/database-content/GeneralView-ManageVisibility.sql

Lines changed: 94 additions & 0 deletions
Large diffs are not rendered by default.

backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/GeneralViewManageVisibilityNodeActionProvider.java renamed to backend/views/syson-diagram-general-view/src/main/java/org/eclipse/syson/diagram/general/view/services/nodeactions/managevisibility/GeneralViewManageVisibilityNodeActionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Contributors:
1111
* Obeo - initial API and implementation
1212
*******************************************************************************/
13-
package org.eclipse.syson.diagram.general.view.services;
13+
package org.eclipse.syson.diagram.general.view.services.nodeactions.managevisibility;
1414

1515
import org.eclipse.emf.ecore.EClass;
1616
import org.eclipse.emf.ecore.EObject;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.diagram.general.view.services.nodeactions.managevisibility;
14+
15+
import org.eclipse.sirius.components.collaborative.diagrams.api.nodeactions.IManageVisibilityMenuActionProvider;
16+
import org.eclipse.sirius.components.collaborative.diagrams.dto.managevisibility.ManageVisibilityAction;
17+
import org.eclipse.sirius.components.core.api.IEditingContext;
18+
import org.eclipse.sirius.components.diagrams.IDiagramElement;
19+
import org.eclipse.sirius.components.diagrams.Node;
20+
import org.eclipse.sirius.components.diagrams.description.DiagramDescription;
21+
import org.springframework.stereotype.Service;
22+
23+
import java.util.List;
24+
25+
/**
26+
* Menu action on the manage visibility modal that will reveal children that also have children.
27+
*
28+
* @author mcharfadi
29+
*/
30+
@Service
31+
public class GeneralViewManageVisibilityRevealValuedContentAction implements IManageVisibilityMenuActionProvider {
32+
33+
public static final String ACTION_ID = "manage_visibility_menu_reveal_valued_content_action";
34+
35+
@Override
36+
public boolean canHandle(IEditingContext editingContext, DiagramDescription diagramDescription, IDiagramElement diagramElement) {
37+
return diagramElement instanceof Node node && !node.getChildNodes().isEmpty();
38+
}
39+
40+
@Override
41+
public List<ManageVisibilityAction> handle(IEditingContext editingContext, DiagramDescription diagramDescription, IDiagramElement diagramElement) {
42+
return List.of(new ManageVisibilityAction(ACTION_ID, "Reveal valued content only"));
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Obeo.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Obeo - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.syson.diagram.general.view.services.nodeactions.managevisibility;
14+
15+
import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramContext;
16+
import org.eclipse.sirius.components.collaborative.diagrams.api.IDiagramQueryService;
17+
import org.eclipse.sirius.components.collaborative.diagrams.api.nodeactions.IManageVisibilityMenuActionHandler;
18+
import org.eclipse.sirius.components.core.api.IEditingContext;
19+
import org.eclipse.sirius.components.diagrams.IDiagramElement;
20+
import org.eclipse.sirius.components.diagrams.Node;
21+
import org.eclipse.sirius.components.diagrams.events.HideDiagramElementEvent;
22+
import org.eclipse.sirius.components.representations.IStatus;
23+
import org.eclipse.sirius.components.representations.Success;
24+
import org.springframework.stereotype.Service;
25+
26+
import java.util.HashSet;
27+
import java.util.Objects;
28+
import java.util.Optional;
29+
import java.util.Set;
30+
31+
/**
32+
* Handler for the menu action on the manage visibility modal that will reveal children that also have children.
33+
*
34+
* @author mcharfadi
35+
*/
36+
@Service
37+
public class GeneralViewManageVisibilityRevealValuedContentHandler implements IManageVisibilityMenuActionHandler {
38+
39+
private final IDiagramQueryService diagramQueryService;
40+
41+
public GeneralViewManageVisibilityRevealValuedContentHandler(IDiagramQueryService diagramQueryService) {
42+
this.diagramQueryService = Objects.requireNonNull(diagramQueryService);
43+
}
44+
45+
@Override
46+
public boolean canHandle(IEditingContext editingContext, IDiagramContext diagramContext, IDiagramElement diagramElement, String actionId) {
47+
return actionId.equals(GeneralViewManageVisibilityRevealValuedContentAction.ACTION_ID);
48+
}
49+
50+
@Override
51+
public IStatus handle(IEditingContext editingContext, IDiagramContext diagramContext, IDiagramElement diagramElement, String actionId) {
52+
Optional<Node> optionalNode = this.diagramQueryService.findNodeById(diagramContext.getDiagram(), diagramElement.getId());
53+
Set<String> nodesToReveal = new HashSet<>();
54+
Set<String> nodesToHide = new HashSet<>();
55+
if (optionalNode.isPresent()) {
56+
optionalNode.get().getChildNodes().forEach(node -> {
57+
if (node.getChildNodes().isEmpty()) {
58+
nodesToHide.add(node.getId());
59+
} else {
60+
nodesToReveal.add(node.getId());
61+
}
62+
});
63+
diagramContext.getDiagramEvents().add(new HideDiagramElementEvent(nodesToReveal, false));
64+
diagramContext.getDiagramEvents().add(new HideDiagramElementEvent(nodesToHide, true));
65+
}
66+
return new Success();
67+
}
68+
69+
}

doc/content/modules/user-manual/pages/release-notes/2025.6.0.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ image::view-usage-graphical-contents.png[ViewUsage graphical contents, width=65%
6060

6161
- `ManageVisibility` node action may now be displayed from the _General View_ on `Definition` and `Usage` graphical nodes.
6262
This node action open a modal that can be used to reveal or hide the graphical node children's.
63+
Menu actions can be used to `reveal all content`, `reveal valued content only` or `hide all content`.
6364

6465
image::release-notes-manage-visibility.png[Manage Visibility modal, width=65%,height=65%]
6566

0 commit comments

Comments
 (0)