Skip to content

Commit

Permalink
[3655] Support "Delete Task Dependency" tool in gantt
Browse files Browse the repository at this point in the history
Bug: #3655
Signed-off-by: Laurent Fasani <[email protected]>
  • Loading branch information
lfasani committed Jun 21, 2024
1 parent 1eab033 commit f343ee4
Show file tree
Hide file tree
Showing 60 changed files with 1,407 additions and 43 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ More existing APIs will be migrated to this new common pattern.
- [releng] Remove the dependency to `reflect-metadata`
- [releng] Switch to `subscriptions-transport-ws` 0.11.0
- [releng] Switch to EMF Json 2.3.11
- https://github.com/eclipse-sirius/sirius-web/issues/3523[#3523] [gantt] Move to @ObeoNetwork/gantt-task-react 0.4.17 to benefit for enhancements
- https://github.com/eclipse-sirius/sirius-web/issues/3523[#3523] [gantt] Move to @ObeoNetwork/gantt-task-react 0.4.18 to benefit for enhancements

=== Bug fixes

Expand Down Expand Up @@ -81,6 +81,7 @@ This dialog presents diagram elements in a tree and allows to select them and up
+
image:doc/screenshots/diagramFilterView.png[Diagram Filter View, 70%]
- https://github.com/eclipse-sirius/sirius-web/issues/3523[#3523] [gantt] Support rounding dates when changing dates from gantt
- https://github.com/eclipse-sirius/sirius-web/issues/3655[#3655] [gantt] Support "Delete Task Dependency" tool in gantt

=== Improvements

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/specifier/images/gantt-task-handlers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions doc/specifier/representation-gantt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Available variables:
** `newStartTime`: The new value of the start time.
** `newEndTime`: The new value of the end time.
** `newDescription`: The new value of the description.
** `newProgress`: The new value of the progress.
** `newProgress`: The new value of the progress.
image::images/gantt-task-handlers.png[Task handlers]

Expand All @@ -121,7 +121,14 @@ index=0 means first position.
This tool defines the behavior when creating a task dependency by dragging the dependency handler from one task to another.
Available variables:
** `sourceObject`: The semantic element associated with the task from which the dependency link is initiated.
** `targetObject`: The semantic element associated with the target task where the dependency finishes.
** `targetObject`: The semantic element associated with the dependant task where the dependency finishes.
image::images/gantt-task-relation-tool.png[Create Task Dependency Tool]
* `Delete Task Dependency Tool`:
This tool defines the behavior when deleting a task dependency using the button in the task dependency contextual palette in Gantt.
Available variables:
** `sourceObject`: The semantic element associated with the task from which the dependency link is initiated.
** `targetObject`: The semantic element associated with the dependant task where the dependency finishes.

image:images/gantt-task-dependency-palette.png[Task Dependency Contextual Palette]

Binary file added doc/user/images/gantt-task-dependency-palette.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/user/images/gantt-task-handlers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/user/images/gantt-task-palette.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 16 additions & 1 deletion doc/user/representation-gantt.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ When selecting a `Task` in Gantt or in the Table, the associated semantic elemen
Using handlers on the task, it is possible to change the start/end dates and the progress.
Clicking on the task and moving it left or right, allows to shift the date keeping the same duration.

image:images/gantt-task-handlers.png[Show/Hide Cards]
image:images/gantt-task-handlers.png[Task handlers]

When changing a date, the date is rounded accordingly to the `Date Rounding Expression` define in the `GanttDescription`.
Holiday is set as Saturday and Sunday. If the rounded date is part of the holiday, it is moved to the next or previous working date.
Expand All @@ -78,6 +78,21 @@ image:images/gantt-task-dependency-tool.png[Task Dependency Tool]
image:images/gantt-task-dependency.png[Task Dependency]


### Contextual tool palettes

Clicking on a task displays a contextual menu.

* `Create Task`: It will invoke `Create Task Tool`
* `Delete Task`: It will invoke `Delete Task Tool`
image:images/gantt-task-palette.png[Task Contextual Palette]

Clicking on a task dependency displays a contextual menu.

* `Delete Task Dependency`: It will invoke `Create Task Dependency Tool`
image:images/gantt-task-dependency-palette.png[Task Dependency Contextual Palette]

### Task reordering

