fix showing solved bugs

This commit is contained in:
f43nd1r 2018-05-30 17:35:52 +02:00
parent aeaff00798
commit 589bb861b4
9 changed files with 103 additions and 199 deletions

View file

@ -1,96 +0,0 @@
package com.faendir.acra.dataprovider;
import com.faendir.acra.config.AcraConfiguration;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import com.vaadin.data.provider.QuerySortOrder;
import com.vaadin.shared.data.sort.SortDirection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntSupplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Lukas
* @since 13.12.2017
*/
public class BufferedDataProvider<T> extends AbstractBackEndDataProvider<T, Void> implements ObservableDataProvider<T, Void> {
private final int pageSize;
private final Function<Pageable, Slice<T>> getter;
private final IntSupplier counter;
private final List<SizeListener> sizeListeners;
public BufferedDataProvider(int pageSize, Function<Pageable, Slice<T>> getter, IntSupplier counter) {
this.getter = getter;
this.counter = counter;
this.pageSize = pageSize;
this.sizeListeners = new ArrayList<>();
}
@Override
protected Stream<T> fetchFromBackEnd(Query<T, Void> query) {
Sort sort = Sort.by(query.getSortOrders().stream().map(OrderAdapter::new).collect(Collectors.toList()));
Slice<T> slice = getter.apply(PageRequest.of(query.getOffset() / pageSize, pageSize, sort));
if (!slice.hasContent()) return Stream.empty();
List<T> content = slice.getContent();
int ignore = query.getOffset() % pageSize;
int size = content.size() - ignore;
Stream<T> result = content.stream().skip(ignore);
while (size < query.getLimit() && slice.hasNext()) {
slice = getter.apply(slice.nextPageable());
if (slice.hasContent()) {
content = slice.getContent();
size += content.size();
result = Stream.concat(result, content.stream());
}
}
return result;
}
@Override
protected int sizeInBackEnd(Query<T, Void> query) {
int result = counter.getAsInt();
sizeListeners.forEach(listener -> listener.sizeChanged(result));
return result;
}
@Override
public void addSizeListener(SizeListener listener) {
sizeListeners.add(listener);
}
@Override
public void removeSizeListener(SizeListener listener) {
sizeListeners.remove(listener);
}
@Component
public static class Factory {
private final AcraConfiguration configuration;
@Autowired
public Factory(AcraConfiguration configuration) {
this.configuration = configuration;
}
public <P, T> BufferedDataProvider<T> create(P parameter, BiFunction<P, Pageable, Slice<T>> getter, Function<P, Integer> counter) {
return new BufferedDataProvider<>(configuration.getPaginationSize(), pageable -> getter.apply(parameter, pageable), () -> counter.apply(parameter));
}
}
private static class OrderAdapter extends Sort.Order {
OrderAdapter(QuerySortOrder adapt) {
super(adapt.getDirection() == SortDirection.ASCENDING ? Sort.Direction.ASC : Sort.Direction.DESC, adapt.getSorted());
}
}
}

View file

@ -1,17 +0,0 @@
package com.faendir.acra.dataprovider;
import com.vaadin.data.provider.DataProvider;
/**
* @author Lukas
* @since 06.01.2018
*/
public interface ObservableDataProvider<T,F> extends DataProvider<T,F> {
void addSizeListener(SizeListener listener);
void removeSizeListener(SizeListener listener);
interface SizeListener {
void sizeChanged(int size);
}
}

View file

