Skip to content

Commit

Permalink
[4403] Add support of row actions in table view DSL
Browse files Browse the repository at this point in the history
Bug: eclipse-sirius#4403
Signed-off-by: Jerome Gout <[email protected]>
  • Loading branch information
jerome-obeo authored and sbegaudeau committed Jan 28, 2025
1 parent ba62d46 commit b1dd897
Show file tree
Hide file tree
Showing 26 changed files with 1,903 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,26 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import org.eclipse.sirius.components.collaborative.dto.CreateRepresentationInput;
import org.eclipse.sirius.components.collaborative.tables.TableRefreshedEventPayload;
import org.eclipse.sirius.components.collaborative.tables.dto.InvokeRowContextMenuEntryInput;
import org.eclipse.sirius.components.core.api.SuccessPayload;
import org.eclipse.sirius.components.tables.Table;
import org.eclipse.sirius.components.tables.TextareaCell;
import org.eclipse.sirius.components.tables.TextfieldCell;
import org.eclipse.sirius.components.tables.tests.graphql.InvokeRowContextMenuEntryMutationRunner;
import org.eclipse.sirius.components.tables.tests.graphql.RowContextMenuQueryRunner;
import org.eclipse.sirius.web.AbstractIntegrationTests;
import org.eclipse.sirius.web.data.PapayaIdentifiers;
import org.eclipse.sirius.web.services.tables.ViewTableDescriptionProvider;
Expand Down Expand Up @@ -59,6 +70,11 @@ public class PapayaViewTableControllerIntegrationTests extends AbstractIntegrati
@Autowired
private ViewTableDescriptionProvider viewTableDescriptionProvider;

@Autowired
private RowContextMenuQueryRunner rowContextMenuQueryRunner;

@Autowired
private InvokeRowContextMenuEntryMutationRunner invokeRowContextMenuEntryMutationRunner;

