Browse Source

Add feature to disable collapsing items in TreeGrid (#8879)

Fixes #8846
tags/8.1.0.alpha3
Teemu Suo-Anttila 7 years ago
parent
commit
6384bc7dee

+ 8
- 33
client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java View File

@@ -23,10 +23,8 @@ import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Event;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.connectors.grid.GridConnector;
import com.vaadin.client.renderers.ClickableRenderer;
import com.vaadin.client.renderers.HierarchyRenderer;
import com.vaadin.client.widget.grid.EventCellReference;
import com.vaadin.client.widget.grid.GridEventHandler;
@@ -54,9 +52,6 @@ public class TreeGridConnector extends GridConnector {

private HierarchyRenderer hierarchyRenderer;

// Expander click event handling
private HandlerRegistration expanderClickHandlerRegistration;

@Override
public TreeGrid getWidget() {
return (TreeGrid) super.getWidget();
@@ -121,7 +116,7 @@ public class TreeGridConnector extends GridConnector {

private HierarchyRenderer getHierarchyRenderer() {
if (hierarchyRenderer == null) {
hierarchyRenderer = new HierarchyRenderer();
hierarchyRenderer = new HierarchyRenderer(this::setCollapsed);
}
return hierarchyRenderer;
}
@@ -130,20 +125,6 @@ public class TreeGridConnector extends GridConnector {
protected void init() {
super.init();

expanderClickHandlerRegistration = getHierarchyRenderer()
.addClickHandler(
new ClickableRenderer.RendererClickHandler<JsonObject>() {
@Override
public void onClick(
ClickableRenderer.RendererClickEvent<JsonObject> event) {
toggleCollapse(getRowKey(event.getRow()),
event.getCell().getRowIndex(),
!isCollapsed(event.getRow()));
event.stopPropagation();
event.preventDefault();
}
});

// Swap Grid's CellFocusEventHandler to this custom one
// The handler is identical to the original one except for the child
// widget check
@@ -158,13 +139,6 @@ public class TreeGridConnector extends GridConnector {
new TreeGridClickEvent(getWidget(), getEventCell(getWidget())));
}

@Override
public void onUnregister() {
super.onUnregister();

expanderClickHandlerRegistration.removeHandler();
}

private native void replaceCellFocusEventHandler(Grid<?> grid,
GridEventHandler<?> eventHandler)
/*-{
@@ -188,9 +162,10 @@ public class TreeGridConnector extends GridConnector {
return cell.getColumn().getRenderer() instanceof HierarchyRenderer;
}

private void toggleCollapse(String rowKey, int rowIndex, boolean collapse) {
private void setCollapsed(int rowIndex, boolean collapsed) {
String rowKey = getRowKey(getDataSource().getRow(rowIndex));
getRpcProxy(NodeCollapseRpc.class).setNodeCollapsed(rowKey, rowIndex,
collapse);
collapsed);
}

/**
@@ -273,15 +248,15 @@ public class TreeGridConnector extends GridConnector {
switch (domEvent.getKeyCode()) {
case KeyCodes.KEY_RIGHT:
if (!leaf && collapsed) {
toggleCollapse(getRowKey(rowData),
event.getCell().getRowIndex(), true);
setCollapsed(event.getCell().getRowIndex(),
!collapsed);
}
break;
case KeyCodes.KEY_LEFT:
if (!collapsed) {
// collapse node
toggleCollapse(getRowKey(rowData),
event.getCell().getRowIndex(), false);
setCollapsed(event.getCell().getRowIndex(),
!collapsed);
}
break;
}

+ 110
- 23
client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java View File

@@ -15,6 +15,8 @@
*/
package com.vaadin.client.renderers;

import java.util.function.BiConsumer;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -35,21 +37,55 @@ import elemental.json.JsonObject;

/**
* A renderer for displaying hierarchical columns in TreeGrid.
*
*
* @author Vaadin Ltd
* @since 8.1
*/
public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
private static final String CLASS_TREE_GRID_NODE = "v-tree-grid-node";
private static final String CLASS_TREE_GRID_EXPANDER = "v-tree-grid-expander";
private static final String CLASS_TREE_GRID_CELL_CONTENT = "v-tree-grid-cell-content";
private static final String CLASS_COLLAPSED = "collapsed";
private static final String CLASS_COLLAPSE_DISABLED = "collapse-disabled";
private static final String CLASS_EXPANDED = "expanded";
private static final String CLASS_DEPTH = "depth-";

private Renderer innerRenderer;

/**
* Constructs a HierarchyRenderer with given collapse callback. Callback is
* called when user clicks on the expander of a row. Callback is given the
* row index and the target collapsed state.
*
* @param collapseCallback
* the callback for collapsing nodes with row index
*/
public HierarchyRenderer(BiConsumer<Integer, Boolean> collapseCallback) {
addClickHandler(event -> {
try {
JsonObject row = (JsonObject) event.getRow();
// Row needs to have hierarchy description
if (!hasHierarchyData(row)) {
return;
}

JsonObject hierarchyData = getHierarchyData(row);
if ((!isCollapsed(hierarchyData)
&& !isCollapseAllowed(hierarchyData))
|| isLeaf(hierarchyData)) {
return;
}

collapseCallback.accept(event.getCell().getRowIndex(),
!isCollapsed(hierarchyData));
} finally {
event.stopPropagation();
event.preventDefault();
}
});
}

@Override
public Widget createWidget() {
return new HierarchyItem(CLASS_TREE_GRID_NODE);
@@ -63,18 +99,15 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
int depth = 0;
boolean leaf = false;
boolean collapsed = false;
if (row.hasKey(
TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION)) {
JsonObject rowDescription = row.getObject(
TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);

depth = (int) rowDescription
.getNumber(TreeGridCommunicationConstants.ROW_DEPTH);
leaf = rowDescription
.getBoolean(TreeGridCommunicationConstants.ROW_LEAF);
boolean collapseAllowed = true;
if (hasHierarchyData(row)) {
JsonObject rowDescription = getHierarchyData(row);

depth = getDepth(rowDescription);
leaf = isLeaf(rowDescription);
if (!leaf) {
collapsed = rowDescription.getBoolean(
TreeGridCommunicationConstants.ROW_COLLAPSED);
collapsed = isCollapsed(rowDescription);
collapseAllowed = isCollapseAllowed(rowDescription);
}
}

@@ -89,22 +122,64 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
cellWidget.setExpanderState(ExpanderState.EXPANDED);
}

// Render the contents of the inner renderer. For non widget renderers
// the cell reference needs to be wrapped so that its getElement method
cellWidget.setCollapseAllowed(collapseAllowed);

// Render the contents of the inner renderer. For non widget
// renderers
// the cell reference needs to be wrapped so that its getElement
// method
// returns the correct element we want to render.
if (innerRenderer instanceof WidgetRenderer) {
((WidgetRenderer) innerRenderer).render(cell, data, ((HierarchyItem) widget).content);
((WidgetRenderer) innerRenderer).render(cell, data,
((HierarchyItem) widget).content);
} else {
innerRenderer.render(new HierarchyRendererCellReferenceWrapper(cell,
((HierarchyItem) widget).content.getElement()), data);
innerRenderer.render(
new HierarchyRendererCellReferenceWrapper(cell,
((HierarchyItem) widget).content.getElement()),
data);
}
}

private int getDepth(JsonObject rowDescription) {
return (int) rowDescription
.getNumber(TreeGridCommunicationConstants.ROW_DEPTH);
}

private JsonObject getHierarchyData(JsonObject row) {
return row.getObject(
TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);
}

private boolean hasHierarchyData(JsonObject row) {
return row.hasKey(
TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);
}

private boolean isLeaf(JsonObject rowDescription) {
boolean leaf;
leaf = rowDescription
.getBoolean(TreeGridCommunicationConstants.ROW_LEAF);
return leaf;
}

private boolean isCollapseAllowed(JsonObject row) {
return row.getBoolean(
TreeGridCommunicationConstants.ROW_COLLAPSE_ALLOWED);
}

private boolean isCollapsed(JsonObject rowDescription) {
boolean collapsed;
collapsed = rowDescription
.getBoolean(TreeGridCommunicationConstants.ROW_COLLAPSED);
return collapsed;
}

/**
* Sets the renderer to be wrapped. This is the original renderer before hierarchy is applied.
* Sets the renderer to be wrapped. This is the original renderer before
* hierarchy is applied.
*
* @param innerRenderer
* Renderer to be wrapped.
* Renderer to be wrapped.
*/
public void setInnerRenderer(Renderer innerRenderer) {
this.innerRenderer = innerRenderer;
@@ -166,11 +241,13 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
}

private void setDepth(int depth) {
String classNameToBeReplaced = getFullClassName(CLASS_DEPTH, panel.getElement().getClassName());
String classNameToBeReplaced = getFullClassName(CLASS_DEPTH,
panel.getElement().getClassName());
if (classNameToBeReplaced == null) {
panel.getElement().addClassName(CLASS_DEPTH + depth);
} else {
panel.getElement().replaceClassName(classNameToBeReplaced, CLASS_DEPTH + depth);
panel.getElement().replaceClassName(classNameToBeReplaced,
CLASS_DEPTH + depth);
}
}

@@ -178,7 +255,8 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
int start = classNameList.indexOf(prefix);
int end = start + prefix.length();
if (start > -1) {
while (end < classNameList.length() && classNameList.charAt(end) != ' ') {
while (end < classNameList.length()
&& classNameList.charAt(end) != ' ') {
end++;
}
return classNameList.substring(start, end);
@@ -203,6 +281,15 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
}
}

private void setCollapseAllowed(boolean collapseAllowed) {
if (expander.getElement().hasClassName(CLASS_EXPANDED)
&& !collapseAllowed) {
expander.getElement().addClassName(CLASS_COLLAPSE_DISABLED);
} else {
expander.getElement().removeClassName(CLASS_COLLAPSE_DISABLED);
}
}

private class Expander extends Widget implements HasClickHandlers {

private Expander() {

+ 16
- 0
documentation/components/components-treegrid.asciidoc View File

@@ -93,6 +93,22 @@ treeGrid.addColumn(Project::getHoursDone).setCaption("Hours Done");
treeGrid.setHierarchyColumn("name");
----

== Prevent Node Collapsing

[classname]#TreeGrid# supports setting a callback method that can allow or prevent the user from collapsing an expanded node.
It can be set with [methodname]#setItemCollapseAllowedProvider# method, that takes a [interfacename]#SerializablePredicate#.
For nodes that cannot be collapsed, the [literal]#++collapse-disabled++# class name is applied to the expansion element

Avoid doing any heavy operations in the method, since it is called for each item when it is being sent to the client.

Example using a predefined set of persons that can not be collapsed:
[source, java]
----
Set<Person> alwaysExpanded;
personTreeGrid.setItemCollapseAllowedProvider(person ->
!alwaysExpanded.contains(person));
----

== Listening to Events

In addition to supporting all the listeners of the standard [classname]#Grid#, [classname]#TreeGrid# supports listening to the expansion and collapsing of items in its hierarchy.

+ 28
- 0
server/src/main/java/com/vaadin/data/provider/HierarchicalDataCommunicator.java View File

@@ -28,6 +28,7 @@ import java.util.stream.Stream;
import com.vaadin.data.HierarchyData;
import com.vaadin.data.provider.HierarchyMapper.TreeLevelQuery;
import com.vaadin.server.SerializableConsumer;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.shared.Range;
import com.vaadin.shared.extension.datacommunicator.HierarchicalDataCommunicatorState;
import com.vaadin.shared.ui.treegrid.TreeGridCommunicationConstants;
@@ -57,6 +58,11 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> {

private HierarchyMapper mapper = new HierarchyMapper();

/**
* Collapse allowed provider used to allow/disallow collapsing nodes.
*/
private SerializablePredicate<T> itemCollapseAllowedProvider = t -> true;

/**
* The captured client side cache size.
*/
@@ -209,6 +215,9 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> {
hierarchyData.put(TreeGridCommunicationConstants.ROW_COLLAPSED,
mapper.isCollapsed(key));
hierarchyData.put(TreeGridCommunicationConstants.ROW_LEAF, false);
hierarchyData.put(
TreeGridCommunicationConstants.ROW_COLLAPSE_ALLOWED,
itemCollapseAllowedProvider.test(item));
}

// add hierarchy information to row as metadata
@@ -386,4 +395,23 @@ public class HierarchicalDataCommunicator<T> extends DataCommunicator<T> {
refresh(expandedItem);
}

/**
* Sets the item collapse allowed provider for this
* HierarchicalDataCommunicator. The provider should return {@code true} for
* any item that the user can collapse.
* <p>
* <strong>Note:</strong> This callback will be accessed often when sending
* data to the client. The callback should not do any costly operations.
*
* @param provider
* the item collapse allowed provider, not {@code null}
*/
public void setItemCollapseAllowedProvider(
SerializablePredicate<T> provider) {
Objects.requireNonNull(provider, "Provider can't be null");
itemCollapseAllowedProvider = provider;

getActiveDataHandler().getActiveData().forEach(this::refresh);
}

}

+ 39
- 19
server/src/main/java/com/vaadin/ui/TreeGrid.java View File

@@ -35,6 +35,7 @@ import com.vaadin.data.provider.HierarchicalDataCommunicator;
import com.vaadin.data.provider.HierarchicalDataProvider;
import com.vaadin.data.provider.HierarchicalQuery;
import com.vaadin.data.provider.InMemoryHierarchicalDataProvider;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.shared.Registration;
import com.vaadin.shared.ui.treegrid.NodeCollapseRpc;
import com.vaadin.shared.ui.treegrid.TreeGridState;
@@ -58,7 +59,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Item expand event listener.
*
*
* @author Vaadin Ltd
* @since 8.1
* @param <T>
@@ -72,7 +73,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Callback method for when an item has been expanded.
*
*
* @param event
* the expand event
*/
@@ -81,7 +82,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Item collapse event listener.
*
*
* @author Vaadin Ltd
* @since 8.1
* @param <T>
@@ -95,7 +96,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Callback method for when an item has been collapsed.
*
*
* @param event
* the collapse event
*/
@@ -104,7 +105,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* An event that is fired when an item is expanded.
*
*
* @author Vaadin Ltd
* @since 8.1
* @param <T>
@@ -116,7 +117,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Construct an expand event.
*
*
* @param source
* the tree grid this event originated from
* @param item
@@ -129,7 +130,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Get the expanded item that triggered this event.
*
*
* @return the expanded item
*/
public T getExpandedItem() {
@@ -140,7 +141,7 @@ public class TreeGrid<T> extends Grid<T> {
/**
* An event that is fired when an item is collapsed. Note that expanded
* subtrees of the collapsed item will not trigger collapse events.
*
*
* @author Vaadin Ltd
* @since 8.1
* @param <T>
@@ -152,7 +153,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Construct a collapse event.
*
*
* @param source
* the tree grid this event originated from
* @param item
@@ -165,7 +166,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Get the collapsed item that triggered this event.
*
*
* @return the collapsed item
*/
public T getCollapsedItem() {
@@ -195,9 +196,9 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Adds an ExpandListener to this TreeGrid.
*
*
* @see ExpandEvent
*
*
* @param listener
* the listener to add
* @return a registration for the listener
@@ -209,9 +210,9 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Adds a CollapseListener to this TreeGrid.
*
*
* @see CollapseEvent
*
*
* @param listener
* the listener to add
* @return a registration for the listener
@@ -366,6 +367,26 @@ public class TreeGrid<T> extends Grid<T> {
getState().hierarchyColumnId = getInternalIdForColumn(getColumn(id));
}

/**
* Sets the item collapse allowed provider for this TreeGrid. The provider
* should return {@code true} for any item that the user can collapse.
* <p>
* <strong>Note:</strong> This callback will be accessed often when sending
* data to the client. The callback should not do any costly operations.
* <p>
* This method is a shortcut to method with the same name in
* {@link HierarchicalDataCommunicator}.
*
* @param provider
* the item collapse allowed provider, not {@code null}
*
* @see HierarchicalDataCommunicator#setItemCollapseAllowedProvider(SerializablePredicate)
*/
public void setItemCollapseAllowedProvider(
SerializablePredicate<T> provider) {
getDataCommunicator().setItemCollapseAllowedProvider(provider);
}

@Override
protected TreeGridState getState() {
return (TreeGridState) super.getState();
@@ -464,9 +485,8 @@ public class TreeGrid<T> extends Grid<T> {
.map(DesignFormatter::encodeForTextNode)
.orElse(""));
}
getDataProvider().fetch(new HierarchicalQuery<>(null, item))
.forEach(childItem -> writeRow(container, childItem, item,
context));
getDataProvider().fetch(new HierarchicalQuery<>(null, item)).forEach(
childItem -> writeRow(container, childItem, item, context));
}

@Override
@@ -491,7 +511,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Emit an expand event.
*
*
* @param item
* the item that was expanded
*/
@@ -501,7 +521,7 @@ public class TreeGrid<T> extends Grid<T> {

/**
* Emit a collapse event.
*
*
* @param item
* the item that was collapsed
*/

+ 2
- 1
shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridCommunicationConstants.java View File

@@ -20,7 +20,7 @@ import java.io.Serializable;
/**
* Set of contants used by TreeGrid. These are commonly used JsonObject keys
* which are considered to be reserved for internal use.
*
*
* @author Vaadin Ltd
* @since 8.1
*/
@@ -29,4 +29,5 @@ public class TreeGridCommunicationConstants implements Serializable {
public static final String ROW_DEPTH = "d";
public static final String ROW_COLLAPSED = "c";
public static final String ROW_LEAF = "l";
public static final String ROW_COLLAPSE_ALLOWED = "ca";
}

+ 7
- 6
testbench-api/src/main/java/com/vaadin/testbench/elements/TreeGridElement.java View File

@@ -15,6 +15,9 @@
*/
package com.vaadin.testbench.elements;

import java.util.Arrays;
import java.util.List;

import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;

@@ -97,8 +100,9 @@ public class TreeGridElement extends GridElement {
public boolean isRowExpanded(int rowIndex, int hierarchyColumnIndex) {
WebElement expandElement = getExpandElement(rowIndex,
hierarchyColumnIndex);
return expandElement.getAttribute("expanded") != null
&& expandElement.getAttribute("collapsed") == null;
List<String> classes = Arrays
.asList(expandElement.getAttribute("class").split(" "));
return classes.contains("expanded") && !classes.contains("collapsed");
}

/**
@@ -111,10 +115,7 @@ public class TreeGridElement extends GridElement {
* @return {@code true} if collapsed, {@code false} if expanded
*/
public boolean isRowCollapsed(int rowIndex, int hierarchyColumnIndex) {
WebElement expandElement = getExpandElement(rowIndex,
hierarchyColumnIndex);
return expandElement.getAttribute("collapsed") != null
&& expandElement.getAttribute("expanded") == null;
return !isRowExpanded(rowIndex, hierarchyColumnIndex);
}

/**

+ 5
- 0
themes/src/main/themes/VAADIN/themes/valo/components/_treegrid.scss View File

@@ -42,6 +42,11 @@ $tg-expander-padding: 10px !default;
content: $tg-expander-char-collapsed;
}
}

&.collapse-disabled {
@include opacity($v-disabled-opacity);
cursor: default;
}
}

// Hierarchy depth styling

+ 16
- 1
uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeatures.java View File

@@ -9,6 +9,7 @@ import com.vaadin.annotations.Widgetset;
import com.vaadin.data.HierarchyData;
import com.vaadin.data.provider.DataProvider;
import com.vaadin.data.provider.InMemoryHierarchicalDataProvider;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.tests.components.AbstractComponentTest;
import com.vaadin.ui.TreeGrid;

@@ -38,7 +39,8 @@ public class TreeGridBasicFeatures extends AbstractComponentTest<TreeGrid> {
grid.addColumn(HierarchicalTestBean::toString).setCaption("String")
.setId("string");
grid.addColumn(HierarchicalTestBean::getDepth).setCaption("Depth")
.setId("depth");
.setId("depth").setDescriptionGenerator(
t -> "Hierarchy depth: " + t.getDepth());
grid.addColumn(HierarchicalTestBean::getIndex)
.setCaption("Index on this depth").setId("index");
grid.setHierarchyColumn("string");
@@ -54,6 +56,7 @@ public class TreeGridBasicFeatures extends AbstractComponentTest<TreeGrid> {

createDataProviderSelect();
createHierarchyColumnSelect();
createCollapseAllowedSelect();
createListenerMenu();
}

@@ -103,6 +106,18 @@ public class TreeGridBasicFeatures extends AbstractComponentTest<TreeGrid> {
(treeGrid, value, data) -> treeGrid.setHierarchyColumn(value));
}

private void createCollapseAllowedSelect() {
LinkedHashMap<String, SerializablePredicate<HierarchicalTestBean>> options = new LinkedHashMap<>();
options.put("all allowed", t -> true);
options.put("all disabled", t -> false);
options.put("depth 0 disabled", t -> t.getDepth() != 0);
options.put("depth 1 disabled", t -> t.getDepth() != 1);

createSelectAction("Collapse allowed", CATEGORY_FEATURES, options,
"all allowed", (treeGrid, value, data) -> treeGrid
.setItemCollapseAllowedProvider(value));
}

@SuppressWarnings("unchecked")
private void createListenerMenu() {
createListenerAction("Collapse listener", "State",

+ 2
- 2
uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridBasicFeaturesTest.java View File

@@ -127,7 +127,7 @@ public class TreeGridBasicFeaturesTest extends MultiBrowserTest {
Assert.assertFalse(logContainsText("Item expanded: 0 | 0"));
Assert.assertFalse(logContainsText("Item collapsed: 0 | 0"));

grid.collapseWithClick(0);
grid.expandWithClick(0);

Assert.assertTrue(logContainsText("Item expanded: 0 | 0"));
Assert.assertFalse(logContainsText("Item collapsed: 0 | 0"));
@@ -140,7 +140,7 @@ public class TreeGridBasicFeaturesTest extends MultiBrowserTest {
selectMenuPath("Component", "State", "Expand listener");
selectMenuPath("Component", "State", "Collapse listener");

grid.collapseWithClick(1);
grid.expandWithClick(1);
grid.collapseWithClick(1);

Assert.assertFalse(logContainsText("Item expanded: 0 | 1"));

+ 111
- 0
uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridCollapseDisabledTest.java View File

@@ -0,0 +1,111 @@
package com.vaadin.tests.components.treegrid;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.vaadin.testbench.elements.TreeGridElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class TreeGridCollapseDisabledTest extends SingleBrowserTest {

private TreeGridElement grid;

@Override
protected Class<?> getUIClass() {
return TreeGridBasicFeatures.class;
}

@Before
public void before() {
openTestURL();
grid = $(TreeGridElement.class).first();
}

@Test
public void collapse_disabled_for_all() {
selectMenuPath("Component", "Features", "Collapse allowed",
"all disabled");

// Assert first and second row can be expanded, but not collapsed
assertExpandRow(0);
assertCollapseRowDisabled(0);

assertExpandRow(1);
assertCollapseRowDisabled(1);
}

@Test
public void collapse_disabled_for_depth0() {
selectMenuPath("Component", "Features", "Collapse allowed",
"depth 0 disabled");

// Assert first row expands
assertExpandRow(0);

// Assert second row expands and collapses
assertExpandRow(1);
assertCollapseRow(1);

// Assert first row does not collapse
assertCollapseRowDisabled(0);
}

@Test
public void collapse_disabled_for_depth1() {
selectMenuPath("Component", "Features", "Collapse allowed",
"depth 1 disabled");

// Assert first row expands
assertExpandRow(0);

// Assert second row expands but does not collapse
assertExpandRow(1);
assertCollapseRowDisabled(1);

// Assert first row still collapses
assertCollapseRow(0);
}

@Test
public void collapse_disabled_mode_change_with_expanded_rows() {
// Assert first row expands
assertExpandRow(0);

// Assert second row expands and collapses
assertExpandRow(1);
assertCollapseRow(1);

selectMenuPath("Component", "Features", "Collapse allowed",
"depth 1 disabled");

Assert.assertTrue("First row should still be expanded",
grid.isRowExpanded(0, 0));

// Assert second row expands but does not collapse
assertExpandRow(1);
assertCollapseRowDisabled(1);

// Assert first row still collapses
assertCollapseRow(0);
}

private void assertExpandRow(int row) {
Assert.assertFalse(grid.isRowExpanded(row, 0));
grid.expandWithClick(row);
Assert.assertTrue(grid.isRowExpanded(row, 0));
}

private void assertCollapseRow(int row) {
Assert.assertTrue("Row not expanded", grid.isRowExpanded(row, 0));
grid.collapseWithClick(row);
Assert.assertFalse("Row did not collapse", grid.isRowExpanded(row, 0));
}

private void assertCollapseRowDisabled(int row) {
Assert.assertTrue("Row not expanded", grid.isRowExpanded(row, 0));
grid.collapseWithClick(row);
Assert.assertTrue("Row should not collapse",
grid.isRowExpanded(row, 0));
}
}

+ 2
- 2
uitest/src/test/java/com/vaadin/tests/components/treegrid/TreeGridScrollingTest.java View File

@@ -129,7 +129,7 @@ public class TreeGridScrollingTest extends SingleBrowserTest {
verifyRow(1, 1, 0);
verifyRow(0, 0, 0);

grid.expandWithClick(3);
grid.collapseWithClick(3);

verifyRow(0, 0, 0);
verifyRow(1, 1, 0);
@@ -144,7 +144,7 @@ public class TreeGridScrollingTest extends SingleBrowserTest {
verifyRow(1, 1, 0);
verifyRow(0, 0, 0);

grid.expandWithClick(0);
grid.collapseWithClick(0);

verifyRow(0, 0, 0);
verifyRow(10, 0, 10);

Loading…
Cancel
Save