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: #4403
Signed-off-by: Jerome Gout <[email protected]>
  • Loading branch information
jerome-obeo committed Jan 15, 2025
1 parent 833d045 commit 34b2e24
Show file tree
Hide file tree
Showing 37 changed files with 2,434 additions and 723 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,25 @@
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.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 @@ -83,11 +99,7 @@ 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 -> {
Consumer<Object> tableContentConsumer = this.getTableSubscriptionConsumer(table -> {
assertThat(table).isNotNull();
assertThat(table.getColumns()).hasSize(1);
assertThat(table.getColumns().get(0).getHeaderLabel()).isEqualTo("Name");
Expand All @@ -99,12 +111,85 @@ public void givenSimpleViewTableDescriptionWhenSubscriptionIsCreatedThenTableIsR
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"));
});

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

@Test
@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")
@Sql(scripts = {"/scripts/papaya.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = {"/scripts/cleanup.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
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.contextMenuEntries[*].label");
assertThat(actionLabels).isNotEmpty().hasSize(1);
assertThat(actionLabels.get(0)).isEqualTo("Change name");

List<String> actionIds = JsonPath.read(document, "$.data.viewer.editingContext.representation.description.contextMenuEntries[*].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,22 @@ private TableDescription createTableDescription() {
.headerIndexLabelExpression("aql:columnIndex")
.build();

var callService = new ViewBuilders().newSetValue()
.featureName("name")
.valueExpression("aql:self.name + 'Updated'");

var contextMenuEntry = new TableBuilders().newRowContextMenuEntry()
.name("change-name")
.labelExpression("Change name")
.preconditionExpression("aql:true")
.body(callService.build())
.build();

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

var cellDescription = new TableBuilders().newCellDescription()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
@Immutable
public final class LineDescription {

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

/**
* The variable name used for the id of a row.
*/
public static final String ID = "id";

private String id;

private Function<VariableManager, String> targetObjectIdProvider;
Expand Down
Original file line number Diff line number Diff line change
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, 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.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
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 @@ -79,5 +79,15 @@ public CellLabelWidgetDescriptionBuilder newCellLabelWidgetDescription() {
return new CellLabelWidgetDescriptionBuilder();
}

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


}
Loading

0 comments on commit 34b2e24

Please sign in to comment.