start adding ui for new version structure
This commit is contained in:
parent
981a6659d3
commit
9c3ac2c6f2
8 changed files with 91 additions and 47 deletions
|
@ -31,6 +31,7 @@ import javax.persistence.FetchType;
|
|||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
/**
|
||||
|
@ -47,6 +48,7 @@ public class Bug {
|
|||
private App app;
|
||||
@Nullable
|
||||
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "solved_version")
|
||||
private Version solvedVersion;
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.annotations.OnDelete;
|
|||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.springframework.data.annotation.PersistenceConstructor;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
@ -33,7 +34,7 @@ import javax.persistence.ManyToOne;
|
|||
* @since 26.07.18
|
||||
*/
|
||||
@Entity
|
||||
public class Version {
|
||||
public class Version implements Comparable<Version>{
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private int id;
|
||||
|
@ -50,11 +51,17 @@ public class Version {
|
|||
Version() {
|
||||
}
|
||||
|
||||
public Version(int code, String name) {
|
||||
public Version(App app, int code, String name) {
|
||||
this.app = app;
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Version(App app, int code, String name, String mappings) {
|
||||
this(app, code, name);
|
||||
this.mappings = mappings;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
@ -67,4 +74,9 @@ public class Version {
|
|||
public String getMappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull Version o) {
|
||||
return Integer.compare(code, o.code);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ import static com.faendir.acra.model.QAttachment.attachment;
|
|||
import static com.faendir.acra.model.QBug.bug;
|
||||
import static com.faendir.acra.model.QReport.report;
|
||||
import static com.faendir.acra.model.QStacktrace.stacktrace1;
|
||||
import static com.faendir.acra.model.QVersion.version;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
|
@ -174,11 +175,11 @@ public class DataService implements Serializable {
|
|||
return new JPAQuery<>(entityManager).from(report).where(where).select(report.id).fetch();
|
||||
}
|
||||
|
||||
/*@NonNull
|
||||
@NonNull
|
||||
@PreAuthorize("T(com.faendir.acra.security.SecurityUtils).hasPermission(#app, T(com.faendir.acra.model.Permission$Level).VIEW)")
|
||||
public QueryDslDataProvider<ProguardMapping> getMappingProvider(@NonNull App app) {
|
||||
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(proguardMapping).where(proguardMapping.app.eq(app)).select(proguardMapping));
|
||||
}*/
|
||||
public QueryDslDataProvider<Version> getVersionProvider(@NonNull App app) {
|
||||
return new QueryDslDataProvider<>(new JPAQuery<>(entityManager).from(version).where(version.app.eq(app)).select(version));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public <T> T store(T entity) {
|
||||
|
@ -309,6 +310,12 @@ public class DataService implements Serializable {
|
|||
.fetchFirst());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@PreAuthorize("T(com.faendir.acra.security.SecurityUtils).hasPermission(#app, T(com.faendir.acra.model.Permission$Level).VIEW)")
|
||||
public List<Version> findAllVersions(@NonNull App app) {
|
||||
return new JPAQuery<>(entityManager).from(version).where(version.app.eq(app)).select(version).fetch();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@PreAuthorize("T(com.faendir.acra.security.SecurityUtils).hasPermission(#app, T(com.faendir.acra.model.Permission$Level).EDIT)")
|
||||
public void changeConfiguration(@NonNull App app, @NonNull App.Configuration configuration) {
|
||||
|
@ -342,7 +349,7 @@ public class DataService implements Serializable {
|
|||
if (app != null) {
|
||||
JSONObject jsonObject = new JSONObject(content);
|
||||
String trace = jsonObject.optString(ReportField.STACK_TRACE.name());
|
||||
Version version = getVersion(jsonObject);
|
||||
Version version = getVersion(app, jsonObject);
|
||||
Stacktrace stacktrace = findStacktrace(app, trace, version.getCode()).orElseGet(() -> {
|
||||
synchronized (stacktraceLock) {
|
||||
return findStacktrace(app, trace, version.getCode()).orElseGet(() -> store(new Stacktrace(findBug(app, trace).orElseGet(() -> new Bug(app, trace)), trace, version)));
|
||||
|
@ -363,7 +370,7 @@ public class DataService implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private Version getVersion(JSONObject jsonObject) {
|
||||
private Version getVersion(App app, JSONObject jsonObject) {
|
||||
JSONObject buildConfig = jsonObject.optJSONObject(ReportField.BUILD_CONFIG.name());
|
||||
Integer versionCode = null;
|
||||
String versionName = null;
|
||||
|
@ -383,7 +390,7 @@ public class DataService implements Serializable {
|
|||
if (versionName == null) {
|
||||
versionName = jsonObject.optString(ReportField.APP_VERSION_NAME.name(), "N/A");
|
||||
}
|
||||
return new Version(versionCode, versionName);
|
||||
return new Version(app, versionCode, versionName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -420,11 +427,11 @@ public class DataService implements Serializable {
|
|||
return new JPAQuery<>(entityManager).from(stacktrace1).where(stacktrace1.bug.eq(bug)).select(stacktrace1).fetch();
|
||||
}
|
||||
|
||||
/*@NonNull
|
||||
@NonNull
|
||||
@PreAuthorize("T(com.faendir.acra.security.SecurityUtils).hasPermission(#app, T(com.faendir.acra.model.Permission$Level).VIEW)")
|
||||
public Optional<Integer> getMaximumMappingVersion(@NonNull App app) {
|
||||
return Optional.ofNullable(new JPAQuery<>(entityManager).from(proguardMapping).where(proguardMapping.app.eq(app)).select(proguardMapping.versionCode.max()).fetchOne());
|
||||
}*/
|
||||
public Optional<Integer> getMaxVersion(@NonNull App app) {
|
||||
return Optional.ofNullable(new JPAQuery<>(entityManager).from(version).where(version.app.eq(app)).select(version.code.max()).fetchOne());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@PreAuthorize("hasRole(T(com.faendir.acra.model.User$Role).ADMIN)")
|
||||
|
|
|
@ -76,7 +76,7 @@ public class MailService {
|
|||
}
|
||||
|
||||
private void check(MailSettings.SendMode sendMode) {
|
||||
List<MailSettings> settings = new JPAQuery<>(entityManager).select(mailSettings).where(mailSettings.sendMode.eq(sendMode)).fetch();
|
||||
List<MailSettings> settings = new JPAQuery<>(entityManager).select(mailSettings).from(mailSettings).where(mailSettings.sendMode.eq(sendMode)).fetch();
|
||||
Map<App, List<MailSettings>> appMap = settings.stream().collect(Collectors.groupingBy(MailSettings::getApp));
|
||||
for (Map.Entry<App, List<MailSettings>> appEntry : appMap.entrySet()) {
|
||||
List<Report> reports = new JPAQuery<>(entityManager).select(report).where(report.date.after(ZonedDateTime.now().minus(1, sendMode.getUnit())).and(report.stacktrace.bug.app.eq(appEntry.getKey()))).fetch();
|
||||
|
|
|
@ -18,9 +18,14 @@ package com.faendir.acra.ui.view.app.tabs;
|
|||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.QReport;
|
||||
import com.faendir.acra.model.QVersion;
|
||||
import com.faendir.acra.model.Version;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.base.ConfigurationLabel;
|
||||
import com.faendir.acra.ui.base.MyGrid;
|
||||
import com.faendir.acra.ui.base.popup.Popup;
|
||||
import com.faendir.acra.ui.component.Card;
|
||||
import com.faendir.acra.ui.component.DownloadButton;
|
||||
|
@ -36,14 +41,22 @@ 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;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.server.StreamResource;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import com.vaadin.flow.spring.annotation.UIScope;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -70,41 +83,40 @@ public class AdminTab extends AppTab<Div> {
|
|||
FlexLayout layout = new FlexLayout();
|
||||
layout.setFlexWrap(FlexLayout.FlexWrap.WRAP);
|
||||
layout.setWidthFull();
|
||||
//TODO
|
||||
/*
|
||||
MyGrid<ProguardMapping> mappingGrid = new MyGrid<>(getDataService().getMappingProvider(app));
|
||||
mappingGrid.setHeightToRows();
|
||||
mappingGrid.addColumn(ProguardMapping::getVersionCode, QProguardMapping.proguardMapping.versionCode, Messages.VERSION).setFlexGrow(1);
|
||||
mappingGrid.setHeight("");
|
||||
Card mappingCard = new Card(mappingGrid);
|
||||
mappingCard.setHeader(Translatable.createText(Messages.DE_OBFUSCATION));
|
||||
mappingCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
MyGrid<Version> versionGrid = new MyGrid<>(getDataService().getVersionProvider(app));
|
||||
versionGrid.setHeightToRows();
|
||||
versionGrid.addColumn(Version::getCode, QVersion.version.code, Messages.VERSION_CODE).setFlexGrow(1);
|
||||
versionGrid.addColumn(Version::getName, QVersion.version.name, Messages.VERSION).setFlexGrow(1);
|
||||
versionGrid.setHeight("");
|
||||
Card versionCard = new Card(versionGrid);
|
||||
versionCard.setHeader(Translatable.createText(Messages.VERSIONS));
|
||||
versionCard.setWidth(500, HasSize.Unit.PIXEL);
|
||||
if (SecurityUtils.hasPermission(app, Permission.Level.EDIT)) {
|
||||
mappingGrid.addColumn(new ComponentRenderer<>(mapping -> new Button(new Icon(VaadinIcon.TRASH), e -> new Popup().addComponent(Translatable.createText(Messages.DELETE_MAPPING_CONFIRM, mapping.getVersionCode())).addYesNoButtons(p -> {
|
||||
getDataService().delete(mapping);
|
||||
mappingGrid.getDataProvider().refreshAll();
|
||||
versionGrid.addColumn(new ComponentRenderer<>(v -> new Button(new Icon(VaadinIcon.TRASH), e -> new Popup().addComponent(Translatable.createText(Messages.DELETE_MAPPING_CONFIRM, v.getCode())).addYesNoButtons(p -> {
|
||||
getDataService().delete(v);
|
||||
versionGrid.getDataProvider().refreshAll();
|
||||
}, true).show())));
|
||||
mappingGrid.appendFooterRow().getCell(mappingGrid.getColumns().get(0)).setComponent(Translatable.createButton(e -> {
|
||||
NumberInput version = new NumberInput(getDataService().getMaximumMappingVersion(app).map(i -> i + 1).orElse(1));//, Messages.VERSION_CODE);
|
||||
versionGrid.appendFooterRow().getCell(versionGrid.getColumns().get(0)).setComponent(Translatable.createButton(e -> {
|
||||
TextField name = new TextField();
|
||||
NumberInput version = new NumberInput(getDataService().getMaxVersion(app).map(i -> i + 1).orElse(1));//, Messages.VERSION_CODE);
|
||||
MemoryBuffer buffer = new MemoryBuffer();
|
||||
Upload upload = new Upload(buffer);
|
||||
new Popup()
|
||||
.setTitle(Messages.NEW_MAPPING)
|
||||
new Popup().setTitle(Messages.NEW_MAPPING)
|
||||
.addComponent(name)
|
||||
.addComponent(version)
|
||||
.addComponent(upload)
|
||||
.addCreateButton(popup -> {
|
||||
try {
|
||||
getDataService().store(new ProguardMapping(app, version.getValue().intValue(), StreamUtils.copyToString(buffer.getInputStream(), Charset.defaultCharset())));
|
||||
getDataService().store(new Version(app, version.getValue().intValue(), name.getValue(), StreamUtils.copyToString(buffer.getInputStream(), Charset.defaultCharset())));
|
||||
} catch (Exception ex) {
|
||||
//TODO
|
||||
}
|
||||
mappingGrid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show();
|
||||
}, Messages.NEW_FILE));
|
||||
versionGrid.getDataProvider().refreshAll();
|
||||
}, true).show();
|
||||
}, Messages.NEW_VERSION));
|
||||
}
|
||||
layout.add(mappingCard);
|
||||
layout.expand(mappingCard);*/
|
||||
layout.add(versionCard);
|
||||
layout.expand(versionCard);
|
||||
|
||||
Translatable<ComboBox<String>> mailBox = Translatable.createComboBox(getDataService().getFromReports(app, null, QReport.report.userEmail), Messages.BY_MAIL);
|
||||
mailBox.setWidthFull();
|
||||
|
|
|
@ -18,9 +18,12 @@ package com.faendir.acra.ui.view.app.tabs;
|
|||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
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.Version;
|
||||
import com.faendir.acra.model.view.VBug;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.BugMerger;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.ui.base.MyGrid;
|
||||
|
@ -31,12 +34,14 @@ import com.faendir.acra.ui.view.bug.tabs.ReportTab;
|
|||
import com.faendir.acra.util.TimeSpanRenderer;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.checkbox.Checkbox;
|
||||
import com.vaadin.flow.component.combobox.ComboBox;
|
||||
import com.vaadin.flow.component.grid.FooterRow;
|
||||
import com.vaadin.flow.component.grid.Grid;
|
||||
import com.vaadin.flow.component.notification.Notification;
|
||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
|
||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import com.vaadin.flow.spring.annotation.UIScope;
|
||||
|
@ -92,17 +97,19 @@ public class BugTab extends AppTab<VerticalLayout> {
|
|||
bugs.addColumn(VBug::getHighestVersionCode, QReport.report.stacktrace.version.code.max(), Messages.LATEST_VERSION);
|
||||
bugs.addColumn(VBug::getUserCount, QReport.report.installationId.countDistinct(), Messages.AFFECTED_USERS);
|
||||
bugs.addColumn(bug -> bug.getBug().getTitle(), QBug.bug.title, Messages.TITLE).setFlexGrow(1);
|
||||
//TODO
|
||||
/*Grid.Column<VBug> solvedColumn = bugs.addColumn(new ComponentRenderer<>(bug -> {
|
||||
Checkbox checkbox = new Checkbox(bug.getBug().isSolved());
|
||||
checkbox.setEnabled(SecurityUtils.hasPermission(app, Permission.Level.EDIT));
|
||||
checkbox.addValueChangeListener(e -> getDataService().setBugSolved(bug.getBug(), e.getValue()));
|
||||
return checkbox;
|
||||
}), QBug.bug.solved, Messages.SOLVED);*/
|
||||
List<Version> versions = getDataService().findAllVersions(app);
|
||||
Grid.Column<VBug> solvedColumn = bugs.addColumn(new ComponentRenderer<>((VBug bug) -> {
|
||||
ComboBox<Version> comboBox = new ComboBox<>("", versions);
|
||||
comboBox.setItemLabelGenerator(Version::getName);
|
||||
comboBox.setValue(bug.getBug().getSolvedVersion());
|
||||
comboBox.setEnabled(SecurityUtils.hasPermission(app, Permission.Level.EDIT));
|
||||
comboBox.addValueChangeListener(e -> getDataService().setBugSolved(bug.getBug(), e.getValue()));
|
||||
return comboBox;
|
||||
}), QBug.bug.solvedVersion, Messages.SOLVED);
|
||||
bugs.addOnClickNavigation(ReportTab.class, bug -> bug.getBug().getId());
|
||||
FooterRow footerRow = bugs.appendFooterRow();
|
||||
footerRow.getCell(countColumn).setComponent(merge);
|
||||
//footerRow.getCell(solvedColumn).setComponent(hideSolved);
|
||||
footerRow.getCell(solvedColumn).setComponent(hideSolved);
|
||||
getContent().removeAll();
|
||||
getContent().add(bugs);
|
||||
getContent().setFlexGrow(1, bugs);
|
||||
|
|
|
@ -131,4 +131,6 @@ login=Login
|
|||
oneArg=%s
|
||||
api=API-Zugriff
|
||||
about=Info
|
||||
overview=Übersicht
|
||||
overview=Übersicht
|
||||
versions=Versionen
|
||||
newVersion=Neue Version
|
|
@ -131,4 +131,6 @@ login=Login
|
|||
oneArg=%s
|
||||
api=API Access
|
||||
about=About
|
||||
overview=Overview
|
||||
overview=Overview
|
||||
versions=Versions
|
||||
newVersion=New Version
|
Loading…
Reference in a new issue