Skip to content

Commit e17a530

Browse files
pcdavidgcoutable
authored andcommitted
[3486] Do not open delete confirmation dialog when a node/edge is not deletable
Bug: #3486 Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
1 parent a5733b5 commit e17a530

File tree

31 files changed

+193
-70
lines changed

31 files changed

+193
-70
lines changed

CHANGELOG.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
Tools are no longer converted with the diagram.
2424
You can use `IViewToolFinder` to find a node or edge tool in a view dsl.
2525
`IToolDiagramExecutor` has been rename to `ISingleClickOnOneDiagramElementHandler` and `ISingleClickOnTwoDiagramElementHandler` has been added, these interface are used to execute a tool from the `InvokeSingleClickOnDiagramElementToolEventHandler` and `InvokeSingleClickOnTwoDiagramElementsToolEventHandler`
26+
- https://github.com/eclipse-sirius/sirius-web/issues/3486[#3486] Nodes and edges have a new `deletable` attribute in the GraphQL Schema that custom nodes must consider in their converter.
27+
On the backend, the node and edge's `deleteHandler` can now be `null` if no semantic deletion tool is defined for this element.
28+
`IViewNodeDeleteHandler`, which only existed to provide a non-null handler able to tell if there was a semantic deletion tool, has been removed.
2629

2730

2831
=== Dependency update
@@ -60,6 +63,7 @@ Downstream applications can now implement the following interfaces:
6063
* `IIndexDeletionServiceDelegate` to customize how indexes are deleted
6164
* `IIndexUpdateServiceDelegate` to customize how the content of the indices is updated
6265
Sirius Web provides a default implementation for all these services, which creates an index per editing context, and indexes all the features of the elements in the editing context (this can be customized by implementing `IIndexEntryProviderDelegate`).
66+
- https://github.com/eclipse-sirius/sirius-web/issues/3486[#3486] [diagram] Do not open delete confirmation dialog when a node/edge is not deletable
6367

6468

6569

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
14+
import { expect, test } from '@playwright/test';
15+
import { PlaywrightExplorer } from '../helpers/PlaywrightExplorer';
16+
import { PlaywrightProject } from '../helpers/PlaywrightProject';
17+
18+
test.describe('delete node without delete tool', () => {
19+
let projectId;
20+
test.beforeEach(async ({ page, request }) => {
21+
await new PlaywrightProject(request).uploadProject(page, 'papayaBasicClassDiagram.zip');
22+
23+
await page.evaluate(() => {
24+
window.localStorage.removeItem('sirius-confirmation-dialog-disabled');
25+
});
26+
});
27+
28+
test.afterEach(async ({ request }) => {
29+
await new PlaywrightProject(request).deleteProject(projectId);
30+
});
31+
32+
test("when hitting 'Del' on a node with no configured delete tool, no confirmation popup is shown ", async ({
33+
page,
34+
}) => {
35+
let requestTriggered = false;
36+
page.on('request', (request) => {
37+
if (
38+
request.url().includes('api/graphql') &&
39+
request.method() === 'POST' &&
40+
JSON.parse(request.postData()).operationName === 'deleteFromDiagram'
41+
) {
42+
requestTriggered = true;
43+
}
44+
});
45+
46+
// Open the diagram
47+
const playwrightExplorer = new PlaywrightExplorer(page);
48+
await playwrightExplorer.expand('Papaya');
49+
await playwrightExplorer.expand('Project');
50+
await playwrightExplorer.expand('Component');
51+
await playwrightExplorer.select('Component class diagram');
52+
53+
await expect(page.getByTestId('rf__wrapper')).toBeVisible();
54+
55+
// Select the semantic in the explorer
56+
await playwrightExplorer.expand('package');
57+
await playwrightExplorer.select('Class');
58+
// And the corresponding node on the diagram
59+
await page.getByTestId('diagram-reveal-selection').click();
60+
61+
// Try do delete from the keyboard
62+
await page.keyboard.press('Delete');
63+
// No dialog should open
64+
await expect(page.getByTestId('confirmation-dialog')).not.toBeVisible();
65+
// And no mutation invoked
66+
expect(requestTriggered).toBe(false);
67+
});
68+
});
Binary file not shown.

packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/resources/schema/diagram.graphqls

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type Node {
115115
defaultWidth: Int
116116
defaultHeight: Int
117117
labelEditable: Boolean!
118+
deletable: Boolean!
118119
customizedStyleProperties: [NodeStyleProperty!]!
119120
initialBorderNodePosition: BorderNodePosition!
120121
}
@@ -301,6 +302,7 @@ type Edge {
301302
state: ViewModifier!
302303
style: EdgeStyle!
303304
centerLabelEditable: Boolean!
305+
deletable: Boolean!
304306
customizedStyleProperties: [EdgeStyleProperty!]!
305307
}
306308

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/Edge.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public final class Edge implements IDiagramElement {
6767

6868
private boolean centerLabelEditable;
6969

70+
private boolean deletable;
71+
7072
private Set<String> customizedStyleProperties;
7173

7274
private Edge() {
@@ -145,6 +147,10 @@ public boolean isCenterLabelEditable() {
145147
return this.centerLabelEditable;
146148
}
147149

150+
public boolean isDeletable() {
151+
return this.deletable;
152+
}
153+
148154
public Set<String> getCustomizedStyleProperties() {
149155
return this.customizedStyleProperties;
150156
}
@@ -194,6 +200,8 @@ public static final class Builder {
194200

195201
private boolean centerLabelEditable;
196202

203+
private boolean deletable;
204+
197205
private Set<String> customizedStyleProperties;
198206

199207
private Builder(String id) {
@@ -216,6 +224,7 @@ private Builder(Edge edge) {
216224
this.state = edge.getState();
217225
this.style = edge.getStyle();
218226
this.centerLabelEditable = edge.isCenterLabelEditable();
227+
this.deletable = edge.isDeletable();
219228
this.customizedStyleProperties = edge.getCustomizedStyleProperties();
220229
}
221230

@@ -289,6 +298,11 @@ public Builder centerLabelEditable(boolean centerLabelEditable) {
289298
return this;
290299
}
291300

301+
public Builder deletable(boolean deletable) {
302+
this.deletable = deletable;
303+
return this;
304+
}
305+
292306
public Builder customizedStyleProperties(Set<String> customizedStyleProperties) {
293307
this.customizedStyleProperties = Objects.requireNonNull(customizedStyleProperties);
294308
return this;
@@ -311,6 +325,7 @@ public Edge build() {
311325
edge.state = Objects.requireNonNull(this.state);
312326
edge.style = Objects.requireNonNull(this.style);
313327
edge.centerLabelEditable = this.centerLabelEditable;
328+
edge.deletable = this.deletable;
314329
edge.customizedStyleProperties = Objects.requireNonNull(this.customizedStyleProperties);
315330
return edge;
316331
}

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/Node.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public final class Node implements IDiagramElement {
7070

7171
private boolean labelEditable;
7272

73+
private boolean deletable;
74+
7375
private boolean pinned;
7476

7577
private Set<String> customizedStyleProperties;
@@ -180,6 +182,10 @@ public boolean isLabelEditable() {
180182
return this.labelEditable;
181183
}
182184

185+
public boolean isDeletable() {
186+
return this.deletable;
187+
}
188+
183189
public boolean isPinned() {
184190
return this.pinned;
185191
}
@@ -245,6 +251,8 @@ public static final class Builder {
245251

246252
private boolean labelEditable;
247253

254+
private boolean deletable;
255+
248256
private boolean pinned;
249257

250258
private Set<String> customizedStyleProperties;
@@ -273,6 +281,7 @@ private Builder(Node node) {
273281
this.defaultWidth = node.getDefaultWidth();
274282
this.defaultHeight = node.getDefaultHeight();
275283
this.labelEditable = node.isLabelEditable();
284+
this.deletable = node.isDeletable();
276285
this.pinned = node.isPinned();
277286
this.customizedStyleProperties = node.getCustomizedStyleProperties();
278287
}
@@ -367,6 +376,11 @@ public Builder labelEditable(boolean labelEditable) {
367376
return this;
368377
}
369378

379+
public Builder deletable(boolean deletable) {
380+
this.deletable = deletable;
381+
return this;
382+
}
383+
370384
public Builder pinned(boolean pinned) {
371385
this.pinned = pinned;
372386
return this;
@@ -398,9 +412,11 @@ public Node build() {
398412
node.defaultWidth = this.defaultWidth; // Optional on purpose
399413
node.defaultHeight = this.defaultHeight; // Optional on purpose
400414
node.labelEditable = this.labelEditable;
415+
node.deletable = this.deletable;
401416
node.pinned = this.pinned;
402417
node.customizedStyleProperties = Objects.requireNonNull(this.customizedStyleProperties);
403418
return node;
404419
}
405420
}
406421
}
422+

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/EdgeComponent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ private Optional<Element> doRenderEdge(VariableManager edgeVariableManager, Edge
207207
.style(appearance.style())
208208
.children(labelChildren)
209209
.centerLabelEditable(edgeDescription.getLabelEditHandler() != null)
210+
.deletable(edgeDescription.getDeleteHandler() != null)
210211
.customizedStyleProperties(appearance.customizedStyleProperties())
211212
.build();
212213

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/components/NodeComponent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ private Element doRender(VariableManager nodeVariableManager, String targetObjec
223223
.defaultWidth(defaultWidth)
224224
.defaultHeight(defaultHeight)
225225
.labelEditable(nodeDescription.getLabelEditHandler() != null)
226+
.deletable(nodeDescription.getDeleteHandler() != null)
226227
.customizedStyleProperties(appearance.customizedStyleProperties())
227228
.build();
228229

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/description/EdgeDescription.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ public EdgeDescription build() {
318318
edgeDescription.sourceProvider = Objects.requireNonNull(this.sourceProvider);
319319
edgeDescription.targetProvider = Objects.requireNonNull(this.targetProvider);
320320
edgeDescription.styleProvider = Objects.requireNonNull(this.styleProvider);
321-
edgeDescription.deleteHandler = Objects.requireNonNull(this.deleteHandler);
321+
edgeDescription.deleteHandler = this.deleteHandler; // Optional on purpose
322322
edgeDescription.labelEditHandler = this.labelEditHandler; // Optional on purpose
323323
return edgeDescription;
324324
}

packages/diagrams/backend/sirius-components-diagrams/src/main/java/org/eclipse/sirius/components/diagrams/description/NodeDescription.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ public NodeDescription build() {
559559
nodeDescription.reusedBorderNodeDescriptionIds = Objects.requireNonNull(this.reusedBorderNodeDescriptionIds);
560560
nodeDescription.reusedChildNodeDescriptionIds = Objects.requireNonNull(this.reusedChildNodeDescriptionIds);
561561
nodeDescription.labelEditHandler = this.labelEditHandler; // Optional on purpose
562-
nodeDescription.deleteHandler = Objects.requireNonNull(this.deleteHandler);
562+
nodeDescription.deleteHandler = this.deleteHandler; // Optional on purpose
563563
nodeDescription.dropNodeHandler = this.dropNodeHandler; // Optional on purpose.
564564
nodeDescription.keepAspectRatio = this.keepAspectRatio;
565565
nodeDescription.isCollapsedByDefaultPredicate = Objects.requireNonNull(this.isCollapsedByDefaultPredicate);

0 commit comments

Comments
 (0)