From eb3fc7b13bfe31b5bd82a91d267c279bd6b3972a Mon Sep 17 00:00:00 2001 From: Onur Idrisoglu Date: Thu, 21 Dec 2017 14:01:06 +0200 Subject: [PATCH 1/3] Multiple Upload Functionality --- .../vaadin/bugrap/ui/ReportDetailView.java | 117 +++++++++--------- .../org/vaadin/bugrap/ui/ReportsModel.java | 31 ++--- .../org/vaadin/bugrap/ui/UploadTracker.java | 91 ++++++++++++++ .../vaadin/bugrap/ui/UploadTrackerModel.java | 14 +++ .../bugrap/ui/beans/FileUploadEvent.java | 51 ++++++++ .../ui/generated/UploadTrackerBase.java | 30 +++++ .../bugrap/util/IUploadedFileListener.java | 10 ++ .../ui/generated/ReportDetailViewBase.html | 2 +- .../ui/generated/UploadTrackerBase.html | 17 +++ .../webapp/VAADIN/themes/mytheme/mytheme.scss | 24 ++++ .../webapp/VAADIN/themes/mytheme/styles.css | 28 ++++- 11 files changed, 341 insertions(+), 74 deletions(-) create mode 100644 bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java create mode 100644 bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java create mode 100644 bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java create mode 100644 bugrap/src/main/java/org/vaadin/bugrap/ui/generated/UploadTrackerBase.java create mode 100644 bugrap/src/main/java/org/vaadin/bugrap/util/IUploadedFileListener.java create mode 100644 bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/UploadTrackerBase.html diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java index ba8c0ec..7b975cd 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java @@ -1,39 +1,33 @@ package org.vaadin.bugrap.ui; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.util.List; import org.vaadin.bugrap.domain.entities.Comment; import org.vaadin.bugrap.domain.entities.Report; +import org.vaadin.bugrap.ui.beans.FileUploadEvent; import org.vaadin.bugrap.ui.generated.ReportDetailViewBase; +import org.vaadin.bugrap.util.IUploadedFileListener; import com.vaadin.data.Binder; -import com.vaadin.server.FileDownloader; -import com.vaadin.server.FileResource; +import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Link; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; -import com.vaadin.ui.ProgressBar; -import com.vaadin.ui.Upload.ProgressListener; -import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.FinishedEvent; +import com.vaadin.ui.Upload.FinishedListener; import com.vaadin.ui.Upload.StartedEvent; import com.vaadin.ui.Upload.StartedListener; -import com.vaadin.ui.Upload.SucceededEvent; -import com.vaadin.ui.Upload.SucceededListener; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; public class ReportDetailView extends ReportDetailViewBase - implements Receiver, SucceededListener, StartedListener, ProgressListener { + implements StartedListener, Component.Listener, IUploadedFileListener, FinishedListener { private ReportsModel model; private Binder binder = new Binder(); - private ProgressBar uploadInProgress; + private int numOfOngoingUploads = 0; public ReportDetailView(ReportsModel reportModel) { model = reportModel; @@ -55,11 +49,10 @@ private void initializeUIComponents() { btnRevertReport.addClickListener(evt -> revertChanges()); btnDone.addClickListener(evt -> saveComment()); btnCancel.addClickListener(evt -> closeWindow()); - btnUpload.setReceiver(this); btnUpload.addStartedListener(this); - btnUpload.addSucceededListener(this); - btnUpload.addProgressListener(this); - txtComment.addValueChangeListener(evt -> commentsUpdated()); + btnUpload.addFinishedListener(this); + txtComment.addValueChangeListener(evt -> setDoneButtonEnablement()); + pnlAttachments.getContent().addListener(this); } private void init() { @@ -73,7 +66,6 @@ private void init() { private void cleanAttachments() { ((HorizontalLayout) pnlAttachments.getContent()).removeAllComponents(); - pnlAttachments.setVisible(false); } private void initializeComboContents() { @@ -95,8 +87,13 @@ private void fillComments() { btnDone.setEnabled(false); } - private void commentsUpdated() { - btnDone.setEnabled(true); + private void setDoneButtonEnablement() { + boolean isEnabled = false; + if (numOfOngoingUploads > 0) + isEnabled = false; + else + isEnabled = !txtComment.isEmpty() || model.hasFilesToSave(); + btnDone.setEnabled(isEnabled); } private void saveReport() { @@ -119,55 +116,61 @@ private void saveComment() { @Override public void uploadStarted(StartedEvent event) { - pnlAttachments.setVisible(true); + initiateUploadTracker(event); + addNewUpload(); + numOfOngoingUploads++; + } + + private void addNewUpload() { + HorizontalLayout layout = (HorizontalLayout) btnUpload.getParent(); + Upload newUpload = new Upload(); + newUpload.setButtonCaption("Attachments..."); + newUpload.addStartedListener(this); + newUpload.addFinishedListener(this); + layout.addComponent(newUpload, layout.getComponentIndex(btnUpload)); + btnUpload.setStyleName("removed-upload", true); + btnUpload = newUpload; + } + + private void initiateUploadTracker(StartedEvent event) { + UploadTracker uploadTracker = new UploadTracker((Upload) event.getSource(), event.getFilename()); + uploadTracker.setUploadedFileListener(this); HorizontalLayout layout = (HorizontalLayout) pnlAttachments.getContent(); - ProgressBar progress = new ProgressBar(); - progress.setCaption(event.getFilename()); - uploadInProgress = progress; - layout.addComponent(progress); - btnDone.setEnabled(false);//disable done button until upload completes + layout.addComponent(uploadTracker); + } + + private void closeWindow() { + Window window = (Window) getParent(); + window.close(); } @Override - public void uploadSucceeded(SucceededEvent event) { - HorizontalLayout layout = (HorizontalLayout) pnlAttachments.getContent(); - layout.removeComponent(uploadInProgress); - uploadInProgress = null; - FileResource file = new FileResource(new File(ReportsModel.FILEUPLOAD_PATH + event.getFilename())); - try { - model.attachFile(event.getFilename(), event.getMIMEType(), file.getStream()); - } catch (IOException e) { - Notification.show("Error occurred while uploading the file", e.getMessage(), Type.ERROR_MESSAGE); - } - FileDownloader downloader = new FileDownloader(file); - Link link = new Link(); - link.setCaption(event.getFilename()); - link.setStyleName("tiny"); - downloader.extend(link); - layout.addComponent(link); - commentsUpdated(); + public void componentEvent(Event event) { + HorizontalLayout layout = (HorizontalLayout) event.getSource(); + pnlAttachments.setVisible(layout.getComponentCount() > 0); } @Override - public OutputStream receiveUpload(String filename, String mimeType) { - FileOutputStream fos = null; + public void uploadedFileReceived(FileUploadEvent event) { try { - fos = new FileOutputStream(ReportsModel.FILEUPLOAD_PATH + filename); - } catch (FileNotFoundException e) { - Notification.show("Error occurred while uploading the file", e.getMessage(), Type.ERROR_MESSAGE); - } finally { - return fos; + model.attachFile(event.getSource(), event.getFilename(), event.getFilename(), event.getDownloadStream()); + setDoneButtonEnablement(); + } catch (IOException e) { + Notification.show("Error uploading file : " + event.getFilename(), + "There was an error while uploading the file :" + e.getMessage(), + com.vaadin.ui.Notification.Type.ERROR_MESSAGE); } } @Override - public void updateProgress(long readBytes, long contentLength) { - if (uploadInProgress != null) - uploadInProgress.setValue(((float) readBytes) / contentLength); + public void uploadFinished(FinishedEvent event) { + numOfOngoingUploads--; + setDoneButtonEnablement(); } - private void closeWindow() { - Window window = (Window) getParent(); - window.close(); + @Override + public void uploadedFileDeleted(Object source) { + model.removeAttachedFile(source); + setDoneButtonEnablement(); } } diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java index 20ccd34..eea6f9a 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java @@ -6,8 +6,10 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.vaadin.bugrap.BaseModel; @@ -20,12 +22,15 @@ import org.vaadin.bugrap.domain.entities.Report.Status; import org.vaadin.bugrap.domain.entities.Report.Type; import org.vaadin.bugrap.domain.entities.Reporter; +import org.vaadin.bugrap.ui.beans.FileUploadEvent; import org.vaadin.bugrap.ui.beans.ReportDistribution; +import org.vaadin.bugrap.util.IUploadedFileListener; import org.vaadin.bugrap.util.ReportUtil; import com.vaadin.data.ValidationException; import com.vaadin.navigator.Navigator; import com.vaadin.server.DownloadStream; +import com.vaadin.ui.Notification; public class ReportsModel extends BaseModel { @@ -38,10 +43,8 @@ public class ReportsModel extends BaseModel { public static final int VERSIONID_ALL = 0; - public static final String FILEUPLOAD_PATH = "/Users/onuridrisoglu/Downloads/temp/"; - private List selectedReports = new ArrayList(); - private List uploadedFilesToSave = new ArrayList(); + private Map uploadedFilesToSave = new HashMap(); protected Report reportForEdit; private int assigneeFilterMode = ASSIGNEE_ALL; @@ -70,14 +73,6 @@ else if (selectedReports.size() == 1) return SELECTIONMODE_MULTI; } - public List getUploadedFilesToSave() { - return uploadedFilesToSave; - } - - public void setUploadedFilesToSave(List uploadedFilesToSave) { - this.uploadedFilesToSave = uploadedFilesToSave; - } - public List findProjects() { List projects = new ArrayList(); projects.addAll(getRepository().findProjects()); @@ -203,17 +198,24 @@ public Comment createComment(String filename, String mimeType, DownloadStream st return comment; } - public void attachFile(String filename, String mimeType, DownloadStream stream) throws IOException { + public void attachFile(Object source, String filename, String mimeType, DownloadStream stream) throws IOException { Comment attachmentComment = createComment(filename, mimeType, stream); - uploadedFilesToSave.add(attachmentComment); + uploadedFilesToSave.put(source, attachmentComment); + } + public void removeAttachedFile(Object source) { + uploadedFilesToSave.remove(source); } public void saveAttachments() { - for (Comment attachment : uploadedFilesToSave) { + for (Comment attachment : uploadedFilesToSave.values()) { getRepository().save(attachment); } uploadedFilesToSave.clear(); } + + public boolean hasFilesToSave() { + return uploadedFilesToSave.size() > 0; + } public ReportDistribution getReportDistribution(ProjectVersion version) { ReportDistribution distribution = new ReportDistribution(); @@ -247,4 +249,5 @@ public void changeStatusFilters(boolean isChecked, Status... status) { else statusFilters.removeAll(Arrays.asList(status)); } + } diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java new file mode 100644 index 0000000..b46a196 --- /dev/null +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java @@ -0,0 +1,91 @@ +package org.vaadin.bugrap.ui; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.OutputStream; + +import org.vaadin.bugrap.ui.beans.FileUploadEvent; +import org.vaadin.bugrap.ui.generated.UploadTrackerBase; +import org.vaadin.bugrap.util.IUploadedFileListener; + +import com.vaadin.server.FileDownloader; +import com.vaadin.server.FileResource; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.ProgressListener; +import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload.SucceededEvent; +import com.vaadin.ui.Upload.SucceededListener; + +public class UploadTracker extends UploadTrackerBase implements Receiver, ProgressListener, SucceededListener { + + private Upload btnUpload; + private IUploadedFileListener uploadedFileListener; + private UploadTrackerModel model = new UploadTrackerModel(); + + public UploadTracker(Upload upload, String filename) { + btnUpload = upload; + btnUpload.setReceiver(this); + btnUpload.addProgressListener(this); + btnUpload.addSucceededListener(this); + uploadProgress.setIndeterminate(false); + lnkFilename.setCaption(filename); + btnCancel.addClickListener(evt -> cancel()); + arrangeComponents(); + } + + private void arrangeComponents() { + uploadProgress.setVisible(!model.isUploadCompleted()); + if (model.isUploadCompleted()) { + setStyleName("completed-upload", true); + btnUpload.setVisible(false); + } + } + + private void cancel() { + if (!model.isUploadCompleted()) { + btnUpload.interruptUpload(); + } + uploadedFileListener.uploadedFileDeleted(btnUpload); + HorizontalLayout layout = (HorizontalLayout)getParent(); + layout.removeComponent(this); + } + + @Override + public void uploadSucceeded(SucceededEvent event) { + FileResource file = new FileResource(new File(UploadTrackerModel.FILEUPLOAD_PATH + event.getFilename())); + FileDownloader downloader = new FileDownloader(file); + downloader.extend(lnkFilename); + model.setUploadCompleted(true); + arrangeComponents(); + uploadedFileListener.uploadedFileReceived(new FileUploadEvent(event.getSource(), event.getFilename(), event.getMIMEType(), file.getStream())); + } + + @Override + public void updateProgress(long readBytes, long contentLength) { + uploadProgress.setValue(((float)readBytes)/(float)contentLength); + } + + @Override + public OutputStream receiveUpload(String filename, String mimeType) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(UploadTrackerModel.FILEUPLOAD_PATH + filename); + } catch (FileNotFoundException e) { + Notification.show("Error occurred while uploading the file", e.getMessage(), Type.ERROR_MESSAGE); + } finally { + return fos; + } + } + + public IUploadedFileListener getUploadedFileListener() { + return uploadedFileListener; + } + + public void setUploadedFileListener(IUploadedFileListener uploadedFileListener) { + this.uploadedFileListener = uploadedFileListener; + } +} diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java new file mode 100644 index 0000000..316a469 --- /dev/null +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java @@ -0,0 +1,14 @@ +package org.vaadin.bugrap.ui; + +public class UploadTrackerModel { + public static final String FILEUPLOAD_PATH = "/Users/onuridrisoglu/Downloads/temp/"; + + private boolean isUploadCompleted = false; + + public boolean isUploadCompleted() { + return isUploadCompleted; + } + public void setUploadCompleted(boolean isUploadCompleted) { + this.isUploadCompleted = isUploadCompleted; + } +} diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java new file mode 100644 index 0000000..81f4dcc --- /dev/null +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java @@ -0,0 +1,51 @@ +package org.vaadin.bugrap.ui.beans; + +import com.vaadin.server.DownloadStream; +import com.vaadin.ui.Upload; + +public class FileUploadEvent { + + private String filename; + private String mimeType; + private DownloadStream downloadStream; + private Object source; + + public FileUploadEvent(Object source, String filename, String mimeType, DownloadStream downloadStream) { + this.filename = filename; + this.mimeType = mimeType; + this.downloadStream = downloadStream; + this.setSource(source); + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getMimeType() { + return mimeType; + } + + public void setMimeType(String mimeType) { + this.mimeType = mimeType; + } + + public DownloadStream getDownloadStream() { + return downloadStream; + } + + public void setDownloadStream(DownloadStream downloadStream) { + this.downloadStream = downloadStream; + } + + public Object getSource() { + return source; + } + + public void setSource(Object source) { + this.source = source; + } +} diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/generated/UploadTrackerBase.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/generated/UploadTrackerBase.java new file mode 100644 index 0000000..e14fff2 --- /dev/null +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/generated/UploadTrackerBase.java @@ -0,0 +1,30 @@ +package org.vaadin.bugrap.ui.generated; + +import com.vaadin.annotations.AutoGenerated; +import com.vaadin.annotations.DesignRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Link; +import com.vaadin.ui.ProgressBar; +import com.vaadin.ui.declarative.Design; + +/** + * !! DO NOT EDIT THIS FILE !! + * + * This class is generated by Vaadin Designer and will be overwritten. + * + * Please make a subclass with logic and additional interfaces as needed, + * e.g class LoginView extends LoginDesign implements View { } + */ +@DesignRoot +@AutoGenerated +@SuppressWarnings("serial") +public class UploadTrackerBase extends HorizontalLayout { + protected Link lnkFilename; + protected ProgressBar uploadProgress; + protected Button btnCancel; + + public UploadTrackerBase() { + Design.read(this); + } +} diff --git a/bugrap/src/main/java/org/vaadin/bugrap/util/IUploadedFileListener.java b/bugrap/src/main/java/org/vaadin/bugrap/util/IUploadedFileListener.java new file mode 100644 index 0000000..aa41ccc --- /dev/null +++ b/bugrap/src/main/java/org/vaadin/bugrap/util/IUploadedFileListener.java @@ -0,0 +1,10 @@ +package org.vaadin.bugrap.util; + +import org.vaadin.bugrap.ui.beans.FileUploadEvent; + +public interface IUploadedFileListener { + + public void uploadedFileReceived(FileUploadEvent event); + + public void uploadedFileDeleted(Object source); +} diff --git a/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/ReportDetailViewBase.html b/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/ReportDetailViewBase.html index 0639b60..4da7484 100644 --- a/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/ReportDetailViewBase.html +++ b/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/ReportDetailViewBase.html @@ -36,7 +36,7 @@ - + diff --git a/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/UploadTrackerBase.html b/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/UploadTrackerBase.html new file mode 100644 index 0000000..49e4c93 --- /dev/null +++ b/bugrap/src/main/resources/org/vaadin/bugrap/ui/generated/UploadTrackerBase.html @@ -0,0 +1,17 @@ + + + + + + + + + + + + + Button + + + + \ No newline at end of file diff --git a/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss index 963fcea..649e5e4 100644 --- a/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss +++ b/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss @@ -40,4 +40,28 @@ width: 10px; vertical-align: center; } + + div.v-slot-removed-upload{ + display: none; + } + + div.completed-upload div.v-button{ + display: none; + } + + div.completed-upload:hover div.v-button{ + display: inline-block; + } + + div.v-slot-completed-upload:hover{ + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + } + div.v-slot-completed-upload div{ + margin-bottom: 5px; + margin-left: 5px; + } } diff --git a/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css b/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css index 9a73de5..f3a39ec 100644 --- a/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css +++ b/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css @@ -14784,6 +14784,30 @@ div.v-layout.v-horizontal.v-widget { background-color: gray; height: 20px; width: 10px; - vertical-align: middle; - margin-left: 1px; + vertical-align: center; +} + +.mytheme div.v-slot-removed-upload { + display: none; +} + +.mytheme div.completed-upload div.v-button { + display: none; +} + +.mytheme div.completed-upload:hover div.v-button { + display: inline-block; +} + +.mytheme div.v-slot-completed-upload:hover { + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme div.v-slot-completed-upload div { + margin-bottom: 5px; + margin-left: 5px; } \ No newline at end of file From 901d13da76b66b5cb6419d250e87a6f8402c9bad Mon Sep 17 00:00:00 2001 From: Onur Idrisoglu Date: Thu, 21 Dec 2017 15:22:03 +0200 Subject: [PATCH 2/3] gitignore and pom --- bugrap/.gitignore | 1 + bugrap/pom.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/bugrap/.gitignore b/bugrap/.gitignore index 3415bc6..c6f0364 100644 --- a/bugrap/.gitignore +++ b/bugrap/.gitignore @@ -4,3 +4,4 @@ /.settings/ /**/.DS_Store /**/rebel.xml +/.vaadin-designer2/ diff --git a/bugrap/pom.xml b/bugrap/pom.xml index 4f63df3..ae2d8b5 100644 --- a/bugrap/pom.xml +++ b/bugrap/pom.xml @@ -105,8 +105,8 @@ update-widgetset compile + compile-theme From 7f1217e490c7100ac6d523e6c903b50b3a74078b Mon Sep 17 00:00:00 2001 From: Onur Idrisoglu Date: Fri, 22 Dec 2017 10:42:40 +0200 Subject: [PATCH 3/3] Attachment method changed from FileResource to StreamResource --- .gitignore | 1 + bugrap/.vaadin-designer2/designer-theme.css | 32 ++++++++++++++++ .../vaadin/bugrap/ui/ReportDetailView.java | 4 +- .../org/vaadin/bugrap/ui/ReportsModel.java | 35 +++++++++--------- .../org/vaadin/bugrap/ui/UploadTracker.java | 37 +++++++++++-------- .../vaadin/bugrap/ui/UploadTrackerModel.java | 1 - .../bugrap/ui/beans/FileUploadEvent.java | 31 ++++++++-------- .../webapp/VAADIN/themes/mytheme/mytheme.scss | 1 + .../webapp/VAADIN/themes/mytheme/styles.css | 1 + 9 files changed, 92 insertions(+), 51 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bb88d3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.DS_Store diff --git a/bugrap/.vaadin-designer2/designer-theme.css b/bugrap/.vaadin-designer2/designer-theme.css index 80bcfdf..fe650de 100644 --- a/bugrap/.vaadin-designer2/designer-theme.css +++ b/bugrap/.vaadin-designer2/designer-theme.css @@ -12500,4 +12500,36 @@ div.v-layout.v-horizontal.v-widget { display: inline-block; width: 19px; overflow: hidden; +} + +.mytheme div.bar { + background-color: gray; + height: 20px; + width: 10px; + vertical-align: center; +} + +.mytheme div.v-slot-removed-upload { + display: none; +} + +.mytheme div.completed-upload div.v-button { + display: none; +} + +.mytheme div.completed-upload:hover div.v-button { + display: inline-block; +} + +.mytheme div.v-slot-completed-upload:hover { + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme div.v-slot-completed-upload div { + margin-bottom: 5px; + margin-left: 5px; } \ No newline at end of file diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java index 7b975cd..f9bc4a8 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportDetailView.java @@ -91,7 +91,7 @@ private void setDoneButtonEnablement() { boolean isEnabled = false; if (numOfOngoingUploads > 0) isEnabled = false; - else + else isEnabled = !txtComment.isEmpty() || model.hasFilesToSave(); btnDone.setEnabled(isEnabled); } @@ -153,7 +153,7 @@ public void componentEvent(Event event) { @Override public void uploadedFileReceived(FileUploadEvent event) { try { - model.attachFile(event.getSource(), event.getFilename(), event.getFilename(), event.getDownloadStream()); + model.attachFile(event.getSource(), event.getFilename(), event.getFilename(), event.getStream()); setDoneButtonEnablement(); } catch (IOException e) { Notification.show("Error uploading file : " + event.getFilename(), diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java index eea6f9a..412dd0b 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/ReportsModel.java @@ -1,6 +1,7 @@ package org.vaadin.bugrap.ui; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -22,15 +23,11 @@ import org.vaadin.bugrap.domain.entities.Report.Status; import org.vaadin.bugrap.domain.entities.Report.Type; import org.vaadin.bugrap.domain.entities.Reporter; -import org.vaadin.bugrap.ui.beans.FileUploadEvent; import org.vaadin.bugrap.ui.beans.ReportDistribution; -import org.vaadin.bugrap.util.IUploadedFileListener; import org.vaadin.bugrap.util.ReportUtil; import com.vaadin.data.ValidationException; import com.vaadin.navigator.Navigator; -import com.vaadin.server.DownloadStream; -import com.vaadin.ui.Notification; public class ReportsModel extends BaseModel { @@ -40,7 +37,7 @@ public class ReportsModel extends BaseModel { public static final int ASSIGNEE_ME = 0; public static final int ASSIGNEE_ALL = 1; - + public static final int VERSIONID_ALL = 0; private List selectedReports = new ArrayList(); @@ -99,15 +96,15 @@ public Collection findReporters() { public List findProjectVersions() { return findProjectVersions(reportForEdit.getProject()); } - + public List findProjectVersionsWithAllOption(Project project) { List projectVersions = findProjectVersions(project); - + ProjectVersion allVersion = new ProjectVersion(); allVersion.setId(VERSIONID_ALL); allVersion.setVersion("All Versions"); allVersion.setProject(project); - + projectVersions.add(0, allVersion); return projectVersions; } @@ -126,7 +123,7 @@ public Collection findReports(Project project, ProjectVersion version) { query.projectVersion = version; } if (assigneeFilterMode == ASSIGNEE_ME) { - query.reportAssignee = getLoginUser(); + query.reportAssignee = getLoginUser(); } query.reportStatuses = statusFilters; return getRepository().findReports(query); @@ -187,10 +184,10 @@ public void saveComment(String commentTxt) { getRepository().save(comment); } - public Comment createComment(String filename, String mimeType, DownloadStream stream) throws IOException { + public Comment createComment(String filename, String mimeType, InputStream stream) throws IOException { Comment comment = new Comment(); comment.setReport(reportForEdit); - comment.setAttachment(stream.getStream().readAllBytes()); + comment.setAttachment(stream.readAllBytes()); comment.setAttachmentName(filename); comment.setAuthor(getLoginUser()); comment.setTimestamp(new Date()); @@ -198,10 +195,11 @@ public Comment createComment(String filename, String mimeType, DownloadStream st return comment; } - public void attachFile(Object source, String filename, String mimeType, DownloadStream stream) throws IOException { + public void attachFile(Object source, String filename, String mimeType, InputStream stream) throws IOException { Comment attachmentComment = createComment(filename, mimeType, stream); uploadedFilesToSave.put(source, attachmentComment); } + public void removeAttachedFile(Object source) { uploadedFilesToSave.remove(source); } @@ -212,7 +210,7 @@ public void saveAttachments() { } uploadedFilesToSave.clear(); } - + public boolean hasFilesToSave() { return uploadedFilesToSave.size() > 0; } @@ -220,9 +218,12 @@ public boolean hasFilesToSave() { public ReportDistribution getReportDistribution(ProjectVersion version) { ReportDistribution distribution = new ReportDistribution(); boolean isAllVersions = version.getId() == VERSIONID_ALL; - distribution.setClosedReports(isAllVersions ? getRepository().countClosedReports(version.getProject()) : getRepository().countClosedReports(version)); - distribution.setAssignedReports(isAllVersions ? getRepository().countOpenedReports(version.getProject()) : getRepository().countOpenedReports(version)); - distribution.setUnassignedReports(isAllVersions ? getRepository().countUnassignedReports(version.getProject()) : getRepository().countUnassignedReports(version)); + distribution.setClosedReports(isAllVersions ? getRepository().countClosedReports(version.getProject()) + : getRepository().countClosedReports(version)); + distribution.setAssignedReports(isAllVersions ? getRepository().countOpenedReports(version.getProject()) + : getRepository().countOpenedReports(version)); + distribution.setUnassignedReports(isAllVersions ? getRepository().countUnassignedReports(version.getProject()) + : getRepository().countUnassignedReports(version)); return distribution; } @@ -249,5 +250,5 @@ public void changeStatusFilters(boolean isChecked, Status... status) { else statusFilters.removeAll(Arrays.asList(status)); } - + } diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java index b46a196..9f2b210 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTracker.java @@ -1,8 +1,11 @@ package org.vaadin.bugrap.ui; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.InputStream; import java.io.OutputStream; import org.vaadin.bugrap.ui.beans.FileUploadEvent; @@ -11,6 +14,9 @@ import com.vaadin.server.FileDownloader; import com.vaadin.server.FileResource; +import com.vaadin.server.Resource; +import com.vaadin.server.StreamResource; +import com.vaadin.server.StreamResource.StreamSource; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; @@ -21,11 +27,12 @@ import com.vaadin.ui.Upload.SucceededListener; public class UploadTracker extends UploadTrackerBase implements Receiver, ProgressListener, SucceededListener { - + private Upload btnUpload; private IUploadedFileListener uploadedFileListener; private UploadTrackerModel model = new UploadTrackerModel(); - + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public UploadTracker(Upload upload, String filename) { btnUpload = upload; btnUpload.setReceiver(this); @@ -50,35 +57,35 @@ private void cancel() { btnUpload.interruptUpload(); } uploadedFileListener.uploadedFileDeleted(btnUpload); - HorizontalLayout layout = (HorizontalLayout)getParent(); + HorizontalLayout layout = (HorizontalLayout) getParent(); layout.removeComponent(this); } @Override public void uploadSucceeded(SucceededEvent event) { - FileResource file = new FileResource(new File(UploadTrackerModel.FILEUPLOAD_PATH + event.getFilename())); - FileDownloader downloader = new FileDownloader(file); + InputStream is = new ByteArrayInputStream(baos.toByteArray()); + StreamResource resource = new StreamResource(new StreamSource() { + @Override + public InputStream getStream() { + return is; + } + }, event.getFilename()); + FileDownloader downloader = new FileDownloader(resource); downloader.extend(lnkFilename); model.setUploadCompleted(true); arrangeComponents(); - uploadedFileListener.uploadedFileReceived(new FileUploadEvent(event.getSource(), event.getFilename(), event.getMIMEType(), file.getStream())); + uploadedFileListener.uploadedFileReceived( + new FileUploadEvent(event.getSource(), event.getFilename(), event.getMIMEType(), is)); } @Override public void updateProgress(long readBytes, long contentLength) { - uploadProgress.setValue(((float)readBytes)/(float)contentLength); + uploadProgress.setValue(((float) readBytes) / (float) contentLength); } @Override public OutputStream receiveUpload(String filename, String mimeType) { - FileOutputStream fos = null; - try { - fos = new FileOutputStream(UploadTrackerModel.FILEUPLOAD_PATH + filename); - } catch (FileNotFoundException e) { - Notification.show("Error occurred while uploading the file", e.getMessage(), Type.ERROR_MESSAGE); - } finally { - return fos; - } + return baos; } public IUploadedFileListener getUploadedFileListener() { diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java index 316a469..ed56dcf 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/UploadTrackerModel.java @@ -1,7 +1,6 @@ package org.vaadin.bugrap.ui; public class UploadTrackerModel { - public static final String FILEUPLOAD_PATH = "/Users/onuridrisoglu/Downloads/temp/"; private boolean isUploadCompleted = false; diff --git a/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java b/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java index 81f4dcc..06bd56c 100644 --- a/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java +++ b/bugrap/src/main/java/org/vaadin/bugrap/ui/beans/FileUploadEvent.java @@ -1,20 +1,19 @@ package org.vaadin.bugrap.ui.beans; -import com.vaadin.server.DownloadStream; -import com.vaadin.ui.Upload; +import java.io.InputStream; public class FileUploadEvent { - + private String filename; private String mimeType; - private DownloadStream downloadStream; private Object source; - - public FileUploadEvent(Object source, String filename, String mimeType, DownloadStream downloadStream) { + private InputStream stream; + + public FileUploadEvent(Object source, String filename, String mimeType, InputStream stream) { this.filename = filename; this.mimeType = mimeType; - this.downloadStream = downloadStream; - this.setSource(source); + this.source = source; + this.stream = stream; } public String getFilename() { @@ -33,14 +32,6 @@ public void setMimeType(String mimeType) { this.mimeType = mimeType; } - public DownloadStream getDownloadStream() { - return downloadStream; - } - - public void setDownloadStream(DownloadStream downloadStream) { - this.downloadStream = downloadStream; - } - public Object getSource() { return source; } @@ -48,4 +39,12 @@ public Object getSource() { public void setSource(Object source) { this.source = source; } + + public InputStream getStream() { + return stream; + } + + public void setStream(InputStream stream) { + this.stream = stream; + } } diff --git a/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss index 649e5e4..f9fea18 100644 --- a/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss +++ b/bugrap/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss @@ -39,6 +39,7 @@ height: 20px; width: 10px; vertical-align: center; + margin-right: 2px; } div.v-slot-removed-upload{ diff --git a/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css b/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css index f3a39ec..3d47e48 100644 --- a/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css +++ b/bugrap/src/main/webapp/VAADIN/themes/mytheme/styles.css @@ -14785,6 +14785,7 @@ div.v-layout.v-horizontal.v-widget { height: 20px; width: 10px; vertical-align: center; + margin-right: 2px; } .mytheme div.v-slot-removed-upload {