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 1b78603 commit b6f2a74
Show file tree
Hide file tree
Showing 37 changed files with 2,446 additions and 736 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 CEA LIST.
* Copyright (c) 2024, 2025 CEA LIST.
* 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 All @@ -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,28 +99,97 @@ 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(1);
assertThat(table.getColumns().get(0).getHeaderLabel()).isEqualTo("Name");
assertThat(table.getColumns().get(0).getHeaderIndexLabel()).isEqualTo("0");
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(((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(1);
assertThat(table.getColumns().get(0).getHeaderLabel()).isEqualTo("Name");
assertThat(table.getColumns().get(0).getHeaderIndexLabel()).isEqualTo("0");
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(((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
@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
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 CEA LIST.
* Copyright (c) 2024, 2025 CEA LIST.
* 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 All @@ -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
@@ -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,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
@@ -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
@@ -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 @@ -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 b6f2a74

Please sign in to comment.