From the table, it is possible to drag and drop a Task to reorder the task or change its container.
Expand Down
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.eclipse.sirius.components.collaborative.gantt.dto.input.ChangeTaskCollapseStateInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.CreateGanttTaskDependencyInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.CreateGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DeleteGanttTaskDependencyInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DeleteGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DropGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.EditGanttTaskInput;
Expand Down Expand Up @@ -55,6 +56,11 @@ public interface IGanttTaskService {
*/
IPayload createTaskDependency(CreateGanttTaskDependencyInput createTaskDependencyInput, IEditingContext editingContext, Gantt gantt);

/**
* Delete a dependency between two tasks.
*/
IPayload deleteTaskDependency(DeleteGanttTaskDependencyInput createTaskDependencyInput, IEditingContext editingContext, Gantt gantt);

/**
* Change the state collapse of a task.
*/
Expand Down Expand Up @@ -97,6 +103,11 @@ public IPayload createTaskDependency(CreateGanttTaskDependencyInput createTaskDe
return null;
}

@Override
public IPayload deleteTaskDependency(DeleteGanttTaskDependencyInput createTaskDependencyInput, IEditingContext editingContext, Gantt gantt) {
return null;
}

@Override
public IPayload changeTaskCollapseState(ChangeTaskCollapseStateInput changeTaskCollapseStateInput, IEditingContext editingContext, IGanttContext ganttContext) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*******************************************************************************
* 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.components.collaborative.gantt.dto.input;

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

import org.eclipse.sirius.components.collaborative.gantt.api.IGanttInput;

/**
* The input of the "Delete task dependency" mutation.
*
* @author lfasani
*/
public record DeleteGanttTaskDependencyInput(UUID id, String editingContextId, String representationId, String sourceTaskId, String targetTaskId) implements IGanttInput {
public DeleteGanttTaskDependencyInput {
Objects.requireNonNull(id);
Objects.requireNonNull(editingContextId);
Objects.requireNonNull(representationId);
Objects.requireNonNull(sourceTaskId);
Objects.requireNonNull(targetTaskId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*******************************************************************************
* 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.components.collaborative.gantt.handlers;

import java.util.Objects;

import org.eclipse.sirius.components.collaborative.api.ChangeDescription;
import org.eclipse.sirius.components.collaborative.api.ChangeKind;
import org.eclipse.sirius.components.collaborative.api.Monitoring;
import org.eclipse.sirius.components.collaborative.gantt.api.IGanttContext;
import org.eclipse.sirius.components.collaborative.gantt.api.IGanttEventHandler;
import org.eclipse.sirius.components.collaborative.gantt.api.IGanttInput;
import org.eclipse.sirius.components.collaborative.gantt.api.IGanttTaskService;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DeleteGanttTaskDependencyInput;
import org.eclipse.sirius.components.collaborative.gantt.message.ICollaborativeGanttMessageService;
import org.eclipse.sirius.components.core.api.ErrorPayload;
import org.eclipse.sirius.components.core.api.IEditingContext;
import org.eclipse.sirius.components.core.api.IPayload;
import org.springframework.stereotype.Service;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import reactor.core.publisher.Sinks.Many;
import reactor.core.publisher.Sinks.One;

/**
* Handle "Delete Task Dependency" events.
*
* @author lfasani
*/
@Service
public class DeleteTaskDependencyEventHandler implements IGanttEventHandler {

private final IGanttTaskService ganttTaskService;

private final ICollaborativeGanttMessageService messageService;

private final Counter counter;

public DeleteTaskDependencyEventHandler(IGanttTaskService ganttTaskService, ICollaborativeGanttMessageService messageService, MeterRegistry meterRegistry) {
this.ganttTaskService = Objects.requireNonNull(ganttTaskService);
this.messageService = Objects.requireNonNull(messageService);

this.counter = Counter.builder(Monitoring.EVENT_HANDLER).tag(Monitoring.NAME, this.getClass().getSimpleName()).register(meterRegistry);
}

@Override
public boolean canHandle(IGanttInput ganttInput) {
return ganttInput instanceof DeleteGanttTaskDependencyInput;
}

@Override
public void handle(One<IPayload> payloadSink, Many<ChangeDescription> changeDescriptionSink, IEditingContext editingContext, IGanttContext ganttContext, IGanttInput ganttInput) {
this.counter.increment();

String message = this.messageService.invalidInput(ganttInput.getClass().getSimpleName(), DeleteGanttTaskDependencyInput.class.getSimpleName());
IPayload payload = new ErrorPayload(ganttInput.id(), message);
ChangeDescription changeDescription = new ChangeDescription(ChangeKind.NOTHING, ganttInput.representationId(), ganttInput);

if (ganttInput instanceof DeleteGanttTaskDependencyInput input) {
payload = this.ganttTaskService.deleteTaskDependency(input, editingContext, ganttContext.getGantt());

changeDescription = new ChangeDescription(ChangeKind.SEMANTIC_CHANGE, ganttInput.representationId(), ganttInput);
}

payloadSink.tryEmitValue(payload);
changeDescriptionSink.tryEmitNext(changeDescription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.sirius.components.collaborative.gantt.dto.input.ChangeTaskCollapseStateInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.CreateGanttTaskDependencyInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.CreateGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DeleteGanttTaskDependencyInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DeleteGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.DropGanttTaskInput;
import org.eclipse.sirius.components.collaborative.gantt.dto.input.EditGanttTaskInput;
Expand Down Expand Up @@ -228,6 +229,34 @@ public IPayload createTaskDependency(CreateGanttTaskDependencyInput createTaskDe
return payload;
}

@Override
public IPayload deleteTaskDependency(DeleteGanttTaskDependencyInput deleteTaskDependencyInput, IEditingContext editingContext, Gantt gantt) {
IPayload payload = new ErrorPayload(deleteTaskDependencyInput.id(), "Delete task dependency failed");

Optional<GanttDescription> ganttDescriptionOpt = this.findGanttDescription(gantt.descriptionId(), editingContext);

if (ganttDescriptionOpt.isPresent()) {
VariableManager variableManager = new VariableManager();
variableManager.put(IEditingContext.EDITING_CONTEXT, editingContext);

Optional<Object> sourceObjectOpt = Optional.of(deleteTaskDependencyInput.sourceTaskId())
.flatMap(taskId -> this.getTaskSemanticObject(taskId, gantt, editingContext));

Optional<Object> targetObjectOpt = Optional.of(deleteTaskDependencyInput.targetTaskId())
.flatMap(taskId -> this.getTaskSemanticObject(taskId, gantt, editingContext));

if (sourceObjectOpt.isPresent() && targetObjectOpt.isPresent()) {
variableManager.put(GanttDescription.SOURCE_OBJECT, sourceObjectOpt.get());
variableManager.put(GanttDescription.TARGET_OBJECT, targetObjectOpt.get());
ganttDescriptionOpt.get().deleteTaskDependencyProvider().accept(variableManager);
}

payload = this.getPayload(deleteTaskDependencyInput.id());
}

return payload;
}

private Optional<Object> getTaskSemanticObject(String taskId, Gantt gantt, IEditingContext editingContext) {
Optional<Object> targetObjectOpt = this.findTask(task -> Objects.equals(task.id(), taskId), gantt.tasks())
.map(task -> this.objectService.getObject(editingContext, task.targetObjectId()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ extend type Mutation {
editGanttTask(input: EditGanttTaskInput!): EditGanttTaskPayload
dropGanttTask(input: DropGanttTaskInput!): DropGanttTaskPayload
createGanttTaskDependency(input: CreateGanttTaskDependencyInput!): CreateGanttTaskDependencyPayload
deleteGanttTaskDependency(input: DeleteGanttTaskDependencyInput!): DeleteGanttTaskDependencyPayload
changeGanttTaskCollapseState(input: ChangeGanttTaskCollapseStateInput!): ChangeGanttTaskCollapseStatePayload
changeGanttColumn(input: ChangeGanttColumnInput!): ChangeGanttColumnPayload
}
Expand Down Expand Up @@ -143,6 +144,15 @@ input CreateGanttTaskDependencyInput {
}
union CreateGanttTaskDependencyPayload = SuccessPayload | ErrorPayload

input DeleteGanttTaskDependencyInput {
id: ID!
editingContextId: ID!
representationId: ID!
sourceTaskId: ID!
targetTaskId: ID!
}
union DeleteGanttTaskDependencyPayload = SuccessPayload | ErrorPayload

input ChangeGanttTaskCollapseStateInput {
id: ID!
editingContextId: ID!
Expand Down
Loading

0 comments on commit f343ee4

Please sign in to comment.