sort base view classes into packages. Split AdminTab into panel classes
This commit is contained in:
parent
74528e1cc7
commit
2aed2d4add
35 changed files with 527 additions and 293 deletions
|
@ -93,7 +93,7 @@ dependencies {
|
|||
def queryDslVersion = '4.2.1'
|
||||
compile "com.querydsl:querydsl-jpa:$queryDslVersion"
|
||||
compile "com.querydsl:querydsl-sql:$queryDslVersion"
|
||||
compile "com.querydsl:querydsl-apt:$queryDslVersion:hibernate"
|
||||
compile "com.querydsl:querydsl-apt:$queryDslVersion:jpa"
|
||||
//vaadin
|
||||
compile 'com.vaadin:vaadin-spring-boot-starter'
|
||||
compile 'com.vaadin:vaadin-push'
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package com.faendir.acra.client.mygrid;
|
||||
|
||||
import com.faendir.acra.ui.view.base.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.layout.MyGrid;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.event.dom.client.MouseDownEvent;
|
||||
import com.vaadin.client.MouseEventDetailsBuilder;
|
||||
|
|
|
@ -18,7 +18,7 @@ package com.faendir.acra.ui;
|
|||
import com.faendir.acra.model.User;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.Path;
|
||||
import com.faendir.acra.ui.view.base.navigation.Path;
|
||||
import com.faendir.acra.ui.view.user.ChangePasswordView;
|
||||
import com.faendir.acra.ui.view.user.UserManagerView;
|
||||
import com.vaadin.annotations.Theme;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
package com.faendir.acra.ui.navigation;
|
||||
|
||||
import com.faendir.acra.ui.view.ErrorView;
|
||||
import com.faendir.acra.ui.view.base.BaseView;
|
||||
import com.faendir.acra.ui.view.base.Path;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.Path;
|
||||
import com.faendir.acra.util.Utils;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
import com.vaadin.ui.Panel;
|
||||
|
|
|
@ -19,7 +19,7 @@ package com.faendir.acra.ui.navigation;
|
|||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
||||
import com.faendir.acra.ui.view.base.ParametrizedBaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.ParametrizedBaseView;
|
||||
|
||||
/**
|
||||
* @author Lukas
|
||||
|
|
|
@ -18,7 +18,7 @@ package com.faendir.acra.ui.navigation;
|
|||
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.ui.annotation.RequiresRole;
|
||||
import com.faendir.acra.ui.view.base.BaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.vaadin.navigator.ViewProvider;
|
||||
import com.vaadin.spring.internal.ViewCache;
|
||||
import com.vaadin.spring.internal.ViewScopeImpl;
|
||||
|
|
|
@ -25,10 +25,10 @@ import com.faendir.acra.security.SecurityUtils;
|
|||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.navigation.SingleViewProvider;
|
||||
import com.faendir.acra.ui.view.app.AppView;
|
||||
import com.faendir.acra.ui.view.base.BaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.faendir.acra.ui.view.base.ConfigurationLabel;
|
||||
import com.faendir.acra.ui.view.base.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.Popup;
|
||||
import com.faendir.acra.ui.view.base.layout.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
|
|
|
@ -22,8 +22,8 @@ import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
|||
import com.faendir.acra.ui.navigation.MyNavigator;
|
||||
import com.faendir.acra.ui.navigation.SingleParametrizedViewProvider;
|
||||
import com.faendir.acra.ui.view.app.tabs.AppTab;
|
||||
import com.faendir.acra.ui.view.base.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.ParametrizedBaseView;
|
||||
import com.faendir.acra.ui.view.base.layout.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.navigation.ParametrizedBaseView;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
|
|
|
@ -17,45 +17,15 @@ 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.rest.RestReportInterface;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.ConfigurationLabel;
|
||||
import com.faendir.acra.ui.view.base.FlexLayout;
|
||||
import com.faendir.acra.ui.view.base.InMemoryUpload;
|
||||
import com.faendir.acra.ui.view.base.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.Popup;
|
||||
import com.faendir.acra.ui.view.base.ValidatedField;
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
import com.vaadin.shared.ui.ContentMode;
|
||||
import com.faendir.acra.ui.view.app.tabs.panels.AdminPanel;
|
||||
import com.faendir.acra.ui.view.base.layout.PanelFlexTab;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.ProgressBar;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.renderers.ButtonRenderer;
|
||||
import com.vaadin.ui.themes.AcraTheme;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
import org.vaadin.risto.stepper.IntStepper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Lukas
|
||||
|
@ -64,155 +34,10 @@ import org.vaadin.risto.stepper.IntStepper;
|
|||
@RequiresAppPermission(Permission.Level.ADMIN)
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class AdminTab implements AppTab {
|
||||
@NonNull private final DataService dataService;
|
||||
|
||||
public class AdminTab extends PanelFlexTab<App> implements AppTab {
|
||||
@Autowired
|
||||
public AdminTab(@NonNull DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component createContent(@NonNull App app, @NonNull NavigationManager navigationManager) {
|
||||
FlexLayout layout = new FlexLayout(proguardPanel(app), exportPanel(app), dangerPanel(app, navigationManager));
|
||||
layout.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
Panel root = new Panel(layout);
|
||||
root.setSizeFull();
|
||||
root.addStyleNames(AcraTheme.NO_BACKGROUND, AcraTheme.NO_BORDER);
|
||||
return root;
|
||||
}
|
||||
|
||||
private Panel dangerPanel(@NonNull App app, @NonNull NavigationManager navigationManager) {
|
||||
Button configButton = new Button("Create new ACRA Configuration",
|
||||
e -> new Popup().setTitle("Confirm")
|
||||
.addComponent(new Label("Are you sure you want to create a new ACRA configuration?<br>The existing configuration will be invalidated", ContentMode.HTML))
|
||||
.addYesNoButtons(popup -> popup.clear().addComponent(new ConfigurationLabel(dataService.recreateReporterUser(app))).addCloseButton().show())
|
||||
.show());
|
||||
configButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
Button matchingButton = new Button("Configure bug matching", e -> {
|
||||
App.Configuration configuration = app.getConfiguration();
|
||||
CheckBox matchByMessage = new CheckBox("Match by exception message", configuration.matchByMessage());
|
||||
CheckBox ignoreInstanceIds = new CheckBox("Ignore instance ids", configuration.ignoreInstanceIds());
|
||||
CheckBox ignoreAndroidLineNumbers = new CheckBox("Ignore android SDK line numbers", configuration.ignoreAndroidLineNumbers());
|
||||
new Popup().addValidatedField(ValidatedField.of(matchByMessage), true)
|
||||
.addValidatedField(ValidatedField.of(ignoreInstanceIds), true)
|
||||
.addValidatedField(ValidatedField.of(ignoreAndroidLineNumbers), true)
|
||||
.addComponent(new Label(
|
||||
"Are you sure you want to save this configuration? All bugs will be recalculated, which may take some time and will reset the 'solved' status"))
|
||||
.addYesNoButtons(p -> dataService.changeConfiguration(app,
|
||||
new App.Configuration(matchByMessage.getValue(), ignoreInstanceIds.getValue(), ignoreAndroidLineNumbers.getValue())), true)
|
||||
.show();
|
||||
});
|
||||
matchingButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
IntStepper age = new IntStepper();
|
||||
age.setValue(30);
|
||||
age.setMinValue(0);
|
||||
age.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
HorizontalLayout purgeAge = new HorizontalLayout();
|
||||
purgeAge.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
|
||||
purgeAge.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
purgeAge.addStyleName(AcraTheme.NO_MARGIN);
|
||||
purgeAge.addComponents(new Button("Purge", e -> dataService.deleteReportsOlderThanDays(app, age.getValue())), new Label(" Reports older than "), age, new Label(" Days"));
|
||||
purgeAge.setExpandRatio(age, 1);
|
||||
ComboBox<Integer> versionBox = new ComboBox<>(null, dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.stacktrace.versionCode));
|
||||
versionBox.setEmptySelectionAllowed(false);
|
||||
versionBox.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
HorizontalLayout purgeVersion = new HorizontalLayout();
|
||||
purgeVersion.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
purgeVersion.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
|
||||
purgeVersion.addStyleName(AcraTheme.NO_MARGIN);
|
||||
purgeVersion.addComponents(new Button("Purge", e -> {
|
||||
if (versionBox.getValue() != null) {
|
||||
dataService.deleteReportsBeforeVersion(app, versionBox.getValue());
|
||||
}
|
||||
}), new Label(" Reports before Version "), versionBox);
|
||||
purgeVersion.setExpandRatio(versionBox, 1);
|
||||
Button deleteButton = new Button("Delete App",
|
||||
e -> new Popup().setTitle("Confirm").addComponent(new Label("Are you sure you want to delete this app and all its associated content?")).addYesNoButtons(popup -> {
|
||||
dataService.delete(app);
|
||||
navigationManager.navigateBack();
|
||||
}, true).show());
|
||||
VerticalLayout layout = new VerticalLayout(configButton, matchingButton, purgeAge, purgeVersion, deleteButton);
|
||||
deleteButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
layout.setSizeFull();
|
||||
layout.addStyleName(AcraTheme.NO_PADDING);
|
||||
Panel danger = new Panel(layout);
|
||||
danger.setCaption("Danger Zone");
|
||||
danger.setIcon(VaadinIcons.EXCLAMATION);
|
||||
danger.addStyleNames(AcraTheme.NO_BACKGROUND, AcraTheme.RED_PANEL_HEADER);
|
||||
return danger;
|
||||
}
|
||||
|
||||
private Panel proguardPanel(@NonNull App app) {
|
||||
VerticalLayout layout = new VerticalLayout();
|
||||
MyGrid<ProguardMapping> grid = new MyGrid<>(null, dataService.getMappingProvider(app));
|
||||
grid.setSizeToRows();
|
||||
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());
|
||||
grid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show()));
|
||||
}
|
||||
layout.addComponent(grid);
|
||||
layout.addStyleName(AcraTheme.NO_PADDING);
|
||||
if (SecurityUtils.hasPermission(app, Permission.Level.EDIT)) {
|
||||
layout.addComponent(new Button("Add File", e -> {
|
||||
IntStepper version = new IntStepper("Version code");
|
||||
version.setValue(dataService.getMaximumMappingVersion(app).map(i -> i + 1).orElse(1));
|
||||
InMemoryUpload upload = new InMemoryUpload("Mapping file:");
|
||||
ProgressBar progressBar = new ProgressBar();
|
||||
upload.addProgressListener((readBytes, contentLength) -> layout.getUI().access(() -> progressBar.setValue((float) readBytes / contentLength)));
|
||||
new Popup().setTitle("New Mapping Configuration")
|
||||
.addComponent(version)
|
||||
.addValidatedField(ValidatedField.of(upload, () -> upload, consumer -> upload.addFinishedListener(event -> consumer.accept(upload)))
|
||||
.addValidator(InMemoryUpload::isUploaded, "Upload failed"))
|
||||
.addComponent(progressBar)
|
||||
.addCreateButton(popup -> {
|
||||
dataService.store(new ProguardMapping(app, version.getValue(), upload.getUploadedString()));
|
||||
grid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show();
|
||||
}));
|
||||
}
|
||||
Panel panel = new Panel(layout);
|
||||
panel.setCaption("De-Obfuscation");
|
||||
panel.addStyleName(AcraTheme.NO_BACKGROUND);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private Panel exportPanel(@NonNull App app) {
|
||||
ComboBox<String> mailBox = new ComboBox<>("By Email Address", dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.userEmail));
|
||||
mailBox.setEmptySelectionAllowed(true);
|
||||
mailBox.setSizeFull();
|
||||
ComboBox<String> idBox = new ComboBox<>("By Installation ID", dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.installationId));
|
||||
idBox.setEmptySelectionAllowed(true);
|
||||
idBox.setSizeFull();
|
||||
Button download = new Button("Download", e -> {
|
||||
if (idBox.getValue() == null && mailBox.getValue() == null) {
|
||||
Notification.show("Nothing selected", Notification.Type.WARNING_MESSAGE);
|
||||
} else {
|
||||
Page page = UI.getCurrent().getPage();
|
||||
page.open(UriComponentsBuilder.fromUri(page.getLocation())
|
||||
.fragment(null)
|
||||
.pathSegment(RestReportInterface.EXPORT_PATH)
|
||||
.queryParam(RestReportInterface.PARAM_APP, app.getId())
|
||||
.queryParam(RestReportInterface.PARAM_ID, idBox.getValue())
|
||||
.queryParam(RestReportInterface.PARAM_MAIL, mailBox.getValue())
|
||||
.build()
|
||||
.toUriString(), null);
|
||||
}
|
||||
});
|
||||
download.setSizeFull();
|
||||
VerticalLayout layout = new VerticalLayout(mailBox, idBox, download);
|
||||
Panel panel = new Panel(layout);
|
||||
panel.setCaption("Export");
|
||||
panel.addStyleName(AcraTheme.NO_BACKGROUND);
|
||||
return panel;
|
||||
public AdminTab(@NonNull List<AdminPanel> panels) {
|
||||
super(panels);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package com.faendir.acra.ui.view.app.tabs;
|
||||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.ui.view.base.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.layout.ComponentFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -25,5 +25,5 @@ import java.io.Serializable;
|
|||
* @author Lukas
|
||||
* @since 27.03.2018
|
||||
*/
|
||||
public interface AppTab extends MyTabSheet.Tab<App>, Serializable {
|
||||
public interface AppTab extends ComponentFactory<App>, Serializable {
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ import com.faendir.acra.security.SecurityUtils;
|
|||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.MyCheckBox;
|
||||
import com.faendir.acra.ui.view.base.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.Popup;
|
||||
import com.faendir.acra.ui.view.base.layout.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.faendir.acra.util.TimeSpanRenderer;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.app.tabs.panels;
|
||||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.ui.view.base.layout.PanelContentFactory;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
public interface AdminPanel extends PanelContentFactory<App> {
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.faendir.acra.ui.view.app.tabs.panels;
|
||||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.ConfigurationLabel;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.faendir.acra.ui.view.base.popup.ValidatedField;
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.server.Resource;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.shared.ui.ContentMode;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.AcraTheme;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.vaadin.risto.stepper.IntStepper;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class DangerPanel implements AdminPanel {
|
||||
@NonNull private final DataService dataService;
|
||||
|
||||
@Autowired
|
||||
public DangerPanel(@NonNull DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component createContent(@NonNull App app, @NonNull NavigationManager navigationManager) {
|
||||
Button configButton = new Button("Create new ACRA Configuration",
|
||||
e -> new Popup().setTitle("Confirm")
|
||||
.addComponent(new Label("Are you sure you want to create a new ACRA configuration?<br>The existing configuration will be invalidated", ContentMode.HTML))
|
||||
.addYesNoButtons(popup -> popup.clear().addComponent(new ConfigurationLabel(dataService.recreateReporterUser(app))).addCloseButton().show())
|
||||
.show());
|
||||
configButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
Button matchingButton = new Button("Configure bug matching", e -> {
|
||||
App.Configuration configuration = app.getConfiguration();
|
||||
CheckBox matchByMessage = new CheckBox("Match by exception message", configuration.matchByMessage());
|
||||
CheckBox ignoreInstanceIds = new CheckBox("Ignore instance ids", configuration.ignoreInstanceIds());
|
||||
CheckBox ignoreAndroidLineNumbers = new CheckBox("Ignore android SDK line numbers", configuration.ignoreAndroidLineNumbers());
|
||||
new Popup().addValidatedField(ValidatedField.of(matchByMessage), true)
|
||||
.addValidatedField(ValidatedField.of(ignoreInstanceIds), true)
|
||||
.addValidatedField(ValidatedField.of(ignoreAndroidLineNumbers), true)
|
||||
.addComponent(new Label(
|
||||
"Are you sure you want to save this configuration? All bugs will be recalculated, which may take some time and will reset the 'solved' status"))
|
||||
.addYesNoButtons(p -> dataService.changeConfiguration(app,
|
||||
new App.Configuration(matchByMessage.getValue(), ignoreInstanceIds.getValue(), ignoreAndroidLineNumbers.getValue())), true)
|
||||
.show();
|
||||
});
|
||||
matchingButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
IntStepper age = new IntStepper();
|
||||
age.setValue(30);
|
||||
age.setMinValue(0);
|
||||
age.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
HorizontalLayout purgeAge = new HorizontalLayout();
|
||||
purgeAge.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
|
||||
purgeAge.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
purgeAge.addStyleName(AcraTheme.NO_MARGIN);
|
||||
purgeAge.addComponents(new Button("Purge", e -> dataService.deleteReportsOlderThanDays(app, age.getValue())), new Label(" Reports older than "), age, new Label(" Days"));
|
||||
purgeAge.setExpandRatio(age, 1);
|
||||
ComboBox<Integer> versionBox = new ComboBox<>(null, dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.stacktrace.versionCode));
|
||||
versionBox.setEmptySelectionAllowed(false);
|
||||
versionBox.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
HorizontalLayout purgeVersion = new HorizontalLayout();
|
||||
purgeVersion.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
purgeVersion.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
|
||||
purgeVersion.addStyleName(AcraTheme.NO_MARGIN);
|
||||
purgeVersion.addComponents(new Button("Purge", e -> {
|
||||
if (versionBox.getValue() != null) {
|
||||
dataService.deleteReportsBeforeVersion(app, versionBox.getValue());
|
||||
}
|
||||
}), new Label(" Reports before Version "), versionBox);
|
||||
purgeVersion.setExpandRatio(versionBox, 1);
|
||||
Button deleteButton = new Button("Delete App",
|
||||
e -> new Popup().setTitle("Confirm").addComponent(new Label("Are you sure you want to delete this app and all its associated content?")).addYesNoButtons(popup -> {
|
||||
dataService.delete(app);
|
||||
navigationManager.navigateBack();
|
||||
}, true).show());
|
||||
VerticalLayout layout = new VerticalLayout(configButton, matchingButton, purgeAge, purgeVersion, deleteButton);
|
||||
deleteButton.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
layout.setSizeFull();
|
||||
layout.addStyleName(AcraTheme.NO_PADDING);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCaption() {
|
||||
return "Danger Zone";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getIcon() {
|
||||
return VaadinIcons.EXCLAMATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStyleName() {
|
||||
return AcraTheme.RED_PANEL_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.app.tabs.panels;
|
||||
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.rest.RestReportInterface;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Notification;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class ExportPanel implements AdminPanel {
|
||||
@NonNull private final DataService dataService;
|
||||
|
||||
@Autowired
|
||||
public ExportPanel(@NonNull DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
@Override
|
||||
public Component createContent(@NonNull App app, @NonNull NavigationManager navigationManager) {
|
||||
ComboBox<String> mailBox = new ComboBox<>("By Email Address", dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.userEmail));
|
||||
mailBox.setEmptySelectionAllowed(true);
|
||||
mailBox.setSizeFull();
|
||||
ComboBox<String> idBox = new ComboBox<>("By Installation ID", dataService.getFromReports(QReport.report.stacktrace.bug.app.eq(app), QReport.report.installationId));
|
||||
idBox.setEmptySelectionAllowed(true);
|
||||
idBox.setSizeFull();
|
||||
Button download = new Button("Download", e -> {
|
||||
if (idBox.getValue() == null && mailBox.getValue() == null) {
|
||||
Notification.show("Nothing selected", Notification.Type.WARNING_MESSAGE);
|
||||
} else {
|
||||
Page page = UI.getCurrent().getPage();
|
||||
page.open(UriComponentsBuilder.fromUri(page.getLocation())
|
||||
.fragment(null)
|
||||
.pathSegment(RestReportInterface.EXPORT_PATH)
|
||||
.queryParam(RestReportInterface.PARAM_APP, app.getId())
|
||||
.queryParam(RestReportInterface.PARAM_ID, idBox.getValue())
|
||||
.queryParam(RestReportInterface.PARAM_MAIL, mailBox.getValue())
|
||||
.build()
|
||||
.toUriString(), null);
|
||||
}
|
||||
});
|
||||
download.setSizeFull();
|
||||
return new VerticalLayout(mailBox, idBox, download);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCaption() {
|
||||
return "Export";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.app.tabs.panels;
|
||||
|
||||
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.security.SecurityUtils;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.InMemoryUpload;
|
||||
import com.faendir.acra.ui.view.base.layout.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.faendir.acra.ui.view.base.popup.ValidatedField;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.ProgressBar;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.renderers.ButtonRenderer;
|
||||
import com.vaadin.ui.themes.AcraTheme;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.vaadin.risto.stepper.IntStepper;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
@SpringComponent
|
||||
@ViewScope
|
||||
public class ProguardPanel implements AdminPanel{
|
||||
@NonNull private final DataService dataService;
|
||||
|
||||
@Autowired
|
||||
public ProguardPanel(@NonNull DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
@Override
|
||||
public Component createContent(@NonNull App app, @NonNull NavigationManager navigationManager) {
|
||||
VerticalLayout layout = new VerticalLayout();
|
||||
MyGrid<ProguardMapping> grid = new MyGrid<>(null, dataService.getMappingProvider(app));
|
||||
grid.setSizeToRows();
|
||||
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());
|
||||
grid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show()));
|
||||
}
|
||||
layout.addComponent(grid);
|
||||
layout.addStyleName(AcraTheme.NO_PADDING);
|
||||
if (SecurityUtils.hasPermission(app, Permission.Level.EDIT)) {
|
||||
layout.addComponent(new Button("Add File", e -> {
|
||||
IntStepper version = new IntStepper("Version code");
|
||||
version.setValue(dataService.getMaximumMappingVersion(app).map(i -> i + 1).orElse(1));
|
||||
InMemoryUpload upload = new InMemoryUpload("Mapping file:");
|
||||
ProgressBar progressBar = new ProgressBar();
|
||||
upload.addProgressListener((readBytes, contentLength) -> layout.getUI().access(() -> progressBar.setValue((float) readBytes / contentLength)));
|
||||
new Popup().setTitle("New Mapping Configuration")
|
||||
.addComponent(version)
|
||||
.addValidatedField(ValidatedField.of(upload, () -> upload, consumer -> upload.addFinishedListener(event -> consumer.accept(upload)))
|
||||
.addValidator(InMemoryUpload::isUploaded, "Upload failed"))
|
||||
.addComponent(progressBar)
|
||||
.addCreateButton(popup -> {
|
||||
dataService.store(new ProguardMapping(app, version.getValue(), upload.getUploadedString()));
|
||||
grid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show();
|
||||
}));
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCaption() {
|
||||
return "De-Obfuscation";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
|
||||
import com.vaadin.server.FileDownloader;
|
||||
import com.vaadin.server.StreamResource;
|
||||
import com.vaadin.server.VaadinRequest;
|
||||
import com.vaadin.server.VaadinResponse;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 24.05.18
|
||||
*/
|
||||
|
||||
public class OnDemandFileDownloader extends FileDownloader {
|
||||
@NonNull
|
||||
private final Supplier<Pair<InputStream, String>> provider;
|
||||
|
||||
public OnDemandFileDownloader(@NonNull Supplier<Pair<InputStream, String>> provider) {
|
||||
super(new StreamResource(() -> new ByteArrayInputStream(new byte[0]), ""));
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleConnectorRequest(VaadinRequest request, VaadinResponse response, String path)
|
||||
throws IOException {
|
||||
Pair<InputStream, String> source = provider.get();
|
||||
if (source != null) {
|
||||
getResource().setStreamSource(source::getFirst);
|
||||
getResource().setFilename(source.getSecond());
|
||||
return super.handleConnectorRequest(request, response, path);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private StreamResource getResource() {
|
||||
return (StreamResource) getFileDownloadResource();
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,8 @@ 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.base.layout.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.faendir.acra.ui.view.report.ReportView;
|
||||
import com.faendir.acra.util.TimeSpanRenderer;
|
||||
import com.vaadin.shared.data.sort.SortDirection;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.vaadin.ui.Component;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
public interface ComponentFactory<T> extends Ordered {
|
||||
Component createContent(@NonNull T t, @NonNull NavigationManager navigationManager);
|
||||
|
||||
String getCaption();
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CssLayout;
|
|
@ -14,11 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.faendir.acra.client.mygrid.MiddleClickGridExtensionConnector;
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.vaadin.data.ValueProvider;
|
||||
import com.vaadin.data.provider.DataProvider;
|
|
@ -14,13 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomComponent;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -40,14 +39,14 @@ public class MyTabSheet<T> extends TabSheet {
|
|||
private final NavigationManager navigationManager;
|
||||
|
||||
@SafeVarargs
|
||||
public MyTabSheet(@NonNull T t, @NonNull NavigationManager navigationManager, Tab<T>... tabs) {
|
||||
public MyTabSheet(@NonNull T t, @NonNull NavigationManager navigationManager, ComponentFactory<T>... tabs) {
|
||||
this(t, navigationManager, Arrays.asList(tabs));
|
||||
}
|
||||
|
||||
public MyTabSheet(@NonNull T t, @NonNull NavigationManager navigationManager, Collection<? extends Tab<T>> tabs) {
|
||||
public MyTabSheet(@NonNull T t, @NonNull NavigationManager navigationManager, Collection<? extends ComponentFactory<T>> tabs) {
|
||||
this.t = t;
|
||||
this.navigationManager = navigationManager;
|
||||
for (Tab<T> tab : tabs) {
|
||||
for (ComponentFactory<T> tab : tabs) {
|
||||
addTab(tab);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +55,7 @@ public class MyTabSheet<T> extends TabSheet {
|
|||
return StreamSupport.stream(Spliterators.spliterator(iterator(), getComponentCount(), Spliterator.ORDERED), false).map(Component::getCaption).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void addTab(Tab<T> tab) {
|
||||
public void addTab(ComponentFactory<T> tab) {
|
||||
TabWrapper<T> wrapper = new TabWrapper<>(t, navigationManager, tab);
|
||||
addComponent(wrapper);
|
||||
addSelectedTabChangeListener(wrapper);
|
||||
|
@ -79,18 +78,12 @@ public class MyTabSheet<T> extends TabSheet {
|
|||
setSelectedTab(component);
|
||||
}
|
||||
|
||||
public interface Tab<T> extends Ordered {
|
||||
Component createContent(@NonNull T t, @NonNull NavigationManager navigationManager);
|
||||
|
||||
String getCaption();
|
||||
}
|
||||
|
||||
private static class TabWrapper<T> extends CustomComponent implements SelectedTabChangeListener {
|
||||
private final T t;
|
||||
private final NavigationManager navigationManager;
|
||||
private final Tab<T> tab;
|
||||
private final ComponentFactory<T> tab;
|
||||
|
||||
private TabWrapper(@NonNull T t, @NonNull NavigationManager navigationManager, @NonNull Tab<T> tab) {
|
||||
private TabWrapper(@NonNull T t, @NonNull NavigationManager navigationManager, @NonNull ComponentFactory<T> tab) {
|
||||
this.t = t;
|
||||
this.navigationManager = navigationManager;
|
||||
this.tab = tab;
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.vaadin.server.Resource;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
public interface PanelContentFactory<T> extends ComponentFactory<T> {
|
||||
default Resource getIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default String getStyleName() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* (C) Copyright 2018 Lukas Morawietz (https://github.com/F43nd1r)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.faendir.acra.ui.view.base.layout;
|
||||
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.Panel;
|
||||
import com.vaadin.ui.themes.AcraTheme;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 17.06.18
|
||||
*/
|
||||
public abstract class PanelFlexTab<T> implements ComponentFactory<T> {
|
||||
@NonNull private final List<? extends PanelContentFactory<T>> factories;
|
||||
|
||||
public PanelFlexTab(@NonNull List<? extends PanelContentFactory<T>> factories) {
|
||||
this.factories = factories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component createContent(@NonNull T t, @NonNull NavigationManager navigationManager) {
|
||||
FlexLayout layout = new FlexLayout(factories.stream().map(factory -> {
|
||||
Panel panel = new Panel(factory.createContent(t, navigationManager));
|
||||
panel.setCaption(factory.getCaption());
|
||||
panel.setIcon(factory.getIcon());
|
||||
panel.addStyleName(AcraTheme.NO_BACKGROUND);
|
||||
if (factory.getStyleName() != null) {
|
||||
panel.addStyleName(factory.getStyleName());
|
||||
}
|
||||
return panel;
|
||||
}).toArray(Component[]::new));
|
||||
layout.setWidth(100, Sizeable.Unit.PERCENTAGE);
|
||||
Panel root = new Panel(layout);
|
||||
root.setSizeFull();
|
||||
root.addStyleNames(AcraTheme.NO_BACKGROUND, AcraTheme.NO_BORDER);
|
||||
return root;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.navigation;
|
||||
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.vaadin.navigator.View;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.navigation;
|
||||
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import org.springframework.lang.NonNull;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.navigation;
|
||||
|
||||
import com.faendir.acra.ui.navigation.MyNavigator;
|
||||
import com.faendir.acra.ui.navigation.SingleViewProvider;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.popup;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.faendir.acra.ui.view.base;
|
||||
package com.faendir.acra.ui.view.base.popup;
|
||||
|
||||
import com.vaadin.server.UserError;
|
||||
import com.vaadin.ui.AbstractComponent;
|
|
@ -18,7 +18,7 @@ package com.faendir.acra.ui.view.base.statistics;
|
|||
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.view.base.FlexLayout;
|
||||
import com.faendir.acra.ui.view.base.layout.FlexLayout;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
|
|
|
@ -23,8 +23,8 @@ import com.faendir.acra.service.DataService;
|
|||
import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
||||
import com.faendir.acra.ui.navigation.MyNavigator;
|
||||
import com.faendir.acra.ui.navigation.SingleParametrizedViewProvider;
|
||||
import com.faendir.acra.ui.view.base.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.ParametrizedBaseView;
|
||||
import com.faendir.acra.ui.view.base.layout.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.navigation.ParametrizedBaseView;
|
||||
import com.faendir.acra.ui.view.bug.tabs.BugTab;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
|
|
|
@ -20,7 +20,7 @@ import com.faendir.acra.model.Permission;
|
|||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
||||
import com.faendir.acra.ui.navigation.NavigationManager;
|
||||
import com.faendir.acra.ui.view.base.Popup;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.vaadin.server.Sizeable;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.ViewScope;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package com.faendir.acra.ui.view.bug.tabs;
|
||||
|
||||
import com.faendir.acra.model.Bug;
|
||||
import com.faendir.acra.ui.view.base.MyTabSheet;
|
||||
import com.faendir.acra.ui.view.base.layout.ComponentFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -25,5 +25,5 @@ import java.io.Serializable;
|
|||
* @author Lukas
|
||||
* @since 27.03.2018
|
||||
*/
|
||||
public interface BugTab extends MyTabSheet.Tab<Bug>, Serializable {
|
||||
public interface BugTab extends ComponentFactory<Bug>, Serializable {
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import com.faendir.acra.model.Report;
|
|||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.annotation.RequiresAppPermission;
|
||||
import com.faendir.acra.ui.navigation.SingleParametrizedViewProvider;
|
||||
import com.faendir.acra.ui.view.base.ParametrizedBaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.ParametrizedBaseView;
|
||||
import com.faendir.acra.util.Utils;
|
||||
import com.vaadin.server.FileDownloader;
|
||||
import com.vaadin.server.StreamResource;
|
||||
|
|
|
@ -20,7 +20,7 @@ import com.faendir.acra.security.SecurityUtils;
|
|||
import com.faendir.acra.model.User;
|
||||
import com.faendir.acra.service.UserService;
|
||||
import com.faendir.acra.ui.BackendUI;
|
||||
import com.faendir.acra.ui.view.base.BaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.faendir.acra.ui.navigation.SingleViewProvider;
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import com.vaadin.server.UserError;
|
||||
|
|
|
@ -25,11 +25,11 @@ import com.faendir.acra.service.DataService;
|
|||
import com.faendir.acra.service.UserService;
|
||||
import com.faendir.acra.ui.annotation.RequiresRole;
|
||||
import com.faendir.acra.ui.navigation.SingleViewProvider;
|
||||
import com.faendir.acra.ui.view.base.BaseView;
|
||||
import com.faendir.acra.ui.view.base.navigation.BaseView;
|
||||
import com.faendir.acra.ui.view.base.MyCheckBox;
|
||||
import com.faendir.acra.ui.view.base.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.Popup;
|
||||
import com.faendir.acra.ui.view.base.ValidatedField;
|
||||
import com.faendir.acra.ui.view.base.layout.MyGrid;
|
||||
import com.faendir.acra.ui.view.base.popup.Popup;
|
||||
import com.faendir.acra.ui.view.base.popup.ValidatedField;
|
||||
import com.vaadin.navigator.ViewChangeListener;
|
||||
import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
|
|
Loading…
Reference in a new issue