Skip to content

Commit

Permalink
[4037] Add support for actions in tree item menu
Browse files Browse the repository at this point in the history
Bug: #4037
Signed-off-by: Jerome Gout <[email protected]>
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
jerome-obeo authored and frouene committed Oct 3, 2024
1 parent e2d6de5 commit 145456f
Show file tree
Hide file tree
Showing 80 changed files with 6,025 additions and 811 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The new option ALWAYS allows the separator to be displayed in every case.
- https://github.com/eclipse-sirius/sirius-web/issues/3678[#3678] [core] Remove `IRepresentationMetadataSearchService#findByRepresentation`, use `IRepresentationMetadataSearchService#findByRepresentationId` instead.
- https://github.com/eclipse-sirius/sirius-web/issues/4050[#4050] [sirius-web] `IUploadFileLoader` must now return an `IResult`.
This allows an error to be displayed when there is a problem during uploading

- https://github.com/eclipse-sirius/sirius-web/issues/4037[#4037] [trees] The tree item id passed to `ITreeQueryService.findTreeItem` is no longer a UUID but is now a String.

=== Dependency update

Expand Down Expand Up @@ -92,6 +92,7 @@ never, always and if_children (to display the separator only if children exist).
- https://github.com/eclipse-sirius/sirius-web/issues/3961[#3961] [sirius-web] Extend the explorer to support multiple presentations
- https://github.com/eclipse-sirius/sirius-web/issues/3856[#3856] [trees] Add tree representation in the view DSL
- https://github.com/eclipse-sirius/sirius-web/issues/4000[#4000] [trees] Add support for styled labels in view model for trees
- https://github.com/eclipse-sirius/sirius-web/issues/4037[#4037] [trees] Add mechanism to define actions in tree item context menu

