reduce duplicated code
This commit is contained in:
parent
def881b156
commit
46d9ffaded
19 changed files with 206 additions and 272 deletions
|
@ -68,7 +68,7 @@ public abstract class BaseChange implements LiquibaseChangePostProcessor {
|
|||
int offset = 0;
|
||||
List<?> list;
|
||||
while (!(list = supplier.get().setFirstResult(offset).setMaxResults(64).getResultList()).isEmpty()) {
|
||||
list.forEach(consumer::accept);
|
||||
list.forEach(consumer);
|
||||
offset += list.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public class RestReportInterface {
|
|||
BooleanExpression where = null;
|
||||
String name = "";
|
||||
if (mail != null && !mail.isEmpty()) {
|
||||
where = report.userEmail.eq(mail).and(where);
|
||||
where = report.userEmail.eq(mail);
|
||||
name += "_" + mail;
|
||||
}
|
||||
if (id != null && !id.isEmpty()) {
|
||||
|
|
|
@ -1,25 +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.base;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 11.10.18
|
||||
*/
|
||||
public interface ActiveChildAware<C, P> {
|
||||
void setActiveChild(C child, P parameter);
|
||||
}
|
147
src/main/java/com/faendir/acra/ui/base/TabView.java
Normal file
147
src/main/java/com/faendir/acra/ui/base/TabView.java
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* (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.base;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.component.FlexLayout;
|
||||
import com.vaadin.flow.component.AttachEvent;
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.component.tabs.Tabs;
|
||||
import com.vaadin.flow.router.BeforeEvent;
|
||||
import com.vaadin.flow.router.HasUrlParameter;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 03.12.18
|
||||
*/
|
||||
public class TabView<T extends Component & HasUrlParameter<P>, P> extends ParentLayout {
|
||||
private final TabInfo<? extends T, P>[] tabs;
|
||||
private final Tabs header;
|
||||
private P parameter;
|
||||
|
||||
@SafeVarargs
|
||||
public TabView(TabInfo<? extends T, P>... tabs) {
|
||||
this.tabs = tabs;
|
||||
header = new Tabs(Stream.of(tabs).map(def -> new com.faendir.acra.ui.component.Tab(def.getLabelId())).toArray(com.faendir.acra.ui.component.Tab[]::new));
|
||||
header.addSelectedChangeListener(e -> getUI().ifPresent(ui -> ui.navigate(tabs[e.getSource().getSelectedIndex()].tabClass, parameter)));
|
||||
setSizeFull();
|
||||
FlexLayout content = new FlexLayout();
|
||||
content.setWidthFull();
|
||||
expand(content);
|
||||
content.getStyle().set("overflow", "auto");
|
||||
setRouterRoot(content);
|
||||
getStyle().set("flex-direction", "column");
|
||||
removeAll();
|
||||
add(header, content);
|
||||
}
|
||||
|
||||
private void setActiveChild(T child, P parameter) {
|
||||
this.parameter = parameter;
|
||||
for (int i = 0; i < tabs.length; i++) {
|
||||
if (tabs[i].getTabClass().equals(child.getClass())) {
|
||||
header.setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class TabInfo<T extends HasUrlParameter<P>, P> {
|
||||
private final Class<T> tabClass;
|
||||
private final String labelId;
|
||||
|
||||
public TabInfo(Class<T> tabClass, String labelId) {
|
||||
this.tabClass = tabClass;
|
||||
this.labelId = labelId;
|
||||
}
|
||||
|
||||
public Class<T> getTabClass() {
|
||||
return tabClass;
|
||||
}
|
||||
|
||||
public String getLabelId() {
|
||||
return labelId;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Tab<T extends Component, P> extends Composite<T> implements HasSecureIntParameter, HasRoute {
|
||||
private final DataService dataService;
|
||||
private final BiFunction<DataService, Integer, Optional<P>> parameterGetter;
|
||||
private final Function<P, Integer> idGetter;
|
||||
private final Function<P, String> titleGetter;
|
||||
private final Function<P, Parent<?>> parentGetter;
|
||||
private P parameter;
|
||||
|
||||
public Tab(DataService dataService, BiFunction<DataService, Integer, Optional<P>> parameterGetter, Function<P, Integer> idGetter, Function<P, String> titleGetter, Function<P, Parent<?>> parentGetter) {
|
||||
this.dataService = dataService;
|
||||
this.parameterGetter = parameterGetter;
|
||||
this.idGetter = idGetter;
|
||||
this.titleGetter = titleGetter;
|
||||
this.parentGetter = parentGetter;
|
||||
}
|
||||
|
||||
public DataService getDataService() {
|
||||
return dataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterSecure(BeforeEvent event, Integer parameter) {
|
||||
Optional<P> p = parameterGetter.apply(dataService, parameter);
|
||||
if (p.isPresent()) {
|
||||
this.parameter = p.get();
|
||||
} else {
|
||||
event.rerouteToError(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void init(P parameter);
|
||||
|
||||
@Override
|
||||
protected void onAttach(AttachEvent attachEvent) {
|
||||
super.onAttach(attachEvent);
|
||||
init(this.parameter);
|
||||
Optional<Component> parent = getParent();
|
||||
while (parent.isPresent()) {
|
||||
if (parent.get() instanceof TabView) {
|
||||
//noinspection unchecked
|
||||
((TabView<Tab<?, ?>, Integer>) parent.get()).setActiveChild(this, idGetter.apply(parameter));
|
||||
break;
|
||||
}
|
||||
parent = parent.get().getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Path.Element<?> getPathElement() {
|
||||
//noinspection unchecked
|
||||
return new Path.ParametrizedTextElement<>((Class<? extends Tab<?, ?>>) getClass(), idGetter.apply(parameter), Messages.ONE_ARG, titleGetter.apply(parameter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parent<?> getLogicalParent() {
|
||||
return parentGetter.apply(parameter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -136,7 +136,7 @@ public class Popup extends Dialog {
|
|||
if(component instanceof HasSize) {
|
||||
try {
|
||||
((HasSize)component).setWidth("100%");
|
||||
}catch (UnsupportedOperationException e) {
|
||||
}catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -85,9 +85,7 @@ public class MainView extends ParentLayout {
|
|||
|
||||
private void showMain() {
|
||||
Translatable<Checkbox> darkTheme = Translatable.createCheckbox(false, Messages.DARK_THEME);
|
||||
darkTheme.getContent().addValueChangeListener(e -> {
|
||||
UI.getCurrent().getElement().setAttribute("theme", e.getValue() ? Lumo.DARK : Lumo.LIGHT);
|
||||
});
|
||||
darkTheme.getContent().addValueChangeListener(e -> UI.getCurrent().getElement().setAttribute("theme", e.getValue() ? Lumo.DARK : Lumo.LIGHT));
|
||||
Translatable<Button> userManager = Translatable.createButton(e -> UI.getCurrent().navigate(UserManager.class), Messages.USER_MANAGER);
|
||||
userManager.setDefaultTextStyle();
|
||||
userManager.getContent().addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
||||
|
|
|
@ -17,24 +17,16 @@
|
|||
package com.faendir.acra.ui.view.app;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.ui.base.ActiveChildAware;
|
||||
import com.faendir.acra.ui.base.ParentLayout;
|
||||
import com.faendir.acra.ui.component.FlexLayout;
|
||||
import com.faendir.acra.ui.component.Tab;
|
||||
import com.faendir.acra.ui.base.TabView;
|
||||
import com.faendir.acra.ui.view.MainView;
|
||||
import com.faendir.acra.ui.view.app.tabs.AdminTab;
|
||||
import com.faendir.acra.ui.view.app.tabs.AppTab;
|
||||
import com.faendir.acra.ui.view.app.tabs.BugTab;
|
||||
import com.faendir.acra.ui.view.app.tabs.ReportTab;
|
||||
import com.faendir.acra.ui.view.app.tabs.StatisticsTab;
|
||||
import com.vaadin.flow.component.tabs.Tabs;
|
||||
import com.vaadin.flow.router.RoutePrefix;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import com.vaadin.flow.spring.annotation.UIScope;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
|
@ -44,42 +36,11 @@ import java.util.stream.Stream;
|
|||
@SpringComponent
|
||||
@RoutePrefix("app")
|
||||
@com.vaadin.flow.router.ParentLayout(MainView.class)
|
||||
public class AppView extends ParentLayout implements ActiveChildAware<AppTab<?>, App> {
|
||||
private App app;
|
||||
private final Tabs tabs;
|
||||
|
||||
@Autowired
|
||||
public class AppView extends TabView<AppTab<?>, Integer> {
|
||||
public AppView() {
|
||||
tabs = new Tabs(Stream.of(TabDef.values()).map(def -> new Tab(def.labelId)).toArray(Tab[]::new));
|
||||
tabs.addSelectedChangeListener(e -> getUI().ifPresent(ui -> ui.navigate(TabDef.values()[e.getSource().getSelectedIndex()].tabClass, app.getId())));
|
||||
setSizeFull();
|
||||
FlexLayout content = new FlexLayout();
|
||||
content.setWidthFull();
|
||||
expand(content);
|
||||
content.getStyle().set("overflow","auto");
|
||||
setRouterRoot(content);
|
||||
getStyle().set("flex-direction","column");
|
||||
removeAll();
|
||||
add(tabs, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActiveChild(AppTab<?> child, App parameter) {
|
||||
app = parameter;
|
||||
Stream.of(TabDef.values()).filter(def -> def.tabClass.equals(child.getClass())).findAny().ifPresent(def -> tabs.setSelectedIndex(def.ordinal()));
|
||||
}
|
||||
|
||||
private enum TabDef {
|
||||
BUG(Messages.BUGS, BugTab.class),
|
||||
REPORT(Messages.REPORTS, ReportTab.class),
|
||||
STATISTICS(Messages.STATISTICS, StatisticsTab.class),
|
||||
ADMIN(Messages.ADMIN, AdminTab.class);
|
||||
private String labelId;
|
||||
private Class<? extends AppTab<?>> tabClass;
|
||||
|
||||
TabDef(String labelId, Class<? extends AppTab<?>> tabClass) {
|
||||
this.labelId = labelId;
|
||||
this.tabClass = tabClass;
|
||||
}
|
||||
super( new TabInfo<>(BugTab.class, Messages.BUGS),
|
||||
new TabInfo<>(ReportTab.class, Messages.REPORTS),
|
||||
new TabInfo<>(StatisticsTab.class, Messages.STATISTICS),
|
||||
new TabInfo<>(AdminTab.class, Messages.ADMIN));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ import com.querydsl.core.types.dsl.BooleanExpression;
|
|||
import com.vaadin.flow.component.UI;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.combobox.ComboBox;
|
||||
import com.vaadin.flow.component.html.Div;
|
||||
import com.vaadin.flow.component.icon.Icon;
|
||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.component.upload.Upload;
|
||||
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
|
||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||
|
@ -69,18 +69,19 @@ import static com.faendir.acra.model.QReport.report;
|
|||
@UIScope
|
||||
@SpringComponent
|
||||
@Route(value = "admin", layout = AppView.class)
|
||||
public class AdminTab extends AppTab<FlexLayout> {
|
||||
public class AdminTab extends AppTab<Div> {
|
||||
@Autowired
|
||||
public AdminTab(DataService dataService) {
|
||||
super(dataService);
|
||||
getContent().setSizeFull();
|
||||
}
|
||||
|
||||
@Override
|
||||
void init(App app) {
|
||||
protected void init(App app) {
|
||||
getContent().removeAll();
|
||||
getContent().setFlexWrap(FlexLayout.FlexWrap.WRAP);
|
||||
getContent().setAlignItems(FlexComponent.Alignment.START);
|
||||
getContent().setWidthFull();
|
||||
FlexLayout layout = new FlexLayout();
|
||||
layout.setFlexWrap(FlexLayout.FlexWrap.WRAP);
|
||||
layout.setWidthFull();
|
||||
MyGrid<ProguardMapping> mappingGrid = new MyGrid<>(getDataService().getMappingProvider(app));
|
||||
mappingGrid.setHeightToRows();
|
||||
mappingGrid.addColumn(ProguardMapping::getVersionCode, QProguardMapping.proguardMapping.versionCode, Messages.VERSION).setFlexGrow(1);
|
||||
|
@ -112,8 +113,8 @@ public class AdminTab extends AppTab<FlexLayout> {
|
|||
.show();
|
||||
}, Messages.NEW_FILE));
|
||||
}
|
||||
getContent().add(mappingCard);
|
||||
getContent().expand(mappingCard);
|
||||
layout.add(mappingCard);
|
||||
layout.expand(mappingCard);
|
||||
|
||||
Translatable<ComboBox<String>> mailBox = Translatable.createComboBox(getDataService().getFromReports(app, null, QReport.report.userEmail), Messages.BY_MAIL);
|
||||
mailBox.setWidthFull();
|
||||
|
@ -138,8 +139,8 @@ public class AdminTab extends AppTab<FlexLayout> {
|
|||
Card exportCard = new Card(mailBox, idBox, download);
|
||||
exportCard.setHeader(Translatable.createText(Messages.EXPORT));
|
||||
exportCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
getContent().add(exportCard);
|
||||
getContent().expand(exportCard);
|
||||
layout.add(exportCard);
|
||||
layout.expand(exportCard);
|
||||
|
||||
Translatable<Button> configButton = Translatable.createButton(e -> new Popup().setTitle(Messages.NEW_ACRA_CONFIG_CONFIRM)
|
||||
.addYesNoButtons(popup -> popup.clear().addComponent(new ConfigurationLabel(getDataService().recreateReporterUser(app))).addCloseButton().show())
|
||||
|
@ -154,14 +155,13 @@ public class AdminTab extends AppTab<FlexLayout> {
|
|||
.show();
|
||||
}, Messages.NEW_BUG_CONFIG);
|
||||
matchingButton.setWidthFull();
|
||||
TextField age = new TextField();
|
||||
age.setValue("30");
|
||||
age.setWidth("100%");
|
||||
NumberInput age = new NumberInput(30);
|
||||
age.setWidthFull();
|
||||
FlexLayout purgeAge = new FlexLayout();
|
||||
purgeAge.setWidthFull();
|
||||
purgeAge.preventWhiteSpaceBreaking();
|
||||
purgeAge.setAlignItems(FlexComponent.Alignment.CENTER);
|
||||
purgeAge.add(Translatable.createButton(e -> getDataService().deleteReportsOlderThanDays(app, Integer.parseInt(age.getValue())), Messages.PURGE),
|
||||
purgeAge.add(Translatable.createButton(e -> getDataService().deleteReportsOlderThanDays(app, age.getValue().intValue()), Messages.PURGE),
|
||||
Translatable.createLabel(Messages.REPORTS_OLDER_THAN1),
|
||||
age, Translatable.createLabel(Messages.REPORTS_OLDER_THAN2));
|
||||
purgeAge.expand(age);
|
||||
|
@ -186,7 +186,8 @@ public class AdminTab extends AppTab<FlexLayout> {
|
|||
dangerCard.setHeader(Translatable.createText(Messages.DANGER_ZONE));
|
||||
dangerCard.setHeaderColor("var(----lumo-error-text-color)", "var(--lumo-error-color)");
|
||||
dangerCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
getContent().add(dangerCard);
|
||||
getContent().expand(dangerCard);
|
||||
layout.add(dangerCard);
|
||||
layout.expand(dangerCard);
|
||||
getContent().add(layout);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,74 +16,18 @@
|
|||
|
||||
package com.faendir.acra.ui.view.app.tabs;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.base.ActiveChildAware;
|
||||
import com.faendir.acra.ui.base.HasRoute;
|
||||
import com.faendir.acra.ui.base.HasSecureIntParameter;
|
||||
import com.faendir.acra.ui.base.Path;
|
||||
import com.faendir.acra.ui.base.TabView;
|
||||
import com.faendir.acra.ui.view.Overview;
|
||||
import com.vaadin.flow.component.AttachEvent;
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.router.BeforeEvent;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 14.07.18
|
||||
*/
|
||||
public abstract class AppTab<T extends Component> extends Composite<T> implements HasSecureIntParameter, HasRoute {
|
||||
private final DataService dataService;
|
||||
private App app;
|
||||
|
||||
public abstract class AppTab<T extends Component> extends TabView.Tab<T, App> {
|
||||
public AppTab(DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
|
||||
public DataService getDataService() {
|
||||
return dataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterSecure(BeforeEvent event, Integer parameter) {
|
||||
Optional<App> app = dataService.findApp(parameter);
|
||||
if (app.isPresent()) {
|
||||
this.app = app.get();
|
||||
} else {
|
||||
event.rerouteToError(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void init(App app);
|
||||
|
||||
@Override
|
||||
protected void onAttach(AttachEvent attachEvent) {
|
||||
super.onAttach(attachEvent);
|
||||
init(this.app);
|
||||
Optional<Component> parent = getParent();
|
||||
while (parent.isPresent()) {
|
||||
if (parent.get() instanceof ActiveChildAware) {
|
||||
//noinspection unchecked
|
||||
((ActiveChildAware<AppTab<?>, App>) parent.get()).setActiveChild(this, app);
|
||||
break;
|
||||
}
|
||||
parent = parent.get().getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Path.Element<?> getPathElement() {
|
||||
//noinspection unchecked
|
||||
return new Path.ParametrizedTextElement<>((Class<? extends AppTab<?>>) getClass(), app.getId(), Messages.ONE_ARG, app.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parent<?> getLogicalParent() {
|
||||
return new Parent<>(Overview.class);
|
||||
super(dataService, DataService::findApp, App::getId, App::getName, app -> new Parent<>(Overview.class));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class BugTab extends AppTab<VerticalLayout> {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(App app) {
|
||||
protected void init(App app) {
|
||||
HorizontalLayout header = new HorizontalLayout();
|
||||
header.setWidth("100%");
|
||||
getContent().add(header);
|
||||
|
|
|
@ -46,7 +46,7 @@ public class ReportTab extends AppTab<Div> {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(App app) {
|
||||
protected void init(App app) {
|
||||
getContent().removeAll();
|
||||
getContent().add(new ReportList(app, getDataService().getReportProvider(app), avatarService, getDataService()::delete));
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class StatisticsTab extends AppTab<Div> {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(App app) {
|
||||
protected void init(App app) {
|
||||
getContent().removeAll();
|
||||
getContent().add(new Statistics(app, null, getDataService()));
|
||||
}
|
||||
|
|
|
@ -17,24 +17,16 @@
|
|||
package com.faendir.acra.ui.view.bug;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.Bug;
|
||||
import com.faendir.acra.ui.base.ActiveChildAware;
|
||||
import com.faendir.acra.ui.base.ParentLayout;
|
||||
import com.faendir.acra.ui.component.FlexLayout;
|
||||
import com.faendir.acra.ui.component.Tab;
|
||||
import com.faendir.acra.ui.base.TabView;
|
||||
import com.faendir.acra.ui.view.MainView;
|
||||
import com.faendir.acra.ui.view.bug.tabs.AdminTab;
|
||||
import com.faendir.acra.ui.view.bug.tabs.BugTab;
|
||||
import com.faendir.acra.ui.view.bug.tabs.ReportTab;
|
||||
import com.faendir.acra.ui.view.bug.tabs.StacktraceTab;
|
||||
import com.faendir.acra.ui.view.bug.tabs.StatisticsTab;
|
||||
import com.vaadin.flow.component.tabs.Tabs;
|
||||
import com.vaadin.flow.router.RoutePrefix;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import com.vaadin.flow.spring.annotation.UIScope;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
|
@ -44,42 +36,11 @@ import java.util.stream.Stream;
|
|||
@SpringComponent
|
||||
@RoutePrefix("bug")
|
||||
@com.vaadin.flow.router.ParentLayout(MainView.class)
|
||||
public class BugView extends ParentLayout implements ActiveChildAware<BugTab<?>, Bug> {
|
||||
private Bug bug;
|
||||
private final Tabs tabs;
|
||||
|
||||
@Autowired
|
||||
public class BugView extends TabView<BugTab<?>, Integer> {
|
||||
public BugView() {
|
||||
tabs = new Tabs(Stream.of(TabDef.values()).map(def -> new Tab(def.labelId)).toArray(Tab[]::new));
|
||||
tabs.addSelectedChangeListener(e -> getUI().ifPresent(ui -> ui.navigate(TabDef.values()[e.getSource().getSelectedIndex()].tabClass, bug.getId())));
|
||||
setSizeFull();
|
||||
FlexLayout content = new FlexLayout();
|
||||
content.setWidthFull();
|
||||
expand(content);
|
||||
content.getStyle().set("overflow", "auto");
|
||||
setRouterRoot(content);
|
||||
getStyle().set("flex-direction", "column");
|
||||
removeAll();
|
||||
add(tabs, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActiveChild(BugTab<?> child, Bug parameter) {
|
||||
bug = parameter;
|
||||
Stream.of(TabDef.values()).filter(def -> def.tabClass.equals(child.getClass())).findAny().ifPresent(def -> tabs.setSelectedIndex(def.ordinal()));
|
||||
}
|
||||
|
||||
private enum TabDef {
|
||||
REPORT(Messages.REPORTS, ReportTab.class),
|
||||
STACKTRACE(Messages.STACKTRACES, StacktraceTab.class),
|
||||
STATISTICS(Messages.STATISTICS, StatisticsTab.class),
|
||||
ADMIN(Messages.ADMIN, AdminTab.class);
|
||||
private String labelId;
|
||||
private Class<? extends BugTab<?>> tabClass;
|
||||
|
||||
TabDef(String labelId, Class<? extends BugTab<?>> tabClass) {
|
||||
this.labelId = labelId;
|
||||
this.tabClass = tabClass;
|
||||
}
|
||||
super(new TabInfo<>(ReportTab.class, Messages.REPORTS),
|
||||
new TabInfo<>(StacktraceTab.class, Messages.STACKTRACES),
|
||||
new TabInfo<>(StatisticsTab.class, Messages.STATISTICS),
|
||||
new TabInfo<>(AdminTab.class, Messages.ADMIN));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.faendir.acra.ui.view.Overview;
|
|||
import com.faendir.acra.ui.view.bug.BugView;
|
||||
import com.vaadin.flow.component.UI;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.html.Div;
|
||||
import com.vaadin.flow.component.textfield.TextArea;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
|
@ -42,17 +43,19 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
@UIScope
|
||||
@SpringComponent("bugAdminTab")
|
||||
@Route(value = "admin", layout = BugView.class)
|
||||
public class AdminTab extends BugTab<FlexLayout> {
|
||||
public class AdminTab extends BugTab<Div> {
|
||||
@Autowired
|
||||
public AdminTab(DataService dataService) {
|
||||
super(dataService);
|
||||
getContent().setSizeFull();
|
||||
}
|
||||
|
||||
@Override
|
||||
void init(Bug bug) {
|
||||
protected void init(Bug bug) {
|
||||
getContent().removeAll();
|
||||
getContent().setFlexWrap(FlexLayout.FlexWrap.WRAP);
|
||||
getContent().setWidthFull();
|
||||
FlexLayout layout = new FlexLayout();
|
||||
layout.setFlexWrap(FlexLayout.FlexWrap.WRAP);
|
||||
layout.setWidthFull();
|
||||
Translatable<TextArea> title = Translatable.createTextArea(bug.getTitle(), Messages.TITLE);
|
||||
title.setWidthFull();
|
||||
Translatable<Button> save = Translatable.createButton(e -> {
|
||||
|
@ -63,8 +66,8 @@ public class AdminTab extends BugTab<FlexLayout> {
|
|||
Card propertiesCard = new Card(title, save);
|
||||
propertiesCard.setHeader(Translatable.createText(Messages.PROPERTIES));
|
||||
propertiesCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
getContent().add(propertiesCard);
|
||||
getContent().expand(propertiesCard);
|
||||
layout.add(propertiesCard);
|
||||
layout.expand(propertiesCard);
|
||||
|
||||
Translatable<Button> unmergeButton = Translatable.createButton(e -> new Popup().setTitle(Messages.UNMERGE_BUG_CONFIRM).addYesNoButtons(p -> {
|
||||
getDataService().unmergeBug(bug);
|
||||
|
@ -78,8 +81,10 @@ public class AdminTab extends BugTab<FlexLayout> {
|
|||
deleteButton.setWidthFull();
|
||||
Card dangerCard = new Card(unmergeButton, deleteButton);
|
||||
dangerCard.setHeader(Translatable.createText(Messages.DANGER_ZONE));
|
||||
dangerCard.setHeaderColor("var(----lumo-error-text-color)", "var(--lumo-error-color)");
|
||||
dangerCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
getContent().add(dangerCard);
|
||||
getContent().expand(dangerCard);
|
||||
layout.add(dangerCard);
|
||||
layout.expand(dangerCard);
|
||||
getContent().add(layout);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,73 +16,17 @@
|
|||
|
||||
package com.faendir.acra.ui.view.bug.tabs;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.Bug;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.base.ActiveChildAware;
|
||||
import com.faendir.acra.ui.base.HasRoute;
|
||||
import com.faendir.acra.ui.base.HasSecureIntParameter;
|
||||
import com.faendir.acra.ui.base.Path;
|
||||
import com.vaadin.flow.component.AttachEvent;
|
||||
import com.faendir.acra.ui.base.TabView;
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.router.BeforeEvent;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 19.11.18
|
||||
*/
|
||||
public abstract class BugTab <T extends Component> extends Composite<T> implements HasSecureIntParameter, HasRoute {
|
||||
private final DataService dataService;
|
||||
private Bug bug;
|
||||
|
||||
public abstract class BugTab <T extends Component> extends TabView.Tab<T, Bug> {
|
||||
public BugTab(DataService dataService) {
|
||||
this.dataService = dataService;
|
||||
}
|
||||
|
||||
public DataService getDataService() {
|
||||
return dataService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameterSecure(BeforeEvent event, Integer parameter) {
|
||||
Optional<Bug> bug = dataService.findBug(parameter);
|
||||
if (bug.isPresent()) {
|
||||
this.bug = bug.get();
|
||||
} else {
|
||||
event.rerouteToError(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void init(Bug bug);
|
||||
|
||||
@Override
|
||||
protected void onAttach(AttachEvent attachEvent) {
|
||||
super.onAttach(attachEvent);
|
||||
init(this.bug);
|
||||
Optional<Component> parent = getParent();
|
||||
while (parent.isPresent()) {
|
||||
if (parent.get() instanceof ActiveChildAware) {
|
||||
//noinspection unchecked
|
||||
((ActiveChildAware<BugTab<?>, Bug>) parent.get()).setActiveChild(this, bug);
|
||||
break;
|
||||
}
|
||||
parent = parent.get().getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Path.Element<?> getPathElement() {
|
||||
//noinspection unchecked
|
||||
return new Path.ParametrizedTextElement<>((Class<? extends BugTab<?>>) getClass(), bug.getId(), Messages.ONE_ARG, bug.getTitle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parent<?> getLogicalParent() {
|
||||
return new ParametrizedParent<>(com.faendir.acra.ui.view.app.tabs.BugTab.class, bug.getApp().getId());
|
||||
super(dataService, DataService::findBug, Bug::getId, Bug::getTitle, bug -> new ParametrizedParent<>(com.faendir.acra.ui.view.app.tabs.BugTab.class, bug.getApp().getId()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class ReportTab extends BugTab<Div> {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(Bug bug) {
|
||||
protected void init(Bug bug) {
|
||||
getContent().removeAll();
|
||||
getContent().add(new ReportList(bug.getApp(), getDataService().getReportProvider(bug), avatarService, getDataService()::delete));
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class StacktraceTab extends BugTab<Div> implements HasSize {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(Bug bug) {
|
||||
protected void init(Bug bug) {
|
||||
getContent().removeAll();
|
||||
for (Stacktrace stacktrace : getDataService().getStacktraces(bug)) {
|
||||
Optional<ProguardMapping> mapping = getDataService().findMapping(bug.getApp(), stacktrace.getVersion().getCode());
|
||||
|
|
|
@ -43,7 +43,7 @@ public class StatisticsTab extends BugTab<Div> {
|
|||
}
|
||||
|
||||
@Override
|
||||
void init(Bug bug) {
|
||||
protected void init(Bug bug) {
|
||||
getContent().removeAll();
|
||||
getContent().add(new Statistics(bug.getApp(), QReport.report.stacktrace.bug.eq(bug), getDataService()));
|
||||
}
|
||||
|
|
|
@ -135,9 +135,7 @@ public class ReportView extends Composite<Div> implements HasSecureStringParamet
|
|||
map.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(Map.Entry::getKey))
|
||||
.forEach(entry -> {
|
||||
layout.add(new Label(entry.getKey()).secondary(), getComponentForContent(entry.getValue()));
|
||||
});
|
||||
.forEach(entry -> layout.add(new Label(entry.getKey()).secondary(), getComponentForContent(entry.getValue())));
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue