Skip to content

Commit

Permalink
feat: Add lazy support to available items grid
Browse files Browse the repository at this point in the history
Close #130
  • Loading branch information
flang committed Feb 23, 2023
1 parent 5b04684 commit 15ebc2c
Show file tree
Hide file tree
Showing 17 changed files with 865 additions and 451 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.flowingcode.vaadin.addons</groupId>
<artifactId>twincolgrid</artifactId>
<version>2.9.3-SNAPSHOT</version>
<version>3.0.0-SNAPSHOT</version>
<name>TwinColGrid add-on</name>
<properties>
<vaadin.version>14.8.1</vaadin.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.flowingcode.vaadin.addons.twincolgrid;

import com.vaadin.flow.component.ItemLabelGenerator;
import com.vaadin.flow.function.SerializableBiPredicate;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;

@RequiredArgsConstructor
@Getter
@Setter
@Accessors(fluent = true)
public class EagerFilterableColumn<T> {

private final ItemLabelGenerator<T> itemLabelGenerator;
private final String header;
private final String filterPlaceholder;
private final boolean enableClearButton;
private final SerializableBiPredicate<T, String> filterCondition;
private String key;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.flowingcode.vaadin.addons.twincolgrid;

import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.Grid.Column;
import com.vaadin.flow.component.grid.HeaderRow;
import com.vaadin.flow.component.grid.ItemDoubleClickEvent;
import com.vaadin.flow.component.grid.dnd.GridDropLocation;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.provider.DataProvider;
import com.vaadin.flow.data.provider.ListDataProvider;
import com.vaadin.flow.data.renderer.TextRenderer;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.shared.Registration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import lombok.NonNull;

public class EagerTwinColModel<T> implements TwinColModel<T> {

private final Grid<T> grid;
private final Label columnLabel = new Label();
private final VerticalLayout layout;
private HeaderRow headerRow;
private boolean droppedInsideGrid = false;
private boolean allowReordering = false;
private Registration moveItemsByDoubleClick;

EagerTwinColModel(@NonNull Grid<T> grid, String className) {
this.grid = grid;
this.grid.setDataProvider(DataProvider.ofCollection(new ArrayList<>()));

layout = new VerticalLayout(columnLabel, grid);

layout.setClassName(className);
grid.setClassName("twincol-grid-items");
columnLabel.setClassName("twincol-grid-label");
}

@Override
@SuppressWarnings("unchecked")
public ListDataProvider<T> getDataProvider() {
return (ListDataProvider<T>) grid.getDataProvider();
}

@Override
public boolean isReorderingEnabled() {
return allowReordering && grid.getSortOrder().isEmpty();
}

@Override
public Grid<T> getGrid() {
return grid;
}

@Override
public Label getColumnLabel() {
return columnLabel;
}

@Override
public boolean isDroppedInsideGrid() {
return droppedInsideGrid;
}

@Override
public void setDroppedInsideGrid(boolean droppedInsideGrid) {
this.droppedInsideGrid = droppedInsideGrid;
}

@Override
public void setAllowReordering(boolean allowReordering) {
this.allowReordering = allowReordering;
}

@Override
public boolean isAllowReordering() {
return allowReordering;
}

@Override
public HeaderRow getHeaderRow() {
return headerRow;
}

@Override
public void setHeaderRow(HeaderRow headerRow) {
this.headerRow = headerRow;
}

@Override
public Registration getMoveItemsByDoubleClick() {
return moveItemsByDoubleClick;
}

@Override
public Registration addItemDoubleClickListener(
ComponentEventListener<ItemDoubleClickEvent<T>> listener) {
moveItemsByDoubleClick = grid.addItemDoubleClickListener(listener);
return moveItemsByDoubleClick;
}

@Override
public void removeItemDoubleClickListener() {
if (moveItemsByDoubleClick != null) {
moveItemsByDoubleClick.remove();
moveItemsByDoubleClick = null;
}
}

@Override
public VerticalLayout getLayout() {
return layout;
}

@Override
public void addAll(Collection<T> items) {
getDataProvider().getItems().addAll(items);
}

@Override
public void removeAll(Collection<T> items) {
getDataProvider().getItems().removeAll(items);
}

@Override
public void clear() {
getDataProvider().getItems().clear();
}

public void addFilterableColumn(EagerFilterableColumn<T> filter) {
Column<T> column =
grid.addColumn(new TextRenderer<>(filter.itemLabelGenerator())).setHeader(filter.header());

Optional.ofNullable(filter.key()).ifPresent(column::setKey);

TextField filterField = new TextField();
filterField.setClearButtonVisible(filter.enableClearButton());

filterField.addValueChangeListener(
event -> getDataProvider()
.addFilter(item -> filter.filterCondition().test(item, filterField.getValue())));

if (headerRow == null) {
setHeaderRow(grid.appendHeaderRow());
}

headerRow.getCell(column).setComponent(filterField);
filterField.setValueChangeMode(ValueChangeMode.EAGER);
filterField.setSizeFull();
filterField.setPlaceholder(filter.filterPlaceholder());
}

public void addItems(Collection<T> draggedItems,
T dropOverItem, GridDropLocation dropLocation) {
if (dropOverItem != null) {
Collection<T> collection = getDataProvider().getItems();
List<T> list = new ArrayList<>(collection);
int dropIndex = list.indexOf(dropOverItem) + (dropLocation == GridDropLocation.BELOW ? 1 : 0);
list.addAll(dropIndex, draggedItems);
clear();
addAll(list);
} else {
addAll(draggedItems);
}
grid.getDataProvider().refreshAll();
}

public Collection<T> getItems() {
return getDataProvider().getItems();
}

@Override
public TwinColModelMode getMode() {
return TwinColModelMode.EAGER;
}

@Override
public boolean supportsAddAll() {
return true;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.flowingcode.vaadin.addons.twincolgrid;

import java.util.Collection;
import java.util.HashSet;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class LazyFilter<T> {

private Collection<T> excludedItems = new HashSet<>();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.flowingcode.vaadin.addons.twincolgrid;

import com.vaadin.flow.component.ItemLabelGenerator;
import com.vaadin.flow.function.SerializableBiPredicate;
import com.vaadin.flow.function.SerializableConsumer;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;

@RequiredArgsConstructor
@Getter
@Accessors(fluent = true)
@Setter
public class LazyFilterableColumn<T> {

private final ItemLabelGenerator<T> itemLabelGenerator;
private final String header;
private final String filterPlaceholder;
private final boolean enableClearButton;
private String key;
private SerializableConsumer<String> lazyFilterAttribute;
private SerializableBiPredicate<T, String> eagerFilterCondition;

public EagerFilterableColumn<T> asEager() {
return new EagerFilterableColumn<>(itemLabelGenerator, header, filterPlaceholder,
enableClearButton, eagerFilterCondition);
}

}
Loading

0 comments on commit 15ebc2c

Please sign in to comment.