Skip to content

Commit

Permalink
[822] Add a DeleteFromDiagram tool in the contextual palette
Browse files Browse the repository at this point in the history
Bug: #822
Signed-off-by: Axel RICHARD <axel.richard@obeo.fr>
Signed-off-by: Stéphane Bégaudeau <stephane.begaudeau@obeo.fr>
  • Loading branch information
sbegaudeau committed Jan 14, 2022
1 parent 469e984 commit 2b298bd
Show file tree
Hide file tree
Showing 12 changed files with 191 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public final class DeleteFromDiagramInput implements IDiagramInput {

private List<String> edgeIds;

private DeletionPolicy deletionPolicy;

@Override
@GraphQLID
@GraphQLField
Expand Down Expand Up @@ -75,9 +77,13 @@ public String getRepresentationId() {
return this.edgeIds;
}

public DeletionPolicy getDeletionPolicy() {
return this.deletionPolicy;
}

@Override
public String toString() {
String pattern = "{0} '{'id: {1}, editingContextId: {2}, representationId: {3}'}'"; //$NON-NLS-1$
return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.id, this.editingContextId, this.representationId);
String pattern = "{0} '{'id: {1}, editingContextId: {2}, representationId: {3}, deletionPolicy: {4}'}'"; //$NON-NLS-1$
return MessageFormat.format(pattern, this.getClass().getSimpleName(), this.id, this.editingContextId, this.representationId, this.deletionPolicy);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2022 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.web.spring.collaborative.diagrams.dto;

/**
* Used to indicate if an element should be deleted semantically or graphically.
*
* @author sbegaudeau
*/
public enum DeletionPolicy {
SEMANTIC, GRAPHICAL
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.eclipse.sirius.web.spring.collaborative.diagrams.api.IDiagramQueryService;
import org.eclipse.sirius.web.spring.collaborative.diagrams.dto.DeleteFromDiagramInput;
import org.eclipse.sirius.web.spring.collaborative.diagrams.dto.DeleteFromDiagramSuccessPayload;
import org.eclipse.sirius.web.spring.collaborative.diagrams.dto.DeletionPolicy;
import org.eclipse.sirius.web.spring.collaborative.diagrams.messages.ICollaborativeDiagramMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -60,6 +61,8 @@
@Service
public class DeleteFromDiagramEventHandler implements IDiagramEventHandler {

public static final String DELETION_POLICY = "deletionPolicy"; //$NON-NLS-1$

private final IObjectService objectService;

private final IDiagramQueryService diagramQueryService;
Expand Down Expand Up @@ -115,7 +118,7 @@ private void handleDelete(One<IPayload> payloadSink, Many<ChangeDescription> cha
for (String edgeId : diagramInput.getEdgeIds()) {
var optionalElement = this.diagramQueryService.findEdgeById(diagram, edgeId);
if (optionalElement.isPresent()) {
IStatus status = this.invokeDeleteEdgeTool(optionalElement.get(), editingContext, diagramContext);
IStatus status = this.invokeDeleteEdgeTool(optionalElement.get(), editingContext, diagramContext, diagramInput.getDeletionPolicy());
if (status instanceof Success) {
atLeastOneOk = true;
} else {
Expand All @@ -129,7 +132,7 @@ private void handleDelete(One<IPayload> payloadSink, Many<ChangeDescription> cha
for (String nodeId : diagramInput.getNodeIds()) {
var optionalElement = this.diagramQueryService.findNodeById(diagram, nodeId);
if (optionalElement.isPresent()) {
IStatus status = this.invokeDeleteNodeTool(optionalElement.get(), editingContext, diagramContext);
IStatus status = this.invokeDeleteNodeTool(optionalElement.get(), editingContext, diagramContext, diagramInput.getDeletionPolicy());
if (status instanceof Success) {
atLeastOneOk = true;
} else {
Expand Down Expand Up @@ -168,7 +171,7 @@ private void sendResponse(One<IPayload> payloadSink, Many<ChangeDescription> cha
changeDescriptionSink.tryEmitNext(changeDescription);
}

private IStatus invokeDeleteNodeTool(Node node, IEditingContext editingContext, IDiagramContext diagramContext) {
private IStatus invokeDeleteNodeTool(Node node, IEditingContext editingContext, IDiagramContext diagramContext, DeletionPolicy deletionPolicy) {
IStatus result = new Failure(""); //$NON-NLS-1$
var optionalNodeDescription = this.findNodeDescription(node, diagramContext.getDiagram(), editingContext);

Expand All @@ -179,6 +182,8 @@ private IStatus invokeDeleteNodeTool(Node node, IEditingContext editingContext,
variableManager.put(VariableManager.SELF, optionalSelf.get());
variableManager.put(IDiagramContext.DIAGRAM_CONTEXT, diagramContext);
variableManager.put(Node.SELECTED_NODE, node);
variableManager.put(DELETION_POLICY, deletionPolicy);

NodeDescription nodeDescription = optionalNodeDescription.get();
this.logger.debug("Deleted diagram element {}", node.getId()); //$NON-NLS-1$
result = nodeDescription.getDeleteHandler().apply(variableManager);
Expand All @@ -195,7 +200,7 @@ private IStatus invokeDeleteNodeTool(Node node, IEditingContext editingContext,
return result;
}

private IStatus invokeDeleteEdgeTool(Edge edge, IEditingContext editingContext, IDiagramContext diagramContext) {
private IStatus invokeDeleteEdgeTool(Edge edge, IEditingContext editingContext, IDiagramContext diagramContext, DeletionPolicy deletionPolicy) {
IStatus result = new Failure(""); //$NON-NLS-1$
var optionalEdgeDescription = this.findEdgeDescription(edge, diagramContext.getDiagram(), editingContext);
if (optionalEdgeDescription.isPresent()) {
Expand All @@ -204,6 +209,8 @@ private IStatus invokeDeleteEdgeTool(Edge edge, IEditingContext editingContext,
VariableManager variableManager = new VariableManager();
variableManager.put(VariableManager.SELF, optionalSelf.get());
variableManager.put(IDiagramContext.DIAGRAM_CONTEXT, diagramContext);
variableManager.put(DELETION_POLICY, deletionPolicy);

// @formatter:off
this.diagramQueryService.findNodeById(diagramContext.getDiagram(), edge.getSourceId())
.flatMap(node -> this.objectService.getObject(editingContext, node.getTargetObjectId()))
Expand All @@ -212,6 +219,7 @@ private IStatus invokeDeleteEdgeTool(Edge edge, IEditingContext editingContext,
.flatMap(node -> this.objectService.getObject(editingContext, node.getTargetObjectId()))
.ifPresent(semanticElement -> variableManager.put(EdgeDescription.SEMANTIC_EDGE_TARGET, semanticElement));
// @formatter:on

EdgeDescription edgeDescription = optionalEdgeDescription.get();
this.logger.debug("Deleted diagram edge {}", edge.getId()); //$NON-NLS-1$
result = edgeDescription.getDeleteHandler().apply(variableManager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,12 @@ input DeleteFromDiagramInput {
representationId: ID!
nodeIds: [ID!]!
edgeIds: [ID!]!
deletionPolicy: DeletionPolicy!
}

enum DeletionPolicy {
SEMANTIC
GRAPHICAL
}

union DeleteFromDiagramPayload = ErrorPayload | DeleteFromDiagramSuccessPayload
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/diagram/DiagramWebSocketContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ServerContext } from 'common/ServerContext';
import {
CreateEdgeTool,
CreateNodeTool,
GQLDeletionPolicy,
GQLDiagramDescription,
GQLDiagramEventPayload,
GQLDiagramEventSubscription,
Expand Down Expand Up @@ -75,7 +76,6 @@ import {
} from 'diagram/operations';
import { ContextualMenu } from 'diagram/palette/ContextualMenu';
import { ContextualPalette } from 'diagram/palette/ContextualPalette';
import { Node } from 'diagram/sprotty/Diagram.types';
import {
DiagramServer,
HIDE_CONTEXTUAL_TOOLBAR_ACTION,
Expand Down Expand Up @@ -313,6 +313,7 @@ export const DiagramWebSocketContainer = ({
displayedRepresentationId,
diagramServer,
diagram,
diagramDescription,
toolSections,
contextualPalette,
contextualMenu,
Expand Down Expand Up @@ -437,7 +438,7 @@ export const DiagramWebSocketContainer = ({
}, [dispatch]);

const deleteElements = useCallback(
(diagramElements) => {
(diagramElements: SModelElement[], deletionPolicy: GQLDeletionPolicy): void => {
const edgeIds = diagramElements.filter((diagramElement) => diagramElement instanceof SEdge).map((elt) => elt.id);
const nodeIds = diagramElements.filter((diagramElement) => diagramElement instanceof SNode).map((elt) => elt.id);

Expand All @@ -447,6 +448,7 @@ export const DiagramWebSocketContainer = ({
representationId,
nodeIds,
edgeIds,
deletionPolicy,
};
deleteElementsMutation({ variables: { input } });
resetTools();
Expand Down Expand Up @@ -569,19 +571,18 @@ export const DiagramWebSocketContainer = ({
const { id, label, kind } = selectedElement as any; // (as any) to be removed when the proper type will be available
newSelection.entries.push({ id, label, kind });
} else if (selectedElement instanceof SNode || selectedElement instanceof SEdge) {
const { id, targetObjectId, targetObjectKind, targetObjectLabel } = selectedElement as any; // (as any) to be removed when the proper type will be available
const { id, kind, targetObjectId, targetObjectKind, targetObjectLabel } = selectedElement as any; // (as any) to be removed when the proper type will be available

const semanticSelectionEntry: SelectionEntry = {
id: targetObjectId,
label: targetObjectLabel,
kind: targetObjectKind,
};

const type = selectedElement instanceof Node ? 'Node' : 'Edge';
const graphicalSelectionEntry: SelectionEntry = {
id,
label: '',
kind: `siriusComponents://graphical?representationType=Diagram&type=${type}`,
kind,
};

newSelection.entries.push(semanticSelectionEntry);
Expand Down Expand Up @@ -930,7 +931,8 @@ export const DiagramWebSocketContainer = ({
}
let invokeDeleteFromContextualPalette;
if (deletable) {
invokeDeleteFromContextualPalette = () => deleteElements([element]);
invokeDeleteFromContextualPalette = (deletionPolicy: GQLDeletionPolicy) =>
deleteElements([element], deletionPolicy);
}
const invokeToolFromContextualPalette = (tool) => {
if (tool.__typename === 'CreateEdgeTool') {
Expand Down Expand Up @@ -999,6 +1001,7 @@ export const DiagramWebSocketContainer = ({
contextualPaletteContent = (
<div className={classes.contextualPalette} style={style}>
<ContextualPalette
diagramDescription={diagramDescription}
toolSections={toolSections}
targetElement={element}
invokeTool={invokeToolFromContextualPalette}
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/diagram/DiagramWebSocketContainer.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,8 @@ export interface GQLTool {
label: string;
imageURL: string;
}

export enum GQLDeletionPolicy {
SEMANTIC = 'SEMANTIC',
GRAPHICAL = 'GRAPHICAL',
}
Loading

0 comments on commit 2b298bd

Please sign in to comment.