Skip to content

Commit

Permalink
[4242] Add support to for the customization of the header of each row
Browse files Browse the repository at this point in the history
Bug: #4242
Signed-off-by: Florian ROUËNÉ <[email protected]>
  • Loading branch information
frouene authored and sbegaudeau committed Dec 4, 2024
1 parent 6cfcc05 commit 6fed9f6
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Specifiers can implement this new interface with a spring `Service`.
A new `IRestDataVersionPayloadSerializerService` interface is available, allowing to customize the default implementation of the JSON serialization of the payload object of `RestDataVersion`.
Specifiers are also encouraged to implement their own `IRestDataVersionPayloadSerializerService` for their domains, as the default one may not return expected results.
- https://github.com/eclipse-sirius/sirius-web/issues/4250[#4250] [table] Add icons to table column headers
- https://github.com/eclipse-sirius/sirius-web/issues/4242[#4242] [table] Add support to for the customization of the header of each row

=== Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.eclipse.emf.ecore.EStructuralFeature;
Expand Down Expand Up @@ -65,10 +66,25 @@ public PackageTableRepresentationDescriptionProvider(IIdentityService identitySe

@Override
public List<IRepresentationDescription> getRepresentationDescriptions(IEditingContext editingContext) {
Function<VariableManager, String> headerLabelProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class)
.map(this.labelService::getLabel)
.orElse(null);

Function<VariableManager, List<String>> headerIconURLsProvider = variableManager -> variableManager.get(VariableManager.SELF, Object.class)
.map(this.labelService::getImagePath)
.orElse(List.of());

Function<VariableManager, String> headerIndexLabelProvider = variableManager -> variableManager.get("rowIndex", Integer.class)
.map(String::valueOf)
.orElse(null);

var lineDescription = LineDescription.newLineDescription(UUID.nameUUIDFromBytes("Table - Line".getBytes()))
.targetObjectIdProvider(new TableTargetObjectIdProvider(this.identityService))
.targetObjectKindProvider(new TableTargetObjectKindProvider(this.identityService))
.semanticElementsProvider(this::getSemanticElements)
.headerLabelProvider(headerLabelProvider)
.headerIconURLsProvider(headerIconURLsProvider)
.headerIndexLabelProvider(headerIndexLabelProvider)
.build();

var tableDescription = TableDescription.newTableDescription(TABLE_DESCRIPTION_ID)
Expand All @@ -86,6 +102,7 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
return List.of(tableDescription);
}