@ -13,16 +13,17 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Stream;
/**
* @author lukas
* @since 30.05.18
*/
public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void> implements ObservableDataProvider<T, Void> {
public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void> {
private final List<SizeListener> sizeListeners;
private final JPAQuery<T> fetchBase;
private final JPAQuery<?> countBase;
private final Supplier<JPAQuery<T>> fetchProvider;
private final Supplier<JPAQuery<?>> countProvider;
private final Map<String, Expression<? extends Comparable>> sortOptions;
public QueryDslDataProvider(JPAQuery<T> base) {
@ -30,22 +31,20 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
}
public QueryDslDataProvider(JPAQuery<T> fetchBase, JPAQuery<?> countBase) {
this.fetchBase = fetchBase;
this.countBase = countBase;
this(fetchBase::clone, countBase::clone);
}
public QueryDslDataProvider(Supplier<JPAQuery<T>> fetchProvider, Supplier<JPAQuery<?>> countProvider){
this.fetchProvider = fetchProvider;
this.countProvider = countProvider;
sizeListeners = new ArrayList<>();
sortOptions = new HashMap<>();
}
@Override
public void addSizeListener(SizeListener listener) {
sizeListeners.add(listener);
}
@Override
public void removeSizeListener(SizeListener listener) {
sizeListeners.remove(listener);
}
public String addSortable(Expression<? extends Comparable> expression) {
String id = String.valueOf(sortOptions.size());
sortOptions.put(id, expression);
@ -54,7 +53,7 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
@Override
protected Stream<T> fetchFromBackEnd(Query<T, Void> query) {
JPAQuery<T> q = fetchBase.clone().offset(query.getOffset()).limit(query.getLimit());
JPAQuery<T> q = fetchProvider.get().offset(query.getOffset()).limit(query.getLimit());
for (QuerySortOrder order : query.getSortOrders()) {
Expression<? extends Comparable> sort = sortOptions.get(order.getSorted());
if (sort != null) {
@ -66,8 +65,13 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
@Override
protected int sizeInBackEnd(Query<T, Void> query) {
int result = Math.toIntExact(countBase.fetchCount());
int result = Math.toIntExact(countProvider.get().fetchCount());
sizeListeners.forEach(listener -> listener.sizeChanged(result));
return result;
}
@FunctionalInterface
public interface SizeListener {
void sizeChanged(int size);
}
}

View file

@ -1,33 +1,31 @@
package com.faendir.acra.model.view;
import com.faendir.acra.model.QApp;
import com.faendir.acra.model.QBug;
import com.faendir.acra.model.QReport;
import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.lang.NonNull;
import javax.persistence.EntityManager;
import static com.faendir.acra.model.QApp.app;
import static com.faendir.acra.model.QBug.bug;
import static com.faendir.acra.model.QReport.report;
/**
* @author lukas
* @since 30.05.18
*/
public abstract class Queries {
private static final QApp APP = QApp.app;
private static final QReport REPORT = QReport.report;
private static final QBug BUG = QBug.bug;
private static final JPAQuery<VBug> V_BUG = new JPAQuery<>().from(BUG)
.join(REPORT)
.on(REPORT.bug.eq(BUG))
.select(new QVBug(BUG, REPORT.date.max(), REPORT.count()))
.groupBy(BUG);
private static final JPAQuery<VApp> V_APP = new JPAQuery<>().from(APP)
.join(BUG)
.on(BUG.app.eq(APP))
.join(REPORT)
.on(REPORT.bug.eq(BUG))
.select(new QVApp(APP, REPORT.count()))
.groupBy(APP);
private static final JPAQuery<VBug> V_BUG = new JPAQuery<>().from(bug)
.join(report)
.on(report.bug.eq(bug))
.select(new QVBug(bug, report.date.max(), report.count()))
.groupBy(bug);
private static final JPAQuery<VApp> V_APP = new JPAQuery<>().from(app)
.join(bug)
.on(bug.app.eq(app))
.join(report)
.on(report.bug.eq(bug))
.select(new QVApp(app, bug.countDistinct(), report.count()))
.groupBy(app);
public static JPAQuery<VBug> selectVBug(@NonNull EntityManager entityManager) {
return V_BUG.clone(entityManager);

View file

@ -2,6 +2,7 @@ package com.faendir.acra.model.view;
import com.faendir.acra.model.App;
import com.querydsl.core.annotations.QueryProjection;
import org.springframework.lang.NonNull;
/**
* @author lukas
@ -10,11 +11,13 @@ import com.querydsl.core.annotations.QueryProjection;
public class VApp {
private final App app;
private final long reportCount;
private final long bugCount;
@QueryProjection
public VApp(App app, long reportCount) {
public VApp(App app, long bugCount, long reportCount) {
this.app = app;
this.reportCount = reportCount;
this.bugCount = bugCount;
}
public App getApp() {
@ -24,4 +27,17 @@ public class VApp {
public long getReportCount() {
return reportCount;
}
public long getBugCount() {
return bugCount;
}
public int getId() {
return app.getId();
}
@NonNull
public String getName() {
return app.getName();
}
}

View file

@ -7,12 +7,7 @@ import com.faendir.acra.model.Bug;
import com.faendir.acra.model.Permission;
import com.faendir.acra.model.ProguardMapping;
import com.faendir.acra.model.QApp;
import com.faendir.acra.model.QAttachment;
import com.faendir.acra.model.QBug;
import com.faendir.acra.model.QPermission;
import com.faendir.acra.model.QProguardMapping;
import com.faendir.acra.model.QReport;
import com.faendir.acra.model.QUser;
import com.faendir.acra.model.Report;
import com.faendir.acra.model.User;
import com.faendir.acra.model.view.Queries;
@ -58,22 +53,25 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static com.faendir.acra.model.QApp.app;
import static com.faendir.acra.model.QAttachment.attachment;
import static com.faendir.acra.model.QBug.bug;
import static com.faendir.acra.model.QPermission.permission;
import static com.faendir.acra.model.QProguardMapping.proguardMapping;
import static com.faendir.acra.model.QReport.report;
import static com.faendir.acra.model.QUser.user;
/**
* @author lukas
* @since 16.05.18
*/
@Service
public class DataService implements Serializable {
private static final QUser USER = QUser.user;
private static final QPermission PERMISSION = QPermission.permission;
private static final QApp APP = QApp.app;
private static final QReport REPORT = QReport.report;
private static final QBug BUG = QBug.bug;
private static final QProguardMapping MAPPING = QProguardMapping.proguardMapping;
private static final QAttachment ATTACHMENT = QAttachment.attachment;
@NonNull private final Log log = LogFactory.getLog(getClass());
@NonNull private final UserService userService;
@NonNull private final EntityManager entityManager;
@ -89,32 +87,33 @@ public class DataService implements Serializable {
boolean isAdmin = SecurityUtils.hasRole(User.Role.ADMIN);
Function<JPQLQuery<?>, BooleanExpression> existenceFunction = isAdmin ? JPQLQuery::notExists : JPQLQuery::exists;
BiFunction<EnumPath<Permission.Level>, Permission.Level, BooleanExpression> compareFunction = isAdmin ? EnumPath::lt : EnumPath::goe;
BooleanExpression where = existenceFunction.apply(JPAExpressions.select(PERMISSION)
.from(USER)
.join(USER.permissions, PERMISSION)
.where(USER.username.eq(SecurityUtils.getUsername()).and(PERMISSION.app.eq(APP)).and(compareFunction.apply(PERMISSION.level, Permission.Level.VIEW))));
return new QueryDslDataProvider<>(Queries.selectVApp(entityManager).where(where), new JPAQuery<>(entityManager).from(APP).where(where));
BooleanExpression where = existenceFunction.apply(JPAExpressions.select(permission)
.from(user)
.join(user.permissions, permission)
.where(user.username.eq(SecurityUtils.getUsername()).and(permission.app.eq(app)).and(compareFunction.apply(permission.level, Permission.Level.VIEW))));
return new QueryDslDataProvider<>(Queries.selectVApp(entityManager).where(where), new JPAQuery<>(entityManager).from(app).where(where));
}
@NonNull
public QueryDslDataProvider<VBug> getBugProvider(@NonNull App app, boolean onlyNonSolved) {
BooleanExpression where = BUG.app.eq(app).and(onlyNonSolved ? BUG.solved.eq(false) : Expressions.TRUE);
return new QueryDslDataProvider<>(Queries.selectVBug(entityManager).where(where), new JPAQuery<>(entityManager).from(BUG).where(where));
public QueryDslDataProvider<VBug> getBugProvider(@NonNull App app, BooleanSupplier onlyNonSolvedProvider) {
Supplier<BooleanExpression> whereSupplier = () -> onlyNonSolvedProvider.getAsBoolean() ? bug.app.eq(app).and(bug.solved.eq(false)) : bug.app.eq(app);
return new QueryDslDataProvider<>(() -> Queries.selectVBug(entityManager).where(whereSupplier.get()),
() -> new JPAQuery<>(entityManager).from(bug).where(whereSupplier.get()));
}
@NonNull
public QueryDslDataProvider<Report> getReportProvider(@NonNull Bug bug) {
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(REPORT).where(REPORT.bug.eq(bug)).select(REPORT));
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(report).where(report.bug.eq(bug)).select(report));
}
@NonNull
public QueryDslDataProvider<Report> getReportProvider(@NonNull App app) {
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(REPORT).join(REPORT.bug).where(REPORT.bug.app.eq(app)).select(REPORT));
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(report).join(report.bug).where(report.bug.app.eq(app)).select(report));
}
@NonNull
public QueryDslDataProvider<ProguardMapping> getMappingProvider(@NonNull App app) {
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(MAPPING).where(MAPPING.app.eq(app)).select(MAPPING));
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(proguardMapping).where(proguardMapping.app.eq(app)).select(proguardMapping));
}
@Transactional
@ -154,9 +153,9 @@ public class DataService implements Serializable {
Bug bug = list.remove(0);
bug.setTitle(title);
StringPath stringPath = Expressions.stringPath("trace");
bug.setStacktraces(new JPAQuery<>(entityManager).from(BUG).join(BUG.stacktraces, stringPath).where(BUG.in(bugs)).select(stringPath).fetch());
bug.setStacktraces(new JPAQuery<>(entityManager).from(QBug.bug).join(QBug.bug.stacktraces, stringPath).where(QBug.bug.in(bugs)).select(stringPath).fetch());
bug = store(bug);
CloseableIterator<Report> iterator = new JPAQuery<>(entityManager).from(REPORT).where(REPORT.bug.in(list)).select(REPORT).iterate();
CloseableIterator<Report> iterator = new JPAQuery<>(entityManager).from(report).where(report.bug.in(list)).select(report).iterate();
while (iterator.hasNext()) {
Report report = iterator.next();
report.setBug(bug);
@ -174,25 +173,28 @@ public class DataService implements Serializable {
@NonNull
public Optional<ProguardMapping> findMapping(@NonNull App app, int versionCode) {
return Optional.ofNullable(new JPAQuery<>(entityManager).from(MAPPING).where(MAPPING.app.eq(app).and(MAPPING.versionCode.eq(versionCode))).select(MAPPING).fetchOne());
return Optional.ofNullable(new JPAQuery<>(entityManager).from(proguardMapping)
.where(proguardMapping.app.eq(app).and(proguardMapping.versionCode.eq(versionCode)))
.select(proguardMapping)
.fetchOne());
}
@NonNull
public Optional<Report> findReport(@NonNull String id) {
return Optional.ofNullable(new JPAQuery<>(entityManager).from(REPORT)
.join(REPORT.bug, BUG)
return Optional.ofNullable(new JPAQuery<>(entityManager).from(report)
.join(report.bug, bug)
.fetchJoin()
.join(BUG.app, APP)
.join(bug.app, app)
.fetchJoin()
.where(REPORT.id.eq(id))
.select(REPORT)
.where(report.id.eq(id))
.select(report)
.fetchOne());
}
@NonNull
public Optional<VBug> findBug(@NonNull String encodedId) {
try {
return Optional.ofNullable(Queries.selectVBug(entityManager).where(BUG.id.eq(Integer.parseInt(encodedId))).fetchOne());
return Optional.ofNullable(Queries.selectVBug(entityManager).where(bug.id.eq(Integer.parseInt(encodedId))).fetchOne());
} catch (NumberFormatException e) {
return Optional.empty();
}
@ -201,7 +203,7 @@ public class DataService implements Serializable {
@NonNull
public Optional<App> findApp(@NonNull String encodedId) {
try {
return Optional.ofNullable(new JPAQuery<>(entityManager).from(APP).where(APP.id.eq(Integer.parseInt(encodedId))).select(APP).fetchOne());
return Optional.ofNullable(new JPAQuery<>(entityManager).from(app).where(app.id.eq(Integer.parseInt(encodedId))).select(app).fetchOne());
} catch (NumberFormatException e) {
return Optional.empty();
}
@ -209,27 +211,27 @@ public class DataService implements Serializable {
@NonNull
public List<App> findAllApps() {
return new JPAQuery<>(entityManager).from(APP).select(APP).fetch();
return new JPAQuery<>(entityManager).from(app).select(app).fetch();
}
@NonNull
public List<Attachment> findAttachments(@NonNull Report report) {
return new JPAQuery<>(entityManager).from(ATTACHMENT).where(ATTACHMENT.report.eq(report)).select(ATTACHMENT).fetch();
return new JPAQuery<>(entityManager).from(attachment).where(attachment.report.eq(report)).select(attachment).fetch();
}
private void deleteOrphanBugs() {
new JPADeleteClause(entityManager, BUG).where(JPAExpressions.selectFrom(REPORT).where(REPORT.bug.eq(BUG)).notExists()).execute();
new JPADeleteClause(entityManager, bug).where(JPAExpressions.selectFrom(report).where(report.bug.eq(bug)).notExists()).execute();
}
private Optional<Bug> findBug(@NonNull App app, @NonNull String stacktrace) {
return Optional.ofNullable(new JPAQuery<>(entityManager).from(BUG).where(BUG.app.eq(app).and(BUG.stacktraces.any().eq(stacktrace))).select(BUG).fetchFirst());
return Optional.ofNullable(new JPAQuery<>(entityManager).from(bug).where(bug.app.eq(app).and(bug.stacktraces.any().eq(stacktrace))).select(bug).fetchFirst());
}
@Transactional
public void changeConfiguration(@NonNull App app, @NonNull App.Configuration configuration) {
app.setConfiguration(configuration);
app = store(app);
CloseableIterator<Report> iterator = new JPAQuery<>(entityManager).from(REPORT).join(REPORT.bug, BUG).where(BUG.app.eq(app)).select(REPORT).iterate();
CloseableIterator<Report> iterator = new JPAQuery<>(entityManager).from(report).join(report.bug, bug).where(bug.app.eq(app)).select(report).iterate();
while (iterator.hasNext()) {
Report report = iterator.next();
String stacktrace = Utils.generifyStacktrace(report.getStacktrace(), app.getConfiguration());
@ -250,19 +252,19 @@ public class DataService implements Serializable {
public void deleteReportsOlderThanDays(@NonNull App app, @NonNull int days) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -days);
new JPADeleteClause(entityManager, REPORT).where(REPORT.bug.app.eq(app).and(REPORT.date.before(calendar.getTime())));
new JPADeleteClause(entityManager, report).where(report.bug.app.eq(app).and(report.date.before(calendar.getTime())));
deleteOrphanBugs();
}
@Transactional
public void deleteReportsBeforeVersion(@NonNull App app, int versionCode) {
new JPADeleteClause(entityManager, REPORT).where(REPORT.bug.app.eq(app).and(REPORT.versionCode.lt(versionCode)));
new JPADeleteClause(entityManager, report).where(report.bug.app.eq(app).and(report.versionCode.lt(versionCode)));
deleteOrphanBugs();
}
@Transactional
public void createNewReport(@NonNull String reporterUserName, @NonNull String content, @NonNull List<MultipartFile> attachments) {
App app = new JPAQuery<>(entityManager).from(APP).where(APP.reporter.username.eq(reporterUserName)).select(APP).fetchOne();
App app = new JPAQuery<>(entityManager).from(QApp.app).where(QApp.app.reporter.username.eq(reporterUserName)).select(QApp.app).fetchOne();
if (app != null) {
JSONObject jsonObject = new JSONObject(content);
String stacktrace = Utils.generifyStacktrace(jsonObject.optString(ReportField.STACK_TRACE.name()), app.getConfiguration());
@ -281,8 +283,8 @@ public class DataService implements Serializable {
}
public <T> Map<T, Long> countReports(@NonNull Predicate where, Expression<?> groupBy, @NonNull Expression<T> select) {
List<Tuple> result = ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(REPORT).where(where).groupBy(groupBy).select(select, REPORT.id.count()).fetch();
return result.stream().collect(Collectors.toMap(tuple -> tuple.get(select), tuple -> tuple.get(REPORT.id.count())));
List<Tuple> result = ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(report).where(where).groupBy(groupBy).select(select, report.id.count()).fetch();
return result.stream().collect(Collectors.toMap(tuple -> tuple.get(select), tuple -> tuple.get(report.id.count())));
}
@NonNull
@ -292,6 +294,6 @@ public class DataService implements Serializable {
@NonNull
public <T> List<T> getFromReports(@NonNull Predicate where, @NonNull Expression<T> select, ComparableExpressionBase<?> order) {
return ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(REPORT).where(where).select(select).distinct().orderBy(order.asc()).fetch();
return ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(report).where(where).select(select).distinct().orderBy(order.asc()).fetch();
}
}

View file

@ -1,6 +1,7 @@
package com.faendir.acra.ui.view;
import com.faendir.acra.model.QApp;
import com.faendir.acra.model.QBug;
import com.faendir.acra.model.QReport;
import com.faendir.acra.model.User;
import com.faendir.acra.model.view.VApp;
@ -46,9 +47,10 @@ public class Overview extends BaseView {
grid.setResponsive(true);
grid.setSizeToRows();
grid.setSelectionMode(Grid.SelectionMode.NONE);
grid.addColumn(app -> app.getApp().getName(), QApp.app.name, "Name");
grid.addColumn(VApp::getName, QApp.app.name, "Name");
grid.addColumn(VApp::getBugCount, QBug.bug.countDistinct(), "Bugs");
grid.addColumn(VApp::getReportCount, QReport.report.count(), "Reports");
grid.addOnClickNavigation(getNavigationManager(), AppView.class, e -> String.valueOf(e.getItem().getApp().getId()));
grid.addOnClickNavigation(getNavigationManager(), AppView.class, e -> String.valueOf(e.getItem().getId()));
VerticalLayout layout = new VerticalLayout();
if (SecurityUtils.hasRole(User.Role.ADMIN)) {
Button add = new Button("New App", e -> addApp());

View file

@ -63,11 +63,11 @@ public class BugTab implements AppTab {
layout.addComponent(header);
layout.setComponentAlignment(header, Alignment.MIDDLE_LEFT);
CheckBox hideSolved = new CheckBox("Hide solved", true);
MyGrid<VBug> bugs = new MyGrid<>(null, dataService.getBugProvider(app, true));
MyGrid<VBug> bugs = new MyGrid<>(null, dataService.getBugProvider(app, hideSolved::getValue));
bugs.setSelectionMode(Grid.SelectionMode.MULTI);
hideSolved.addValueChangeListener(e -> layout.getUI().access(() -> {
Set<VBug> selection = bugs.getSelectedItems();
bugs.setDataProvider(dataService.getBugProvider(app, e.getValue()));
bugs.getDataProvider().refreshAll();
selection.forEach(bugs::select);
}));
Button merge = new Button("Merge bugs", e -> {

View file

@ -25,7 +25,7 @@ import java.util.function.Function;
*/
public class MyGrid<T> extends Composite {
private final ExposingGrid<T> grid;
private QueryDslDataProvider<T> dataProvider;
private final QueryDslDataProvider<T> dataProvider;
public MyGrid(String caption, QueryDslDataProvider<T> dataProvider) {
this.dataProvider = dataProvider;
@ -106,11 +106,6 @@ public class MyGrid<T> extends Composite {
return dataProvider;
}
public void setDataProvider(QueryDslDataProvider<T> dataProvider) {
this.dataProvider = dataProvider;
grid.setDataProvider(dataProvider);
}
public static class MiddleClickExtension<T> extends Grid.AbstractGridExtension<T> {
private MiddleClickExtension(MyGrid<T> myGrid) {
ExposingGrid<T> grid = myGrid.grid;