Skip to content

Commit

Permalink
[3983] Add drag and drop support for explorer
Browse files Browse the repository at this point in the history
Bug: #3983
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
frouene committed Sep 24, 2024
1 parent 5f2fdc1 commit d6d0c0a
Show file tree
Hide file tree
Showing 24 changed files with 928 additions and 29 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ Both `IInput` and `IDomainEvent` implement `ICause` and will thus be used to ind
- https://github.com/eclipse-sirius/sirius-web/issues/3972[#3972] [diagram] The `InsideLabelStyle#displayHeaderSeparator` has been renamed to `headerSeparatorDisplayMode` and is no longer a boolean but an enum with three possible values: NEVER, ALWAYS, and IF-CHILDREN.
Previously, the value false was equivalent to NEVER, and true to IF-CHILDREN.
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/3678[#3678] [core] Remove `IRepresentationMetadataSearchService#findByRepresentation`, use `IRepresentationMetadataSearchService#findByRepresentationId` instead.
- https://github.com/eclipse-sirius/sirius-web/issues/3983[#3983] [trees] The `TreeDescription` must now implement a `dropTreeItemHandler`.

=== Dependency update

Expand All @@ -53,12 +54,14 @@ The new option ALWAYS allows the separator to be displayed in every case.
- https://github.com/eclipse-sirius/sirius-web/issues/3763[#3763] [diagram] Make it possible to display semantic candidates in the selection dialog using a tree
- https://github.com/eclipse-sirius/sirius-web/issues/3979[#3979] [core] Add Project related REST APIs.
The new endpoints are:
** getProjects (`GET /api/rest/projects`): Get all projects.
** getProjects (`GET /api/rest/projects`): Get all projects.
** getProjectById (`GET /api/rest/projects/{projectId}`): Get project with the given id (projectId).
** createProject (`POST /projects`): Create a new project with the given name and
description (optional).
** deleteProject (`POST /api/rest/projects/{projectId}`): Delete the project with the given id (projectId).
** updateProject (`PUT /projects/{projectId}`): Update the project with the given id (projectId).
- https://github.com/eclipse-sirius/sirius-web/issues/3983[#3983] [trees] Add drag and drop support for explorer


=== Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.eclipse.sirius.components.representations.GetOrCreateRandomIdProvider;
import org.eclipse.sirius.components.representations.IRepresentationDescription;
import org.eclipse.sirius.components.representations.IStatus;
import org.eclipse.sirius.components.representations.Success;
import org.eclipse.sirius.components.representations.VariableManager;
import org.eclipse.sirius.components.trees.description.TreeDescription;
import org.eclipse.sirius.components.trees.renderer.TreeRenderer;
Expand Down Expand Up @@ -139,6 +140,7 @@ private TreeDescription getModelBrowserDescription(String descriptionId, Functio
.renameHandler(this::getRenameHandler)
.treeItemObjectProvider(this::getTreeItemObject)
.parentObjectProvider(this::getParentObject)
.dropTreeItemHandler(variableManager -> new Success())
.build();
}

Expand Down Expand Up @@ -278,8 +280,7 @@ private StyledString getLabel(VariableManager variableManager) {
StyledString styledString = this.objectService.getStyledLabel(self);
if (!styledString.toString().isBlank()) {
return styledString;
}
else {
} else {
var kind = this.objectService.getKind(self);
label = this.urlParser.getParameterValues(kind).get(SemanticKindConstants.ENTITY_ARGUMENT).get(0);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*******************************************************************************
* 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.application.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ResourceBundleMessageSource;

/**
* Configuration used to retrieve the message source accessor for the project.
*
* @author frouene
*/
@Configuration
public class SiriusWebMessageServiceConfiguration {

private static final String PATH = "messages/sirius-web-application";

@Bean
public MessageSourceAccessor siriusWebApplicationMessageSourceAccessor() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.addBasenames(PATH);
return new MessageSourceAccessor(messageSource);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* 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.application.messages;

/**
* Interface of the sirius web message service.
*
* @author frouene
*/
public interface ISiriusWebMessageService {

String unavailableFeature();

String alreadySetFeature();

/**
* Implementation which does nothing, used for mocks in unit tests.
*
* @author frouene
*/
class NoOp implements ISiriusWebMessageService {

@Override
public String unavailableFeature() {
return "";
}

@Override
public String alreadySetFeature() {
return "";
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*******************************************************************************
* 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.application.messages;

/**
* This class is used to hold all the keys of the internationalization messages.
*
* @author frouene
*/
public final class MessageConstants {

public static final String UNAVAILABLE_FEATURE = "UNAVAILABLE_FEATURE";

public static final String ALREADY_SET_FEATURE = "ALREADY_SET_FEATURE";

private MessageConstants() {
// Prevent instantiation
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* 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.application.messages;

import java.util.Objects;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.stereotype.Service;

/**
* Implementation of the sirius web message service.
*
* @author frouene
*/
@Service
public class SiriusWebMessageService implements ISiriusWebMessageService {

private final MessageSourceAccessor messageSourceAccessor;

public SiriusWebMessageService(@Qualifier("siriusWebApplicationMessageSourceAccessor") MessageSourceAccessor messageSourceAccessor) {
this.messageSourceAccessor = Objects.requireNonNull(messageSourceAccessor);
}

@Override
public String unavailableFeature() {
return this.messageSourceAccessor.getMessage(MessageConstants.UNAVAILABLE_FEATURE, new Object[] {});
}

@Override
public String alreadySetFeature() {
return this.messageSourceAccessor.getMessage(MessageConstants.ALREADY_SET_FEATURE, new Object[] {});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
*******************************************************************************/
package org.eclipse.sirius.web.application.views.explorer.services;


import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -24,6 +26,7 @@
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.sirius.components.collaborative.api.ChangeKind;
import org.eclipse.sirius.components.collaborative.api.IRepresentationImageProvider;
import org.eclipse.sirius.components.core.CoreImageConstants;
import org.eclipse.sirius.components.core.RepresentationMetadata;
Expand All @@ -39,6 +42,7 @@
import org.eclipse.sirius.components.representations.Failure;
import org.eclipse.sirius.components.representations.IRepresentationDescription;
import org.eclipse.sirius.components.representations.IStatus;
import org.eclipse.sirius.components.representations.Success;
import org.eclipse.sirius.components.representations.VariableManager;
import org.eclipse.sirius.components.trees.Tree;
import org.eclipse.sirius.components.trees.TreeItem;
Expand All @@ -48,6 +52,7 @@
import org.eclipse.sirius.web.application.views.explorer.services.api.IDeleteTreeItemHandler;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerChildrenProvider;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerElementsProvider;
import org.eclipse.sirius.web.application.views.explorer.services.api.IExplorerModificationService;
import org.eclipse.sirius.web.application.views.explorer.services.api.IRenameTreeItemHandler;
import org.eclipse.sirius.web.application.views.explorer.services.configuration.ExplorerDescriptionProviderConfiguration;
import org.eclipse.sirius.web.domain.boundedcontexts.representationdata.projections.RepresentationDataMetadataOnly;
Expand Down Expand Up @@ -90,7 +95,9 @@ public class ExplorerDescriptionProvider implements IEditingContextRepresentatio

private final IRepresentationDataSearchService representationDataSearchService;

public ExplorerDescriptionProvider(ExplorerDescriptionProviderConfiguration explorerDescriptionProviderConfiguration, List<IRepresentationImageProvider> representationImageProviders, IExplorerElementsProvider explorerElementsProvider, IExplorerChildrenProvider explorerChildrenProvider, List<IRenameTreeItemHandler> renameTreeItemHandlers, List<IDeleteTreeItemHandler> deleteTreeItemHandlers) {
private final IExplorerModificationService explorerModificationService;

public ExplorerDescriptionProvider(ExplorerDescriptionProviderConfiguration explorerDescriptionProviderConfiguration, List<IRepresentationImageProvider> representationImageProviders, IExplorerElementsProvider explorerElementsProvider, IExplorerChildrenProvider explorerChildrenProvider, List<IRenameTreeItemHandler> renameTreeItemHandlers, List<IDeleteTreeItemHandler> deleteTreeItemHandlers, IExplorerModificationService explorerModificationService) {
this.objectService = explorerDescriptionProviderConfiguration.getObjectService();
this.urlParser = explorerDescriptionProviderConfiguration.getUrlParser();
this.representationDataSearchService = explorerDescriptionProviderConfiguration.getRepresentationDataSearchService();
Expand All @@ -99,6 +106,7 @@ public ExplorerDescriptionProvider(ExplorerDescriptionProviderConfiguration expl
this.explorerChildrenProvider = Objects.requireNonNull(explorerChildrenProvider);
this.renameTreeItemHandlers = Objects.requireNonNull(renameTreeItemHandlers);
this.deleteTreeItemHandlers = Objects.requireNonNull(deleteTreeItemHandlers);
this.explorerModificationService = Objects.requireNonNull(explorerModificationService);
}

@Override
Expand All @@ -124,6 +132,7 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
.deleteHandler(this::getDeleteHandler)
.renameHandler(this::getRenameHandler)
.treeItemObjectProvider(this::getTreeItemObject)
.dropTreeItemHandler(this::getDropTreeItemProvider)
.build();
return List.of(explorerTreeDescription);
}
Expand Down Expand Up @@ -197,7 +206,7 @@ private StyledString getLabel(VariableManager variableManager) {
var kind = this.objectService.getKind(self);
label = this.urlParser.getParameterValues(kind).get(SemanticKindConstants.ENTITY_ARGUMENT).get(0);
}
} else if (self instanceof Setting setting) {
} else if (self instanceof Setting setting) {
label = setting.getEStructuralFeature().getName();
}
return StyledString.of(label);
Expand Down Expand Up @@ -360,4 +369,16 @@ private Object getParentObject(VariableManager variableManager) {
}
return result;
}

private IStatus getDropTreeItemProvider(VariableManager variableManager) {
var optionalEditingContext = variableManager.get(IEditingContext.EDITING_CONTEXT, IEditingContext.class);
var optionalTreeItemId = variableManager.get("targetTreeItem", String.class);
List<String> droppedTreeItems = variableManager.get("droppedTreeItems", List.class).orElse(List.of());
var optionalIndex = variableManager.get("index", Integer.class);
if (optionalTreeItemId.isPresent() && optionalEditingContext.isPresent()) {
this.explorerModificationService.moveObject(optionalEditingContext.get(), droppedTreeItems, optionalTreeItemId.get(), optionalIndex.orElse(-1));
return new Success(ChangeKind.SEMANTIC_CHANGE, Map.of());
}
return new Failure("");
}
}
Loading

0 comments on commit d6d0c0a

Please sign in to comment.