private boolean canCreate(VariableManager variableManager) {
return variableManager.get(VariableManager.SELF, Object.class)
.filter(PackageSpec.class::isInstance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ public List<IRepresentationDescription> getRepresentationDescriptions(IEditingCo
.targetObjectIdProvider(new TableTargetObjectIdProvider(this.identityService))
.targetObjectKindProvider(new TableTargetObjectKindProvider(this.identityService))
.semanticElementsProvider(this::getSemanticElements)
.headerLabelProvider(variableManager -> "")
.headerIconURLsProvider(variableManager -> List.of())
.headerIndexLabelProvider(variableManager -> "")
.build();

var tableDescription = TableDescription.newTableDescription(TABLE_DESCRIPTION_ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,25 @@
public class TableIconURLControllerTests extends AbstractIntegrationTests {

private static final String TABLE_EVENT_SUBSCRIPTION = """
subscription tableEvent($input: TableEventInput!) {
tableEvent(input: $input) {
__typename
... on TableRefreshedEventPayload {
table {
id
columns {
id
iconURLs
}
}
}
}
}
""";
subscription tableEvent($input: TableEventInput!) {
tableEvent(input: $input) {
__typename
... on TableRefreshedEventPayload {
table {
id
columns {
id
iconURLs
}
lines {
id
headerIconURLs
}
}
}
}
}
""";

@Autowired
private IGivenCreatedRepresentation givenCreatedRepresentation;
Expand Down Expand Up @@ -110,15 +114,25 @@ public void givenPapayaPackageWhenWeSubscribeToTableWithIconThenURLOfItsIconsAre
String typename = JsonPath.read(body, "$.data.tableEvent.__typename");
assertThat(typename).isEqualTo(TableRefreshedEventPayload.class.getSimpleName());

List<List<String>> tableStubRowIconURLs = JsonPath.read(body, "$.data.tableEvent.table.columns[*].iconURLs");
assertThat(tableStubRowIconURLs)
List<List<String>> columnIconURLs = JsonPath.read(body, "$.data.tableEvent.table.columns[*].iconURLs");
assertThat(columnIconURLs)
.isNotEmpty()
.allSatisfy(iconURLs -> {
assertThat(iconURLs)
.isNotEmpty()
.hasSize(1)
.allSatisfy(iconURL -> assertThat(iconURL).startsWith(URLConstants.IMAGE_BASE_PATH));
});

List<List<String>> rowIconURLs = JsonPath.read(body, "$.data.tableEvent.table.lines[*].headerIconURLs");
assertThat(rowIconURLs)
.isNotEmpty()
.allSatisfy(iconURLs -> {
assertThat(iconURLs)
.isNotEmpty()
.hasSize(2)
.allSatisfy(iconURL -> assertThat(iconURL).startsWith(URLConstants.IMAGE_BASE_PATH));
});
}, () -> fail("Missing table"));

StepVerifier.create(flux)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ private TableWidgetDescription getTableWidgetDescription() {
.targetObjectIdProvider(this::getTargetObjectId)
.targetObjectKindProvider(this::getTargetObjectKind)
.semanticElementsProvider(semanticElementsProvider)
.headerLabelProvider(variableManager -> "")
.headerIconURLsProvider(variableManager -> List.of())
.headerIndexLabelProvider(variableManager -> "")
.build();
lineDescriptions.add(lineDescription);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type Line {
targetObjectId: ID!
targetObjectKind: String!
cells: [Cell!]!
headerLabel: String!
headerIconURLs: [String!]!
headerIndexLabel: String!
}

interface Cell {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2024 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
* 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.tables.graphql.datafetchers;

import java.util.List;
import java.util.Objects;

import org.eclipse.sirius.components.annotations.spring.graphql.QueryDataFetcher;
import org.eclipse.sirius.components.core.api.IImageURLSanitizer;
import org.eclipse.sirius.components.graphql.api.IDataFetcherWithFieldCoordinates;
import org.eclipse.sirius.components.graphql.api.URLConstants;
import org.eclipse.sirius.components.tables.Line;

import graphql.schema.DataFetchingEnvironment;

/**
* The data fetcher used to concatenate the server image URL to the row header image path.
*
* @author frouene
*/
@QueryDataFetcher(type = "Line", field = "headerIconURLs")
public class LineHeaderIconURLsDataFetcher implements IDataFetcherWithFieldCoordinates<List<String>> {

private final IImageURLSanitizer imageURLSanitizer;

public LineHeaderIconURLsDataFetcher(IImageURLSanitizer imageURLSanitizer) {
this.imageURLSanitizer = Objects.requireNonNull(imageURLSanitizer);
}

@Override
public List<String> get(DataFetchingEnvironment environment) throws Exception {
Line source = environment.getSource();

return source.getHeaderIconURLs().stream()
.map(url -> this.imageURLSanitizer.sanitize(URLConstants.IMAGE_BASE_PATH, url))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ public final class Line {

private List<ICell> cells;

private String headerLabel;

private List<String> headerIconURLs;

private String headerIndexLabel;

private Line() {
// Prevent instantiation
}
Expand All @@ -61,6 +67,18 @@ public List<ICell> getCells() {
return this.cells;
}

public String getHeaderLabel() {
return this.headerLabel;
}

public List<String> getHeaderIconURLs() {
return this.headerIconURLs;
}

public String getHeaderIndexLabel() {
return this.headerIndexLabel;
}

public static Builder newLine(UUID id) {
return new Builder(id);
}
Expand Down Expand Up @@ -89,6 +107,12 @@ public static final class Builder {

private List<ICell> cells;

private String headerLabel;

private List<String> headerIconURLs;

private String headerIndexLabel;

private Builder(UUID id) {
this.id = Objects.requireNonNull(id);
}
Expand Down Expand Up @@ -120,13 +144,31 @@ public Builder cells(List<ICell> cells) {
return this;
}

public Builder headerLabel(String headerLabel) {
this.headerLabel = Objects.requireNonNull(headerLabel);
return this;
}

public Builder headerIconURLs(List<String> headerIconURLs) {
this.headerIconURLs = Objects.requireNonNull(headerIconURLs);
return this;
}

public Builder headerIndexLabel(String headerIndexLabel) {
this.headerIndexLabel = Objects.requireNonNull(headerIndexLabel);
return this;
}

public Line build() {
Line line = new Line();
line.id = Objects.requireNonNull(this.id);
line.targetObjectId = Objects.requireNonNull(this.targetObjectId);
line.targetObjectKind = Objects.requireNonNull(this.targetObjectKind);
line.descriptionId = Objects.requireNonNull(this.descriptionId);
line.cells = Objects.requireNonNull(this.cells);
line.headerLabel = Objects.requireNonNull(this.headerLabel);
line.headerIconURLs = Objects.requireNonNull(this.headerIconURLs);
line.headerIndexLabel = Objects.requireNonNull(this.headerIndexLabel);
return line;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ public Element render() {

List<Element> children = new ArrayList<>();
List<Object> semanticElements = lineDescription.getSemanticElementsProvider().apply(variableManager);

var index = 0;
for (Object semanticElement : semanticElements) {
VariableManager lineVariableManager = variableManager.createChild();
lineVariableManager.put(VariableManager.SELF, semanticElement);
lineVariableManager.put("rowIndex", index++);

String targetObjectId = lineDescription.getTargetObjectIdProvider().apply(lineVariableManager);
var optionalPreviousLine = linesRequestor.getByTargetObjectId(targetObjectId);
Expand All @@ -77,15 +78,22 @@ private Element doRender(VariableManager lineVariableManager, String targetObjec

String targetObjectKind = lineDescription.getTargetObjectKindProvider().apply(lineVariableManager);

String headerLabel = lineDescription.getHeaderLabelProvider().apply(lineVariableManager);
List<String> headerIconURLs = lineDescription.getHeaderIconURLsProvider().apply(lineVariableManager);
String headerIndexLabel = lineDescription.getHeaderIndexLabelProvider().apply(lineVariableManager);

var cells = this.getCells(lineVariableManager, lineId);

List<Element> children = new ArrayList<>();
children.addAll(cells);

LineElementProps lineElementProps = LineElementProps.newLineElementProps(lineId)
var lineElementProps = LineElementProps.newLineElementProps(lineId)
.descriptionId(lineDescription.getId())
.targetObjectId(targetObjectId)
.targetObjectKind(targetObjectKind)
.headerLabel(headerLabel)
.headerIconURLs(headerIconURLs)
.headerIndexLabel(headerIndexLabel)
.children(children)
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ public final class LineDescription {

private Function<VariableManager, List<Object>> semanticElementsProvider;

private Function<VariableManager, String> headerLabelProvider;

private Function<VariableManager, List<String>> headerIconURLsProvider;

private Function<VariableManager, String> headerIndexLabelProvider;

private LineDescription() {
// Prevent instantiation
}
Expand All @@ -57,6 +63,18 @@ public Function<VariableManager, List<Object>> getSemanticElementsProvider() {
return this.semanticElementsProvider;
}

public Function<VariableManager, String> getHeaderLabelProvider() {
return this.headerLabelProvider;
}

public Function<VariableManager, List<String>> getHeaderIconURLsProvider() {
return this.headerIconURLsProvider;
}

public Function<VariableManager, String> getHeaderIndexLabelProvider() {
return this.headerIndexLabelProvider;
}

public static Builder newLineDescription(UUID id) {
return new Builder(id);
}
Expand All @@ -83,6 +101,12 @@ public static final class Builder {

private Function<VariableManager, List<Object>> semanticElementsProvider;

private Function<VariableManager, String> headerLabelProvider;

private Function<VariableManager, List<String>> headerIconURLsProvider;

private Function<VariableManager, String> headerIndexLabelProvider;

public Builder(UUID id) {
this.id = Objects.requireNonNull(id);
}
Expand All @@ -102,12 +126,30 @@ public Builder semanticElementsProvider(Function<VariableManager, List<Object>>
return this;
}

public Builder headerLabelProvider(Function<VariableManager, String> headerLabelProvider) {
this.headerLabelProvider = Objects.requireNonNull(headerLabelProvider);
return this;
}

public Builder headerIconURLsProvider(Function<VariableManager, List<String>> headerIconURLsProvider) {
this.headerIconURLsProvider = Objects.requireNonNull(headerIconURLsProvider);
return this;
}

public Builder headerIndexLabelProvider(Function<VariableManager, String> headerIndexLabelProvider) {
this.headerIndexLabelProvider = Objects.requireNonNull(headerIndexLabelProvider);
return this;
}

public LineDescription build() {
LineDescription lineDescription = new LineDescription();
lineDescription.id = Objects.requireNonNull(this.id);
lineDescription.targetObjectIdProvider = Objects.requireNonNull(this.targetObjectIdProvider);
lineDescription.targetObjectKindProvider = Objects.requireNonNull(this.targetObjectKindProvider);
lineDescription.semanticElementsProvider = Objects.requireNonNull(this.semanticElementsProvider);
lineDescription.headerLabelProvider = Objects.requireNonNull(this.headerLabelProvider);
lineDescription.headerIconURLsProvider = Objects.requireNonNull(this.headerIconURLsProvider);
lineDescription.headerIndexLabelProvider = Objects.requireNonNull(this.headerIndexLabelProvider);
return lineDescription;
}
}
Expand Down
Loading

0 comments on commit 6fed9f6

Please sign in to comment.