@BeforeEach
public void beforeEach() {
Expand All @@ -82,31 +98,98 @@ private Flux<Object> givenSubscriptionToViewTableRepresentation() {
public void givenSimpleViewTableDescriptionWhenSubscriptionIsCreatedThenTableIsRender() {
var flux = this.givenSubscriptionToViewTableRepresentation();

Consumer<Object> tableContentConsumer = payload -> Optional.of(payload)
.filter(TableRefreshedEventPayload.class::isInstance)
.map(TableRefreshedEventPayload.class::cast)
.map(TableRefreshedEventPayload::table)
.ifPresentOrElse(table -> {
assertThat(table).isNotNull();
assertThat(table.getColumns()).hasSize(2);
assertThat(table.getColumns().get(0).getHeaderLabel()).isEqualTo("Name");
assertThat(table.getColumns().get(0).getHeaderIndexLabel()).isEqualTo("0");
assertThat(table.getColumns().get(1).getHeaderLabel()).isEqualTo("Description");
assertThat(table.getColumns().get(1).getHeaderIndexLabel()).isEqualTo("1");
assertThat(table.getLines()).hasSize(2);
assertThat(table.getLines().get(0).getHeaderIndexLabel()).isEqualTo("0");
assertThat(table.getLines().get(0).getCells().get(0)).isInstanceOf(TextfieldCell.class);
assertThat(table.getLines().get(0).getCells().get(1)).isInstanceOf(TextareaCell.class);
assertThat(((TextfieldCell) table.getLines().get(0).getCells().get(0)).getValue()).isEqualTo("Success");
assertThat(table.getLines().get(1).getHeaderIndexLabel()).isEqualTo("1");
assertThat(table.getLines().get(1).getCells().get(0)).isInstanceOf(TextfieldCell.class);
assertThat(((TextfieldCell) table.getLines().get(1).getCells().get(0)).getValue()).isEqualTo("Failure");
}, () -> fail("Missing table"));
Consumer<Object> tableContentConsumer = this.getTableSubscriptionConsumer(table -> {
assertThat(table).isNotNull();
assertThat(table.getColumns()).hasSize(2);
assertThat(table.getColumns().get(0).getHeaderLabel()).isEqualTo("Name");
assertThat(table.getColumns().get(0).getHeaderIndexLabel()).isEqualTo("0");
assertThat(table.getColumns().get(1).getHeaderLabel()).isEqualTo("Description");
assertThat(table.getColumns().get(1).getHeaderIndexLabel()).isEqualTo("1");
assertThat(table.getLines()).hasSize(2);
assertThat(table.getLines().get(0).getHeaderIndexLabel()).isEqualTo("0");
assertThat(table.getLines().get(0).getCells().get(0)).isInstanceOf(TextfieldCell.class);
assertThat(table.getLines().get(0).getCells().get(1)).isInstanceOf(TextareaCell.class);
assertThat(((TextfieldCell) table.getLines().get(0).getCells().get(0)).getValue()).isEqualTo("Success");
assertThat(table.getLines().get(1).getHeaderIndexLabel()).isEqualTo("1");
assertThat(table.getLines().get(1).getCells().get(0)).isInstanceOf(TextfieldCell.class);
assertThat(((TextfieldCell) table.getLines().get(1).getCells().get(0)).getValue()).isEqualTo("Failure");
});

StepVerifier.create(flux)
.consumeNextWith(tableContentConsumer)
.thenCancel()
.verify(Duration.ofSeconds(10));
}

@Test
@GivenSiriusWebServer
@DisplayName("Given a simple view table description, when a row context menu entry is retrieved and invoked, then the row context menu entry is correctly executed")
public void givenSimpleViewTableDescriptionWhenRowContextMenuEntryIsInvokedThenRowContextMenuEntryIsCorrectlyExecuted() {
var flux = this.givenSubscriptionToViewTableRepresentation();

var tableId = new AtomicReference<String>();
var rowId = new AtomicReference<UUID>();
var rowLabel = new AtomicReference<String>();
Consumer<Object> tableContentConsumer = this.getTableSubscriptionConsumer(table -> {
assertThat(table).isNotNull();
assertThat(table.getLines()).hasSize(2);
tableId.set(table.getId());
rowId.set(table.getLines().get(0).getId());
rowLabel.set(table.getLines().get(0).getHeaderLabel());
});

var actionId = new AtomicReference<String>();
Runnable getContextMenuEntriesTask = () -> {
Map<String, Object> variables = Map.of(
"editingContextId", PapayaIdentifiers.PAPAYA_PROJECT.toString(),
"representationId", tableId.get(),
"tableId", tableId.get(),
"rowId", rowId.get().toString());
var result = this.rowContextMenuQueryRunner.run(variables);
Object document = Configuration.defaultConfiguration().jsonProvider().parse(result);

List<String> actionLabels = JsonPath.read(document, "$.data.viewer.editingContext.representation.description.rowContextMenuEntries[*].label");
assertThat(actionLabels).isNotEmpty().hasSize(1);
assertThat(actionLabels.get(0)).isEqualTo("Change name");

List<String> actionIds = JsonPath.read(document, "$.data.viewer.editingContext.representation.description.rowContextMenuEntries[*].id");
actionId.set(actionIds.get(0));
};

Runnable invokeChangeNameAction = () -> {
var invokeRowContextMenuEntryInput = new InvokeRowContextMenuEntryInput(
UUID.randomUUID(),
PapayaIdentifiers.PAPAYA_PROJECT.toString(),
tableId.get(),
tableId.get(),
rowId.get(),
actionId.get()
);
var result = this.invokeRowContextMenuEntryMutationRunner.run(invokeRowContextMenuEntryInput);

String typename = JsonPath.read(result, "$.data.invokeRowContextMenuEntry.__typename");
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
};

Consumer<Object> updatedTableContentConsumer = this.getTableSubscriptionConsumer(table -> {
assertThat(table).isNotNull();
assertThat(table.getLines().get(0).getHeaderLabel()).isEqualTo(rowLabel + "Updated");
});

StepVerifier.create(flux)
.consumeNextWith(tableContentConsumer)
.then(getContextMenuEntriesTask)
.then(invokeChangeNameAction)
.consumeNextWith(updatedTableContentConsumer)
.thenCancel()
.verify(Duration.ofSeconds(10));
}

private Consumer<Object> getTableSubscriptionConsumer(Consumer<Table> tableConsumer) {
return payload -> Optional.of(payload)
.filter(TableRefreshedEventPayload.class::isInstance)
.map(TableRefreshedEventPayload.class::cast)
.map(TableRefreshedEventPayload::table)
.ifPresentOrElse(tableConsumer, () -> fail("Missing table"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.sirius.components.view.View;
import org.eclipse.sirius.components.view.builder.generated.table.TableBuilders;
import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilder;
import org.eclipse.sirius.components.view.builder.generated.view.ViewBuilders;
import org.eclipse.sirius.components.view.emf.table.TableIdProvider;
import org.eclipse.sirius.components.view.table.TableDescription;
import org.eclipse.sirius.emfjson.resource.JsonResource;
Expand Down Expand Up @@ -88,9 +89,23 @@ private TableDescription createTableDescription() {
.headerIndexLabelExpression("aql:columnIndex")
.build();

var contextMenuEntry = new TableBuilders().newRowContextMenuEntry()
.name("change-name")
.labelExpression("Change name")
.preconditionExpression("aql:true")
.body(
new ViewBuilders().newSetValue()
.featureName("name")
.valueExpression("aql:self.name + 'Updated'")
.build()
)
.build();

var rowDescription = new TableBuilders().newRowDescription()
.semanticCandidatesExpression("aql:self.types")
.headerIndexLabelExpression("aql:rowIndex")
.headerLabelExpression("aql:self.name")
.contextMenuEntries(contextMenuEntry)
.build();

var nameCellDescription = new TableBuilders().newCellDescription()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand Down Expand Up @@ -29,6 +29,11 @@
@Immutable
public final class LineDescription {

/**
* The variable name used to store a reference to a row.
*/
public static final String SELECTED_ROW = "selectedRow";

private String id;

private Function<VariableManager, String> targetObjectIdProvider;
Expand All @@ -53,6 +58,10 @@ private LineDescription() {
// Prevent instantiation
}

public static Builder newLineDescription(String id) {
return new Builder(id);
}

public String getId() {
return this.id;
}
Expand Down Expand Up @@ -93,10 +102,6 @@ public Predicate<VariableManager> getIsResizablePredicate() {
return this.isResizablePredicate;
}

public static Builder newLineDescription(String id) {
return new Builder(id);
}

@Override
public String toString() {
String pattern = "{0} '{'id: {1}'}'";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 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
Expand Down Expand Up @@ -33,6 +33,11 @@ public final class TableDescription implements IRepresentationDescription {

public static final String LABEL = "label";

/**
* The variable name used to store a reference to a table.
*/
public static final String TABLE = "table";

private String id;

private String label;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2023, 2025 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.view.builder.generated.table;

/**
* Builder for RowContextMenuEntryBuilder.
*
* @author BuilderGenerator
* @generated
*/
public class RowContextMenuEntryBuilder {

/**
* Create instance org.eclipse.sirius.components.view.table.RowContextMenuEntry.
* @generated
*/
private org.eclipse.sirius.components.view.table.RowContextMenuEntry rowContextMenuEntry = org.eclipse.sirius.components.view.table.TableFactory.eINSTANCE.createRowContextMenuEntry();

/**
* Return instance org.eclipse.sirius.components.view.table.RowContextMenuEntry.
* @generated
*/
protected org.eclipse.sirius.components.view.table.RowContextMenuEntry getRowContextMenuEntry() {
return this.rowContextMenuEntry;
}

/**
* Return instance org.eclipse.sirius.components.view.table.RowContextMenuEntry.
* @generated
*/
public org.eclipse.sirius.components.view.table.RowContextMenuEntry build() {
return this.getRowContextMenuEntry();
}

/**
* Setter for Name.
*
* @generated
*/
public RowContextMenuEntryBuilder name(java.lang.String value) {
this.getRowContextMenuEntry().setName(value);
return this;
}
/**
* Setter for LabelExpression.
*
* @generated
*/
public RowContextMenuEntryBuilder labelExpression(java.lang.String value) {
this.getRowContextMenuEntry().setLabelExpression(value);
return this;
}
/**
* Setter for IconURLExpression.
*
* @generated
*/
public RowContextMenuEntryBuilder iconURLExpression(java.lang.String value) {
this.getRowContextMenuEntry().setIconURLExpression(value);
return this;
}
/**
* Setter for PreconditionExpression.
*
* @generated
*/
public RowContextMenuEntryBuilder preconditionExpression(java.lang.String value) {
this.getRowContextMenuEntry().setPreconditionExpression(value);
return this;
}
/**
* Setter for Body.
*
* @generated
*/
public RowContextMenuEntryBuilder body(org.eclipse.sirius.components.view.Operation ... values) {
for (org.eclipse.sirius.components.view.Operation value : values) {
this.getRowContextMenuEntry().getBody().add(value);
}
return this;
}


}

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2023, 2024 Obeo.
* Copyright (c) 2023, 2025 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
Expand Down Expand Up @@ -124,5 +124,17 @@ public RowDescriptionBuilder isResizableExpression(java.lang.String value) {
return this;
}

/**
* Setter for ContextMenuEntries.
*
* @generated
*/
public RowDescriptionBuilder contextMenuEntries(org.eclipse.sirius.components.view.table.RowContextMenuEntry ... values) {
for (org.eclipse.sirius.components.view.table.RowContextMenuEntry value : values) {
this.getRowDescription().getContextMenuEntries().add(value);
}
return this;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,15 @@ public CellTextareaWidgetDescriptionBuilder newCellTextareaWidgetDescription() {
return new CellTextareaWidgetDescriptionBuilder();
}

/**
* Instantiate a RowContextMenuEntryBuilder .
*
* @author BuilderGenerator
* @generated
*/
public RowContextMenuEntryBuilder newRowContextMenuEntry() {
return new RowContextMenuEntryBuilder();
}


}
Loading

0 comments on commit b1dd897

Please sign in to comment.