Skip to content

Commit

Permalink
Merge pull request #74 from FlowingCode/sort
Browse files Browse the repository at this point in the history
feat: extend selection semantics to support ordered value along with UI to adjust
  • Loading branch information
paodb authored Jul 23, 2021
2 parents 114f771 + aa94498 commit 5da756b
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 61 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ rebel.xml
/webpack.generated.js
/package.json
/bin/
/.npmrc
/frontend/generated/vaadin.ts
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.vaadin.flow.data.renderer.TextRenderer;
import com.vaadin.flow.data.selection.SelectionListener;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.function.SerializableComparator;
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.shared.Registration;
import java.io.Serializable;
Expand All @@ -52,9 +53,11 @@
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -64,8 +67,15 @@
public class TwinColGrid<T> extends VerticalLayout
implements HasValue<ValueChangeEvent<Set<T>>, Set<T>>, HasComponents, HasSize {

private static final class GridEx<T> extends Grid<T> {
@Override
protected SerializableComparator<T> createSortingComparator() {
return super.createSortingComparator();
}
}

private static final class TwinColModel<T> implements Serializable {
final Grid<T> grid = new Grid<>();
final GridEx<T> grid = new GridEx<>();
final Label columnLabel = new Label();
final VerticalLayout layout = new VerticalLayout(columnLabel, grid);
HeaderRow headerRow;
Expand Down Expand Up @@ -471,7 +481,23 @@ public void setValue(final Set<T> value) {
*/
@Override
public Set<T> getValue() {
return Collections.unmodifiableSet(new LinkedHashSet<>(right.getItems()));
return Collections
.unmodifiableSet(collectValue(Collectors.<T, Set<T>>toCollection(LinkedHashSet::new)));
}

/**
* Collects the current value of this object according to the configured order.
*
* @return the current selection
*/
<C> C collectValue(Collector<T, ?, C> collector) {
Stream<T> stream = right.getItems().stream();
SerializableComparator<T> comparator = right.grid.createSortingComparator();
if (comparator != null) {
return stream.sorted(comparator).collect(collector);
} else {
return stream.collect(collector);
}
}

@Override
Expand Down Expand Up @@ -648,4 +674,13 @@ public TwinColGrid<T> selectRowOnClick() {
});
return this;
}

public HasValue<? extends ValueChangeEvent<List<T>>, List<T>> asList() {
return new TwinColGridListAdapter<>(this);
}

@Override
public Set<T> getEmptyValue() {
return Collections.emptySet();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*-
* #%L
* TwinColGrid add-on
* %%
* Copyright (C) 2017 - 2021 Flowing Code
* %%
* 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.
* #L%
*/
package com.flowingcode.vaadin.addons.twincolgrid;

import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.component.HasValue.ValueChangeEvent;
import com.vaadin.flow.shared.Registration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;

/**
* Expose {@link TwinColGrid} as a {@code HasValue} of {@code List}
*
* @author Javier Godoy
*/
@SuppressWarnings("serial")
@RequiredArgsConstructor
class TwinColGridListAdapter<T> implements HasValue<ValueChangeEvent<List<T>>, List<T>> {

private interface IDelegate {
boolean isEmpty();

void clear();

void setReadOnly(boolean readOnly);

boolean isReadOnly();

void setRequiredIndicatorVisible(boolean requiredIndicatorVisible);

boolean isRequiredIndicatorVisible();
}

@Getter
@AllArgsConstructor
private final class ValueChangeEventImpl implements ValueChangeEvent<List<T>> {

boolean isFromClient;
List<T> value;

@Override
public HasValue<?, List<T>> getHasValue() {
return TwinColGridListAdapter.this;
}

@Override
public List<T> getOldValue() {
return null;
}

}

@NonNull
@Delegate(types = IDelegate.class)
private final TwinColGrid<T> delegate;

@Override
public void setValue(List<T> value) {
delegate.setValue(new LinkedHashSet<>(value));
}

@Override
public List<T> getValue() {
return Collections.unmodifiableList(delegate.collectValue(Collectors.toList()));
}

@Override
public Registration addValueChangeListener(
ValueChangeListener<? super ValueChangeEvent<List<T>>> listener) {

List<Registration> registrations = new ArrayList<>();

registrations.add(delegate.addValueChangeListener(ev -> {
List<T> value = new ArrayList<>(ev.getValue());
ValueChangeEvent<List<T>> listEvent;
listEvent = new ValueChangeEventImpl(ev.isFromClient(), new ArrayList<>(value));
listener.valueChanged(listEvent);
}));

// sorting the grid changes its value under List::equals
registrations.add(delegate.getRightGrid().addSortListener(ev -> {
List<T> value = getValue();
ValueChangeEvent<List<T>> listEvent;
listEvent = new ValueChangeEventImpl(ev.isFromClient(), value);
listener.valueChanged(listEvent);
}));

return () -> registrations.forEach(Registration::remove);
}

@Override
public List<T> getEmptyValue() {
return Collections.emptyList();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,50 +20,67 @@

package com.flowingcode.vaadin.addons.twincolgrid;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.Notification.Position;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.binder.Binder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

@SuppressWarnings("serial")
public class BoundDemo extends VerticalLayout {

private final List<Book> selectedBooks = new ArrayList<>();
private final List<Book> availableBooks = new ArrayList<>();

public BoundDemo() {
final Set<Book> selectedBooks = new HashSet<>();
selectedBooks.add(new Book("1478375108", "Vaadin Recipes"));
selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));
initializeData();
final Library library = new Library("Public Library", selectedBooks);

final List<Book> availableBooks = new ArrayList<>();
availableBooks.add(new Book("1478375108", "Vaadin Recipes"));
availableBooks.add(new Book("9781849515221", "Learning Vaadin"));
availableBooks.add(
new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner�s Guide"));
availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook"));
availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision"));
availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));
availableBooks.add(new Book("9529267533", "Book of Vaadin"));
availableBooks.add(new Book("1782169776", "Learning Vaadin 7, Second Edition"));

// Binded
final TwinColGrid<Book> bindedTwinColGrid =
final TwinColGrid<Book> twinColGrid =
new TwinColGrid<>(
availableBooks, "TwinColGrid demo with Binder and row select without checkbox")
.addColumn(Book::getIsbn, "ISBN")
.addColumn(Book::getTitle, "Title")
.addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
.addSortableColumn(Book::getTitle, Comparator.comparing(Book::getTitle), "Title")
.withLeftColumnCaption("Available books")
.withRightColumnCaption("Added books")
.withoutRemoveAllButton()
.withSizeFull()
.selectRowOnClick();

final Binder<Library> binder = new Binder<>();
binder.bind(bindedTwinColGrid, Library::getBooks, Library::setBooks);
binder.bind(twinColGrid.asList(), Library::getBooks, Library::setBooks);
binder.setBean(library);

add(bindedTwinColGrid);
add(twinColGrid);
add(new Button("Get values", ev -> {
binder.getBean().getBooks()
.forEach(book -> Notification.show(book.getTitle(), 3000, Position.BOTTOM_START));
}));

add(new Button("Clear TwinColGrid", ev -> {
twinColGrid.clear();
}));

setSizeFull();
}

private void initializeData() {
selectedBooks.add(new Book("1478375108", "Vaadin Recipes"));
selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));


availableBooks.add(new Book("1478375108", "Vaadin Recipes"));
availableBooks.add(new Book("9781849515221", "Learning Vaadin"));
availableBooks
.add(new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide"));
availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook"));
availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision"));
availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));
availableBooks.add(new Book("9529267533", "Book of Vaadin"));
availableBooks.add(new Book("1782169776", "Learning Vaadin 7, Second Edition"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,13 @@

@SuppressWarnings("serial")
public class DragAndDropDemo extends VerticalLayout {
public DragAndDropDemo() {
final Set<Book> selectedBooks = new HashSet<>();
selectedBooks.add(new Book("1478375108", "Vaadin Recipes"));
selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));

final List<Book> availableBooks = new ArrayList<>();
availableBooks.add(new Book("1478375108", "Vaadin Recipes"));
availableBooks.add(new Book("9781849515221", "Learning Vaadin"));
availableBooks.add(
new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner�s Guide"));
availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook"));
availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision"));
availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));
availableBooks.add(new Book("9529267533", "Book of Vaadin"));
availableBooks.add(new Book("1782169776", "Learning Vaadin 7, Second Edition"));
private final Set<Book> selectedBooks = new HashSet<>();
private final List<Book> availableBooks = new ArrayList<>();

public DragAndDropDemo() {
initializeData();

// Drag and drop
final TwinColGrid<Book> twinColGrid =
new TwinColGrid<>(availableBooks, "TwinColGrid demo with drag and drop support")
.addSortableColumn(Book::getIsbn, Comparator.comparing(Book::getIsbn), "ISBN")
Expand All @@ -67,4 +57,20 @@ public DragAndDropDemo() {
add(twinColGrid, countLabel);
setSizeFull();
}

private void initializeData() {
selectedBooks.add(new Book("1478375108", "Vaadin Recipes"));
selectedBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));


availableBooks.add(new Book("1478375108", "Vaadin Recipes"));
availableBooks.add(new Book("9781849515221", "Learning Vaadin"));
availableBooks
.add(new Book("9781782162261", "Vaadin 7 UI Design By Example: Beginner\u2019s Guide"));
availableBooks.add(new Book("9781849518802", "Vaadin 7 Cookbook"));
availableBooks.add(new Book("9526800605", "Book of Vaadin: 7th Edition, 1st Revision"));
availableBooks.add(new Book("9789526800677", "Book of Vaadin: Volume 2 "));
availableBooks.add(new Book("9529267533", "Book of Vaadin"));
availableBooks.add(new Book("1782169776", "Learning Vaadin 7, Second Edition"));
}
}
Loading

0 comments on commit 5da756b

Please sign in to comment.