From 3017820a537808c3b6baa337a17f2a8f1585d543 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Tue, 6 Sep 2016 17:00:26 +0300 Subject: [PATCH] Add DescriptionGenerators for Grid and Columns Change-Id: Ib32726ba3297a05cbc05898f37579777b9a921e0 --- .../client/connectors/grid/GridConnector.java | 43 ++++++++++ server/src/main/java/com/vaadin/ui/Grid.java | 84 ++++++++++++++++++- .../components/grid/basics/GridBasics.java | 13 +++ .../basics/GridDescriptionGeneratorTest.java | 74 ++++++++++++++++ 4 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridDescriptionGeneratorTest.java diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java index 880de07d55..006aa65318 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java @@ -21,15 +21,18 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.google.gwt.dom.client.Element; import com.google.gwt.event.shared.HandlerRegistration; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler; import com.vaadin.client.DeferredWorker; import com.vaadin.client.HasComponentsConnector; +import com.vaadin.client.TooltipInfo; import com.vaadin.client.connectors.AbstractListingConnector; import com.vaadin.client.data.DataSource; import com.vaadin.client.ui.SimpleManagedLayout; +import com.vaadin.client.widget.grid.CellReference; import com.vaadin.client.widget.grid.selection.ClickSelectHandler; import com.vaadin.client.widget.grid.selection.SpaceSelectHandler; import com.vaadin.client.widget.grid.sort.SortEvent; @@ -235,4 +238,44 @@ public class GridConnector clickSelectHandler = null; } } + + @Override + public boolean hasTooltip() { + // Always check for generated descriptions. + return true; + } + + @Override + public TooltipInfo getTooltipInfo(Element element) { + CellReference cell = getWidget().getCellReference(element); + + if (cell != null) { + JsonObject row = cell.getRow(); + + if (row != null && (row.hasKey(GridState.JSONKEY_ROWDESCRIPTION) + || row.hasKey(GridState.JSONKEY_CELLDESCRIPTION))) { + + Column column = cell.getColumn(); + if (columnToIdMap.containsKey(column)) { + JsonObject cellDescriptions = row + .getObject(GridState.JSONKEY_CELLDESCRIPTION); + + String id = columnToIdMap.get(column); + if (cellDescriptions != null + && cellDescriptions.hasKey(id)) { + return new TooltipInfo(cellDescriptions.getString(id)); + } else if (row.hasKey(GridState.JSONKEY_ROWDESCRIPTION)) { + return new TooltipInfo(row + .getString(GridState.JSONKEY_ROWDESCRIPTION)); + } + } + } + } + + if (super.hasTooltip()) { + return super.getTooltipInfo(element); + } else { + return null; + } + } } diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 96d7376816..4a12099977 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -24,6 +24,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -73,6 +74,17 @@ public class Grid extends AbstractListing> extends Function, Serializable { } + /** + * A callback interface for generating description texts for an item. + * + * @param + * the grid bean type + */ + @FunctionalInterface + public interface DescriptionGenerator + extends Function, Serializable { + } + /** * A callback interface for generating details for a particular row in Grid. * @@ -320,6 +332,7 @@ public class Grid extends AbstractListing> private Function>> sortOrderProvider; private Comparator comparator; private StyleGenerator styleGenerator; + private DescriptionGenerator descriptionGenerator; /** * Constructs a new Column configuration with given header caption, @@ -424,7 +437,15 @@ public class Grid extends AbstractListing> if (style != null && !style.isEmpty()) { JsonObject styleObj = getDataObject(jsonObject, GridState.JSONKEY_CELLSTYLES); - styleObj.put(getState(false).id, style); + styleObj.put(communicationId, style); + } + } + if (descriptionGenerator != null) { + String description = descriptionGenerator.apply(data); + if (description != null && !description.isEmpty()) { + JsonObject descriptionObj = getDataObject(jsonObject, + GridState.JSONKEY_CELLDESCRIPTION); + descriptionObj.put(communicationId, description); } } } @@ -627,14 +648,42 @@ public class Grid extends AbstractListing> public StyleGenerator getStyleGenerator() { return styleGenerator; } + + /** + * Sets the description generator that is used for generating + * descriptions for cells in this column. + * + * @param cellDescriptionGenerator + * the cell description generator to set, or + * null to remove a previously set generator + * @return this column + */ + public Column setDescriptionGenerator( + DescriptionGenerator cellDescriptionGenerator) { + this.descriptionGenerator = cellDescriptionGenerator; + getParent().getDataCommunicator().reset(); + return this; + } + + /** + * Gets the description generator that is used for generating + * descriptions for cells. + * + * @return the cell description generator, or null if no + * generator is set + */ + public DescriptionGenerator getDescriptionGenerator() { + return descriptionGenerator; + } } private KeyMapper> columnKeys = new KeyMapper<>(); - private Set> columnSet = new HashSet<>(); + private Set> columnSet = new LinkedHashSet<>(); private List>> sortOrder = new ArrayList<>(); private DetailsManager detailsManager; private Set extensionComponents = new HashSet<>(); private StyleGenerator styleGenerator; + private DescriptionGenerator descriptionGenerator; /** * Constructor for the {@link Grid} component. @@ -652,6 +701,12 @@ public class Grid extends AbstractListing> json.put(GridState.JSONKEY_ROWSTYLE, styleName); } } + if (descriptionGenerator != null) { + String description = descriptionGenerator.apply(item); + if (description != null && !description.isEmpty()) { + json.put(GridState.JSONKEY_ROWDESCRIPTION, description); + } + } }); } @@ -922,6 +977,31 @@ public class Grid extends AbstractListing> return styleGenerator; } + /** + * Sets the description generator that is used for generating descriptions + * for rows. + * + * @param descriptionGenerator + * the row description generator to set, or null to + * remove a previously set generator + */ + public void setDescriptionGenerator( + DescriptionGenerator descriptionGenerator) { + this.descriptionGenerator = descriptionGenerator; + getDataCommunicator().reset(); + } + + /** + * Gets the description generator that is used for generating descriptions + * for rows. + * + * @return the row description generator, or null if no + * generator is set + */ + public DescriptionGenerator getDescriptionGenerator() { + return descriptionGenerator; + } + @Override protected GridState getState() { return getState(true); diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java index 5c9f03336e..8c4aa4eec0 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java @@ -188,6 +188,19 @@ public class GridBasics extends AbstractTestUIWithLog { } createRowStyleMenu(stateMenu.addItem("Row style generator", null)); createCellStyleMenu(stateMenu.addItem("Cell style generator", null)); + stateMenu.addItem("Row description generator", + item -> grid.setDescriptionGenerator(item.isChecked() + ? t -> "Row tooltip for row " + t.getRowNumber() + : null)) + .setCheckable(true); + stateMenu + .addItem("Cell description generator", item -> grid.getColumns() + .stream().findFirst() + .ifPresent(c -> c.setDescriptionGenerator( + item.isChecked() ? t -> "Cell tooltip for row " + + t.getRowNumber() + ", Column 0" + : null))) + .setCheckable(true); } private void createRowStyleMenu(MenuItem rowStyleMenu) { diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridDescriptionGeneratorTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridDescriptionGeneratorTest.java new file mode 100644 index 0000000000..58ded39798 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridDescriptionGeneratorTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; + +public class GridDescriptionGeneratorTest extends GridBasicsTest { + + @Test + public void testCellDescription() { + openTestURL(); + selectMenuPath("Component", "State", "Cell description generator"); + + getGridElement().getCell(1, 0).showTooltip(); + String tooltipText = findElement(By.className("v-tooltip-text")) + .getText(); + assertEquals("Tooltip text", "Cell tooltip for row 1, Column 0", + tooltipText); + + getGridElement().getCell(1, 1).showTooltip(); + assertTrue("Tooltip should not be present in cell (1, 1) ", + findElement(By.className("v-tooltip-text")).getText() + .isEmpty()); + } + + @Test + public void testRowDescription() { + openTestURL(); + selectMenuPath("Component", "State", "Row description generator"); + + getGridElement().getCell(5, 3).showTooltip(); + String tooltipText = findElement(By.className("v-tooltip-text")) + .getText(); + assertEquals("Tooltip text", "Row tooltip for row 5", tooltipText); + + getGridElement().getCell(15, 3).showTooltip(); + tooltipText = findElement(By.className("v-tooltip-text")).getText(); + assertEquals("Tooltip text", "Row tooltip for row 15", tooltipText); + } + + @Test + public void testRowAndCellDescription() { + openTestURL(); + selectMenuPath("Component", "State", "Row description generator"); + selectMenuPath("Component", "State", "Cell description generator"); + + getGridElement().getCell(5, 0).showTooltip(); + String tooltipText = findElement(By.className("v-tooltip-text")) + .getText(); + assertEquals("Tooltip text", "Cell tooltip for row 5, Column 0", + tooltipText); + + getGridElement().getCell(5, 3).showTooltip(); + tooltipText = findElement(By.className("v-tooltip-text")).getText(); + assertEquals("Tooltip text", "Row tooltip for row 5", tooltipText); + } +} -- 2.39.5