fix grid sorting
This commit is contained in:
parent
6a239978d1
commit
aeaff00798
9 changed files with 130 additions and 53 deletions
|
@ -1,8 +1,8 @@
|
|||
package com.faendir.acra.dataprovider;
|
||||
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.querydsl.core.types.Order;
|
||||
import com.querydsl.core.types.OrderSpecifier;
|
||||
import com.querydsl.core.types.dsl.Expressions;
|
||||
import com.querydsl.jpa.impl.JPAQuery;
|
||||
import com.vaadin.data.provider.AbstractBackEndDataProvider;
|
||||
import com.vaadin.data.provider.Query;
|
||||
|
@ -10,7 +10,9 @@ import com.vaadin.data.provider.QuerySortOrder;
|
|||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -21,8 +23,9 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
|
|||
private final List<SizeListener> sizeListeners;
|
||||
private final JPAQuery<T> fetchBase;
|
||||
private final JPAQuery<?> countBase;
|
||||
private final Map<String, Expression<? extends Comparable>> sortOptions;
|
||||
|
||||
public QueryDslDataProvider(JPAQuery<T> base){
|
||||
public QueryDslDataProvider(JPAQuery<T> base) {
|
||||
this(base, base);
|
||||
}
|
||||
|
||||
|
@ -30,6 +33,7 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
|
|||
this.fetchBase = fetchBase;
|
||||
this.countBase = countBase;
|
||||
sizeListeners = new ArrayList<>();
|
||||
sortOptions = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,11 +46,20 @@ public class QueryDslDataProvider<T> extends AbstractBackEndDataProvider<T, Void
|
|||
sizeListeners.remove(listener);
|
||||
}
|
||||
|
||||
public String addSortable(Expression<? extends Comparable> expression) {
|
||||
String id = String.valueOf(sortOptions.size());
|
||||
sortOptions.put(id, expression);
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<T> fetchFromBackEnd(Query<T, Void> query) {
|
||||
JPAQuery<T> q = fetchBase.clone().offset(query.getOffset()).limit(query.getLimit());
|
||||
for (QuerySortOrder order : query.getSortOrders()){
|
||||
q = q.orderBy(new OrderSpecifier<>(order.getDirection() == SortDirection.ASCENDING ? Order.ASC : Order.DESC, Expressions.asComparable(order.getSorted())));
|
||||
for (QuerySortOrder order : query.getSortOrders()) {
|
||||
Expression<? extends Comparable> sort = sortOptions.get(order.getSorted());
|
||||
if (sort != null) {
|
||||
q = q.orderBy(new OrderSpecifier<>(order.getDirection() == SortDirection.ASCENDING ? Order.ASC : Order.DESC, sort));
|
||||
}
|
||||
}
|
||||
return q.fetch().stream();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.faendir.acra.service.data;
|
||||
|
||||
import com.faendir.acra.dataprovider.ObservableDataProvider;
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Attachment;
|
||||
|
@ -86,7 +85,7 @@ public class DataService implements Serializable {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public ObservableDataProvider<VApp, Void> getAppProvider() {
|
||||
public QueryDslDataProvider<VApp> getAppProvider() {
|
||||
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;
|
||||
|
@ -98,23 +97,23 @@ public class DataService implements Serializable {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public ObservableDataProvider<VBug, Void> getBugProvider(@NonNull App app, boolean onlyNonSolved) {
|
||||
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));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ObservableDataProvider<Report, Void> getReportProvider(@NonNull Bug bug) {
|
||||
public QueryDslDataProvider<Report> getReportProvider(@NonNull Bug bug) {
|
||||
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(REPORT).where(REPORT.bug.eq(bug)).select(REPORT));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ObservableDataProvider<Report, Void> getReportProvider(@NonNull App app) {
|
||||
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));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ObservableDataProvider<ProguardMapping, Void> getMappingProvider(@NonNull App app) {
|
||||
public QueryDslDataProvider<ProguardMapping> getMappingProvider(@NonNull App app) {
|
||||
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(MAPPING).where(MAPPING.app.eq(app)).select(MAPPING));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.faendir.acra.service.user;
|
||||
|
||||
import com.faendir.acra.config.AcraConfiguration;
|
||||
import com.faendir.acra.dataprovider.ObservableDataProvider;
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
|
@ -114,7 +113,7 @@ public class UserService implements Serializable {
|
|||
return new User(acraConfiguration.getUser().getName(), passwordEncoder.encode(acraConfiguration.getUser().getPassword()), Arrays.asList(User.Role.USER, User.Role.ADMIN));
|
||||
}
|
||||
|
||||
public ObservableDataProvider<User, Void> getUserProvider() {
|
||||
public QueryDslDataProvider<User> getUserProvider() {
|
||||
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(USER).where(USER.roles.any().eq(User.Role.USER)).select(USER));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.faendir.acra.ui.view;
|
||||
|
||||
import com.faendir.acra.model.QApp;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.model.User;
|
||||
import com.faendir.acra.model.view.VApp;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
|
@ -44,8 +46,8 @@ public class Overview extends BaseView {
|
|||
grid.setResponsive(true);
|
||||
grid.setSizeToRows();
|
||||
grid.setSelectionMode(Grid.SelectionMode.NONE);
|
||||
grid.addColumn(app -> app.getApp().getName(), "name", "Name");
|
||||
grid.addColumn(VApp::getReportCount, "reportCount", "Reports");
|
||||
grid.addColumn(app -> app.getApp().getName(), QApp.app.name, "Name");
|
||||
grid.addColumn(VApp::getReportCount, QReport.report.count(), "Reports");
|
||||
grid.addOnClickNavigation(getNavigationManager(), AppView.class, e -> String.valueOf(e.getItem().getApp().getId()));
|
||||
VerticalLayout layout = new VerticalLayout();
|
||||
if (SecurityUtils.hasRole(User.Role.ADMIN)) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.faendir.acra.ui.view.app.tabs;
|
|||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.ProguardMapping;
|
||||
import com.faendir.acra.model.QProguardMapping;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.data.DataService;
|
||||
|
@ -18,6 +19,7 @@ import com.faendir.acra.ui.view.base.ValidatedField;
|
|||
import com.faendir.acra.util.Style;
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
import com.vaadin.shared.ui.ContentMode;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
|
@ -132,12 +134,12 @@ public class AdminTab implements AppTab {
|
|||
VerticalLayout layout = new VerticalLayout();
|
||||
MyGrid<ProguardMapping> grid = new MyGrid<>(null, dataService.getMappingProvider(app));
|
||||
grid.setSizeToRows();
|
||||
grid.addColumn(ProguardMapping::getVersionCode, "Version");
|
||||
grid.sort(grid.addColumn(ProguardMapping::getVersionCode, QProguardMapping.proguardMapping.versionCode, "Version"), SortDirection.ASCENDING);
|
||||
if (SecurityUtils.hasPermission(app, Permission.Level.EDIT)) {
|
||||
grid.addColumn(report -> "Delete",
|
||||
new ButtonRenderer<>(e -> new Popup().setTitle("Confirm")
|
||||
.addComponent(new Label("Are you sure you want to delete the mapping for version " + e.getItem().getVersionCode() + "?"))
|
||||
.addYesNoButtons(p -> dataService.delete(e.getItem()), true))).setSortable(false);
|
||||
.addYesNoButtons(p -> dataService.delete(e.getItem()), true)));
|
||||
}
|
||||
layout.addComponent(grid);
|
||||
Style.NO_PADDING.apply(layout);
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.faendir.acra.ui.view.app.tabs;
|
|||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.QBug;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.model.view.VBug;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.data.DataService;
|
||||
|
@ -84,13 +86,13 @@ public class BugTab implements AppTab {
|
|||
header.addComponent(merge);
|
||||
header.addComponent(hideSolved);
|
||||
header.setComponentAlignment(hideSolved, Alignment.MIDDLE_RIGHT);
|
||||
bugs.addColumn(VBug::getReportCount,"reportCount", "Reports");
|
||||
bugs.sort(bugs.addColumn(VBug::getLastReport, new TimeSpanRenderer(), "lastReport", "Latest Report"), SortDirection.DESCENDING);
|
||||
bugs.addColumn(bug -> bug.getBug().getVersionCode(), "versionCode", "Version");
|
||||
bugs.addColumn(bug -> bug.getBug().getTitle(), "title", "Title").setExpandRatio(1).setMinimumWidthFromContent(false);
|
||||
bugs.addColumn(VBug::getReportCount,QReport.report.count(), "Reports");
|
||||
bugs.sort(bugs.addColumn(VBug::getLastReport, new TimeSpanRenderer(), QReport.report.date.max(), "Latest Report"), SortDirection.DESCENDING);
|
||||
bugs.addColumn(bug -> bug.getBug().getVersionCode(), QBug.bug.versionCode, "Version");
|
||||
bugs.addColumn(bug -> bug.getBug().getTitle(), QBug.bug.title, "Title").setExpandRatio(1).setMinimumWidthFromContent(false);
|
||||
bugs.addOnClickNavigation(navigationManager, com.faendir.acra.ui.view.bug.BugView.class, bugItemClick -> String.valueOf(bugItemClick.getItem().getBug().getId()));
|
||||
bugs.addColumn(bug -> new MyCheckBox(bug.getBug().isSolved(), SecurityUtils.hasPermission(app, Permission.Level.EDIT), e -> dataService.setBugSolved(bug.getBug(), e.getValue())),
|
||||
new ComponentRenderer(), "solved", "Solved");
|
||||
new ComponentRenderer(), QBug.bug.solved, "Solved");
|
||||
layout.addComponent(bugs);
|
||||
layout.setExpandRatio(bugs, 1);
|
||||
layout.setSizeFull();
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package com.faendir.acra.ui.view.base;
|
||||
|
||||
import com.faendir.acra.client.mygrid.MiddleClickGridExtensionConnector;
|
||||
import com.faendir.acra.dataprovider.ObservableDataProvider;
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.vaadin.data.ValueProvider;
|
||||
import com.vaadin.data.provider.DataProvider;
|
||||
import com.vaadin.shared.MouseEventDetails;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
import com.vaadin.ui.Composite;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.renderers.AbstractRenderer;
|
||||
import com.vaadin.ui.renderers.TextRenderer;
|
||||
|
@ -12,15 +16,21 @@ import elemental.json.JsonObject;
|
|||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author Lukas
|
||||
* @since 14.05.2017
|
||||
*/
|
||||
public class MyGrid<T> extends Grid<T> {
|
||||
public MyGrid(String caption, ObservableDataProvider<T, ?> dataProvider) {
|
||||
super(caption, dataProvider);
|
||||
public class MyGrid<T> extends Composite {
|
||||
private final ExposingGrid<T> grid;
|
||||
private QueryDslDataProvider<T> dataProvider;
|
||||
|
||||
public MyGrid(String caption, QueryDslDataProvider<T> dataProvider) {
|
||||
this.dataProvider = dataProvider;
|
||||
grid = new ExposingGrid<>(caption, dataProvider);
|
||||
setCompositionRoot(grid);
|
||||
setSizeFull();
|
||||
MiddleClickExtension.extend(this);
|
||||
}
|
||||
|
@ -32,48 +42,84 @@ public class MyGrid<T> extends Grid<T> {
|
|||
|
||||
@NonNull
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull AbstractRenderer<? super T, ? super R> renderer, @NonNull String caption) {
|
||||
return addColumn(valueProvider, renderer).setId(caption).setCaption(caption).setSortable(false);
|
||||
return grid.addColumn(valueProvider, renderer).setCaption(caption).setSortable(false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull String id, @NonNull String caption) {
|
||||
return addColumn(valueProvider, new TextRenderer(), id, caption);
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull Expression<? extends Comparable> sort, @NonNull String caption) {
|
||||
return addColumn(valueProvider, new TextRenderer(), sort, caption);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull AbstractRenderer<? super T, ? super R> renderer, @NonNull String id,
|
||||
@NonNull String caption) {
|
||||
return addColumn(valueProvider, renderer).setId(id).setCaption(caption);
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull AbstractRenderer<? super T, ? super R> renderer,
|
||||
@NonNull Expression<? extends Comparable> sort, @NonNull String caption) {
|
||||
return grid.addColumn(valueProvider, renderer).setId(dataProvider.addSortable(sort)).setCaption(caption);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public <R> Grid.Column<T, R> addColumn(@NonNull ValueProvider<T, R> valueProvider, @NonNull AbstractRenderer<? super T, ? super R> renderer) {
|
||||
return grid.addColumn(valueProvider, renderer).setSortable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItems(@NonNull Collection<T> items) {
|
||||
super.setItems(items);
|
||||
grid.setItems(items);
|
||||
setHeightByRows(items.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeightByRows(double rows) {
|
||||
super.setHeightByRows(rows >= 1 ? rows : 1);
|
||||
grid.setHeightByRows(rows >= 1 ? rows : 1);
|
||||
}
|
||||
|
||||
public void setSizeToRows() {
|
||||
((ObservableDataProvider) getDataProvider()).addSizeListener(rows -> getUI().access(() -> setHeightByRows(rows)));
|
||||
dataProvider.addSizeListener(rows -> getUI().access(() -> setHeightByRows(rows)));
|
||||
}
|
||||
|
||||
public void addOnClickNavigation(@NonNull NavigationManager navigationManager, Class<? extends BaseView> namedView, Function<ItemClick<T>, String> parameterGetter) {
|
||||
addItemClickListener(e -> {
|
||||
public void setBodyRowHeight(double rowHeight) {
|
||||
grid.setBodyRowHeight(rowHeight);
|
||||
}
|
||||
|
||||
public void setSelectionMode(Grid.SelectionMode selectionMode) {
|
||||
grid.setSelectionMode(selectionMode);
|
||||
}
|
||||
|
||||
public void sort(Grid.Column<T, ?> column, SortDirection direction) {
|
||||
grid.sort(column, direction);
|
||||
}
|
||||
|
||||
public Set<T> getSelectedItems() {
|
||||
return grid.getSelectedItems();
|
||||
}
|
||||
|
||||
public void select(T item) {
|
||||
grid.select(item);
|
||||
}
|
||||
|
||||
public void addOnClickNavigation(@NonNull NavigationManager navigationManager, Class<? extends BaseView> namedView,
|
||||
Function<Grid.ItemClick<T>, String> parameterGetter) {
|
||||
grid.addItemClickListener(e -> {
|
||||
boolean newTab = e.getMouseEventDetails().getButton() == MouseEventDetails.MouseButton.MIDDLE || e.getMouseEventDetails().isCtrlKey();
|
||||
navigationManager.navigateTo(namedView, parameterGetter.apply(e), newTab);
|
||||
});
|
||||
}
|
||||
|
||||
public static class MiddleClickExtension<T> extends AbstractGridExtension<T> {
|
||||
private MiddleClickExtension(MyGrid<T> grid) {
|
||||
public QueryDslDataProvider<T> getDataProvider() {
|
||||
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;
|
||||
super.extend(grid);
|
||||
registerRpc((rowIndex, rowKey, columnInternalId, details) -> grid.fireEvent(
|
||||
new ItemClick<>(grid, grid.getColumnByInternalId(columnInternalId), grid.getDataCommunicator().getKeyMapper().get(rowKey),
|
||||
details, rowIndex)), MiddleClickGridExtensionConnector.Rpc.class);
|
||||
registerRpc((rowIndex, rowKey, columnInternalId, details) -> myGrid.fireEvent(new Grid.ItemClick<>(grid,
|
||||
grid.getColumnByInternalId(columnInternalId),
|
||||
grid.getDataCommunicator().getKeyMapper().get(rowKey),
|
||||
details,
|
||||
rowIndex)), MiddleClickGridExtensionConnector.Rpc.class);
|
||||
}
|
||||
|
||||
public static void extend(MyGrid<?> grid) {
|
||||
|
@ -96,4 +142,15 @@ public class MyGrid<T> extends Grid<T> {
|
|||
public void refreshData(Object item) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ExposingGrid<T> extends Grid<T> {
|
||||
ExposingGrid(String caption, DataProvider<T, ?> dataProvider) {
|
||||
super(caption, dataProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column<T, ?> getColumnByInternalId(String columnId) {
|
||||
return super.getColumnByInternalId(columnId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
package com.faendir.acra.ui.view.base;
|
||||
|
||||
import com.faendir.acra.dataprovider.ObservableDataProvider;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.model.Report;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.report.ReportView;
|
||||
import com.faendir.acra.util.TimeSpanRenderer;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.renderers.ButtonRenderer;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
@ -22,15 +24,15 @@ import java.util.function.Consumer;
|
|||
public class ReportList extends MyGrid<Report> {
|
||||
public static final String CAPTION = "Reports";
|
||||
|
||||
public ReportList(App app, @NonNull NavigationManager navigationManager, @NonNull Consumer<Report> reportDeleter, @NonNull ObservableDataProvider<Report, ?> reportProvider) {
|
||||
public ReportList(App app, @NonNull NavigationManager navigationManager, @NonNull Consumer<Report> reportDeleter, @NonNull QueryDslDataProvider<Report> reportProvider) {
|
||||
super(CAPTION, reportProvider);
|
||||
setId(CAPTION);
|
||||
setSelectionMode(SelectionMode.NONE);
|
||||
sort(addColumn(Report::getDate, new TimeSpanRenderer(), "date", "Date"), SortDirection.DESCENDING);
|
||||
addColumn(Report::getVersionCode, "versionCode", "App Version");
|
||||
addColumn(Report::getAndroidVersion, "androidVersion", "Android Version");
|
||||
addColumn(Report::getPhoneModel, "phoneModel", "Device");
|
||||
addColumn(report -> report.getStacktrace().split("\n", 2)[0], "stacktrace", "Stacktrace").setExpandRatio(1).setMinimumWidthFromContent(false);
|
||||
setSelectionMode(Grid.SelectionMode.NONE);
|
||||
sort(addColumn(Report::getDate, new TimeSpanRenderer(), QReport.report.date, "Date"), SortDirection.DESCENDING);
|
||||
addColumn(Report::getVersionCode, QReport.report.versionCode, "App Version");
|
||||
addColumn(Report::getAndroidVersion, QReport.report.androidVersion, "Android Version");
|
||||
addColumn(Report::getPhoneModel, QReport.report.phoneModel, "Device");
|
||||
addColumn(report -> report.getStacktrace().split("\n", 2)[0], QReport.report.stacktrace, "Stacktrace").setExpandRatio(1).setMinimumWidthFromContent(false);
|
||||
if (SecurityUtils.hasPermission(app, Permission.Level.EDIT)) {
|
||||
addColumn(report -> "Delete", new ButtonRenderer<>(e -> new Popup().setTitle("Confirm")
|
||||
.addComponent(new Label("Are you sure you want to delete this report?"))
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.faendir.acra.ui.view.user;
|
|||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.QUser;
|
||||
import com.faendir.acra.model.User;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.data.DataService;
|
||||
|
@ -54,7 +55,7 @@ public class UserManagerView extends BaseView {
|
|||
userGrid.setSelectionMode(Grid.SelectionMode.NONE);
|
||||
userGrid.setBodyRowHeight(42);
|
||||
userGrid.setSizeToRows();
|
||||
userGrid.addColumn(User::getUsername, "username", "Username");
|
||||
userGrid.addColumn(User::getUsername, QUser.user.username, "Username");
|
||||
userGrid.addColumn(user -> new MyCheckBox(user.getRoles().contains(User.Role.ADMIN), !user.getUsername().equals(SecurityUtils.getUsername()), e -> {
|
||||
userService.setAdmin(user, e.getValue());
|
||||
userGrid.getDataProvider().refreshAll();
|
||||
|
|
Loading…
Reference in a new issue