== v2024.9.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ private TreeDescription getModelBrowserDescription(String descriptionId, Functio
.treeItemObjectProvider(this::getTreeItemObject)
.parentObjectProvider(this::getParentObject)
.treeItemLabelProvider(this::getLabel)
.contextMenuEntries(List.of())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,13 @@ private String getResourceLabel(Resource resource) {
.orElse(resource.getURI().lastSegment());
}

public Object toggleAbstractEntity(Object self) {
if (self instanceof Entity entity) {
entity.setAbstract(!entity.isAbstract());
}
return self;
}

/**
* Wrapper for {@link org.eclipse.emf.ecore.EStructuralFeature.Setting} to avoid AQL interpreter sees this element as an list.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.eclipse.sirius.web.application.studio.services.representations;

import java.util.List;
import java.util.Objects;
import java.util.UUID;

Expand All @@ -27,7 +28,9 @@
import org.eclipse.sirius.components.view.builder.generated.tree.TreeBuilders;
import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders;
import org.eclipse.sirius.components.view.emf.tree.ITreeIdProvider;
import org.eclipse.sirius.components.view.tree.FetchTreeItemContextMenuEntryKind;
import org.eclipse.sirius.components.view.tree.TreeDescription;
import org.eclipse.sirius.components.view.tree.TreeItemContextMenuEntry;
import org.eclipse.sirius.components.view.tree.TreeItemLabelDescription;
import org.eclipse.sirius.components.view.tree.TreeItemLabelElementDescription;
import org.eclipse.sirius.emfjson.resource.JsonResource;
Expand Down Expand Up @@ -55,8 +58,12 @@ public class DomainViewTreeDescriptionProvider implements IEditingContextProcess

private static final String AQL_TRUE = "aql:true";

private static final String AQL_SELF_IS_AN_ENTITY = "aql:self.oclIsKindOf(domain::Entity)";

private final IStudioCapableEditingContextPredicate studioCapableEditingContextPredicate;

private final ViewBuilders viewBuilderHelper = new ViewBuilders();

private final View view;

private final ITreeIdProvider treeIdProvider;
Expand Down Expand Up @@ -123,6 +130,7 @@ private TreeDescription domainExplorerDescription(TextStylePalette domainTextSty
.treeItemObjectExpression("aql:editingContext.getTreeItemObject(id)")
.preconditionExpression("aql:false") // -> set canCreate to false to avoid to be display in New representation menu
.treeItemLabelDescriptions(this.entityStyle(domainTextStylePalette), this.attributeStyle(domainTextStylePalette), this.defaultStyle())
.contextMenuEntries(this.getContextMenuEntries().toArray(TreeItemContextMenuEntry[] ::new))
.build();
return this.viewDescription;
}
Expand All @@ -149,7 +157,7 @@ private TreeItemLabelDescription entityStyle(TextStylePalette textStylePalette)
return new TreeBuilders()
.newTreeItemLabelDescription()
.name("entity style")
.preconditionExpression("aql:self.oclIsKindOf(domain::Entity)")
.preconditionExpression(AQL_SELF_IS_AN_ENTITY)
.children(this.getEntityKeyFragment(textStylePalette), this.getEntityValueFragment(textStylePalette))
.build();
}
Expand Down Expand Up @@ -224,4 +232,24 @@ private TextStyleDescription getTextStyleByName(TextStylePalette textStylePalett
.findFirst()
.orElse(null);
}

private List<TreeItemContextMenuEntry> getContextMenuEntries() {
var callService = this.viewBuilderHelper.newChangeContext()
.expression("aql:self.toggleAbstractEntity()");

var helpMenuEntry = new TreeBuilders().newFetchTreeItemContextMenuEntry()
.labelExpression("Help")
.iconURLExpression("/img/DefaultEdgeIcon.svg")
.preconditionExpression(AQL_SELF_IS_AN_ENTITY)
.urlExression("https://eclipse.dev/sirius/sirius-web.html")
.kind(FetchTreeItemContextMenuEntryKind.OPEN)
.build();
var toggleAbstractMenuEntry = new TreeBuilders().newSingleClickTreeItemContextMenuEntry()
.labelExpression("Toggle abstract")
.preconditionExpression(AQL_SELF_IS_AN_ENTITY)
.body(callService.build())
.build();

return List.of(helpMenuEntry, toggleAbstractMenuEntry);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
.renameHandler(this::getRenameHandler)
.treeItemObjectProvider(this::getTreeItemObject)
.treeItemLabelProvider(this::getLabel)
.contextMenuEntries(List.of())
.build();
return List.of(explorerTreeDescription);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
.canCreatePredicate(variableManager -> false)
.targetObjectIdProvider(variableManager -> variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class).map(IEditingContext::getId).orElse(null))
.elementsProvider(this::getElements)
.contextMenuEntries(List.of())
.build();

return List.of(explorerDescription);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
.deleteHandler(variableManager -> new Success())
.renameHandler((variableManager, newName) -> new Success())
.treeItemObjectProvider(this::getTreeItemObject)
.contextMenuEntries(List.of())
.build();
return List.of(treeDescription);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2024 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.tests.graphql;

import java.util.Map;
import java.util.Objects;

import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor;
import org.eclipse.sirius.components.graphql.tests.api.IQueryRunner;
import org.springframework.stereotype.Service;

/**
* Used to get the list of actions in the context menu of a tree item from the GraphQL API.
*
* @author Jerome Gout
*/
@Service
public class FetchTreeItemContextMenuEntryDataQueryRunner implements IQueryRunner {

private static final String TREE_ITEM_CONTEXT_MENU_QUERY = """
query getFetchTreeItemContextMenuEntryDataQuery(
$editingContextId: ID!
$representationId: ID!
$treeItemId: ID!
$menuEntryId: ID!
) {
viewer {
editingContext(editingContextId: $editingContextId) {
representation(representationId: $representationId) {
description {
... on TreeDescription {
fetchTreeItemContextMenuEntryData(treeItemId: $treeItemId, menuEntryId: $menuEntryId) {
urlToFetch
fetchKind
}
}
}
}
}
}
}
""";

private final IGraphQLRequestor graphQLRequestor;

public FetchTreeItemContextMenuEntryDataQueryRunner(IGraphQLRequestor graphQLRequestor) {
this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor);
}

@Override
public String run(Map<String, Object> variables) {
return this.graphQLRequestor.execute(TREE_ITEM_CONTEXT_MENU_QUERY, variables);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2024 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.tests.graphql;

import java.util.Map;
import java.util.Objects;

import org.eclipse.sirius.components.collaborative.trees.dto.InvokeSingleClickTreeItemContextMenuEntryInput;
import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor;
import org.eclipse.sirius.components.graphql.tests.api.IMutationRunner;
import org.springframework.stereotype.Service;

/**
* Used to execute a single click context menu entry with the GraphQL API.
*
* @author Jerome Gout
*/
@Service
public class SingleClickTreeItemContextMenuEntryMutationRunner implements IMutationRunner<InvokeSingleClickTreeItemContextMenuEntryInput> {

private static final String INVOKE_SINGLE_CLICK_CONTEXT_MENU_ENTRY = """
mutation invokeSingleClickTreeItemContextMenuEntry($input: InvokeSingleClickTreeItemContextMenuEntryInput!) {
invokeSingleClickTreeItemContextMenuEntry(input: $input) {
__typename
... on ErrorPayload {
message
}
}
}
""";

private final IGraphQLRequestor graphQLRequestor;

public SingleClickTreeItemContextMenuEntryMutationRunner(IGraphQLRequestor graphQLRequestor) {
this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor);
}

@Override
public String run(InvokeSingleClickTreeItemContextMenuEntryInput input) {
Map<String, Object> inputMap = Map.of(
"id", input.id(),
"editingContextId", input.editingContextId(),
"representationId", input.representationId(),
"treeItemId", input.treeItemId(),
"menuEntryId", input.menuEntryId()
);
Map<String, Object> variables = Map.of("input", inputMap);
return this.graphQLRequestor.execute(INVOKE_SINGLE_CLICK_CONTEXT_MENU_ENTRY, variables);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2024 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.tests.graphql;

import java.util.Map;
import java.util.Objects;

import org.eclipse.sirius.components.graphql.tests.api.IGraphQLRequestor;
import org.eclipse.sirius.components.graphql.tests.api.IQueryRunner;
import org.springframework.stereotype.Service;

/**
* Used to get the list of actions in the context menu of a tree item from the GraphQL API.
*
* @author Jerome Gout
*/
@Service
public class TreeItemContextMenuQueryRunner implements IQueryRunner {

private static final String TREE_ITEM_CONTEXT_MENU_QUERY = """
query getAllContextMenuActions($editingContextId: ID!, $representationId: ID!, $treeItemId: ID!) {
viewer {
editingContext(editingContextId: $editingContextId) {
representation(representationId: $representationId) {
description {
... on TreeDescription {
contextMenu(treeItemId: $treeItemId) {
__typename
id
label
iconURL
}
}
}
}
}
}
}
""";

private final IGraphQLRequestor graphQLRequestor;

public TreeItemContextMenuQueryRunner(IGraphQLRequestor graphQLRequestor) {
this.graphQLRequestor = Objects.requireNonNull(graphQLRequestor);
}

@Override
public String run(Map<String, Object> variables) {
return this.graphQLRequestor.execute(TREE_ITEM_CONTEXT_MENU_QUERY, variables);
}
}
Loading

0 comments on commit 145456f

Please sign in to comment.