PopUp dialog for canceling queued uploads (#1112)

* added cancel dialog for queued uploads

Signed-off-by: Robert Sing <robert.sing@bosch-si.com>

* fix PR review findings

Signed-off-by: Robert Sing <robert.sing@bosch-si.com>

* fix sonar finding

Signed-off-by: Robert Sing <robert.sing@bosch-si.com>

* fixed DashboardMenu navigation

Signed-off-by: Robert Sing <robert.sing@bosch-si.com>
This commit is contained in:
Robert Sing
2021-06-14 13:40:20 +02:00
committed by GitHub
parent bacd72f40c
commit 18851d62a1
5 changed files with 63 additions and 4 deletions

View File

@@ -8,6 +8,8 @@
*/ */
package org.eclipse.hawkbit.ui.artifacts; package org.eclipse.hawkbit.ui.artifacts;
import static org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus.UPLOAD_STARTED;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
@@ -24,7 +26,9 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsGridLayout; import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsGridLayout;
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleGridLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleGridLayout;
import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout; import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout;
import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware; import org.eclipse.hawkbit.ui.common.event.EventViewAware;
@@ -32,19 +36,26 @@ import org.eclipse.hawkbit.ui.common.layout.listener.LayoutResizeListener;
import org.eclipse.hawkbit.ui.common.layout.listener.LayoutResizeListener.ResizeHandler; import org.eclipse.hawkbit.ui.common.layout.listener.LayoutResizeListener.ResizeHandler;
import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener; import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener;
import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener.VisibilityHandler; import org.eclipse.hawkbit.ui.common.layout.listener.LayoutVisibilityListener.VisibilityHandler;
import org.eclipse.hawkbit.ui.menu.DashboardEvent;
import org.eclipse.hawkbit.ui.menu.DashboardMenu;
import org.eclipse.hawkbit.ui.menu.DashboardMenuItem;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.navigator.View; import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewBeforeLeaveEvent;
import com.vaadin.server.Page; import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeEvent;
import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.server.Page.BrowserWindowResizeListener;
import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.VerticalLayout;
/** /**
@@ -63,6 +74,8 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
private final SMTypeFilterLayout smTypeFilterLayout; private final SMTypeFilterLayout smTypeFilterLayout;
private final SoftwareModuleGridLayout smGridLayout; private final SoftwareModuleGridLayout smGridLayout;
private final ArtifactDetailsGridLayout artifactDetailsGridLayout; private final ArtifactDetailsGridLayout artifactDetailsGridLayout;
private final VaadinMessageSource i18n;
private final DashboardMenu dashboardMenu;
private HorizontalLayout mainLayout; private HorizontalLayout mainLayout;
@@ -74,12 +87,15 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
final UINotification uiNotification, final ArtifactUploadState artifactUploadState, final UINotification uiNotification, final ArtifactUploadState artifactUploadState,
final EntityFactory entityFactory, final SoftwareModuleManagement softwareModuleManagement, final EntityFactory entityFactory, final SoftwareModuleManagement softwareModuleManagement,
final SoftwareModuleTypeManagement softwareModuleTypeManagement, final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final MultipartConfigElement multipartConfigElement, final ArtifactManagement artifactManagement) { final MultipartConfigElement multipartConfigElement, final ArtifactManagement artifactManagement,
final DashboardMenu dashboardMenu) {
this.permChecker = permChecker; this.permChecker = permChecker;
this.artifactUploadState = artifactUploadState; this.artifactUploadState = artifactUploadState;
this.i18n = i18n;
this.dashboardMenu = dashboardMenu;
final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, uiNotification, final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus,
permChecker); uiNotification, permChecker);
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
this.smTypeFilterLayout = new SMTypeFilterLayout(uiDependencies, softwareModuleTypeManagement, this.smTypeFilterLayout = new SMTypeFilterLayout(uiDependencies, softwareModuleTypeManagement,
@@ -260,4 +276,35 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
artifactDetailsGridLayout.unsubscribeListener(); artifactDetailsGridLayout.unsubscribeListener();
} }
} }
@Override
public void beforeLeave(final ViewBeforeLeaveEvent event) {
if (isAnyUploadInUploadQueue()) {
final ConfirmationDialog confirmDeleteDialog = new ConfirmationDialog(i18n,
i18n.getMessage(UIMessageIdProvider.CAPTION_CLEAR_FILE_UPLOAD_QUEUE),
i18n.getMessage(UIMessageIdProvider.MESSAGE_CLEAR_FILE_UPLOAD_QUEUE), ok -> {
if (Boolean.TRUE.equals(ok)) {
// Clear all queued file uploads
artifactUploadState.clearFileStates();
event.navigate();
} else {
// Send a PostViewChangeEvent to the DashboardMenu as if the navigation actually
// happened to prevent the DashboardMenu navigation from getting stuck
final DashboardMenuItem dashboardMenuItem = dashboardMenu.getByViewName(VIEW_NAME);
dashboardMenu.postViewChange(DashboardEvent.createPostViewChangeEvent(dashboardMenuItem));
}
}, UIComponentIdProvider.UPLOAD_QUEUE_CLEAR_CONFIRMATION_DIALOG);
UI.getCurrent().addWindow(confirmDeleteDialog.getWindow());
confirmDeleteDialog.getWindow().bringToFront();
} else {
event.navigate();
}
}
private boolean isAnyUploadInUploadQueue() {
return artifactUploadState.getAllFileUploadProgressValuesFromOverallUploadProcessList().stream()
.map(FileUploadProgress::getFileUploadStatus)
.anyMatch(fileUploadStatus -> fileUploadStatus == UPLOAD_STARTED);
}
} }

View File

@@ -60,7 +60,7 @@ public class FileTransferHandlerStreamVariable extends AbstractFileTransferHandl
} }
/** /**
* Checks for duplication and invalid file name during feil upload process * Checks for duplication and invalid file name during file upload process
* *
* @param event * @param event
* StreamingStartEvent * StreamingStartEvent

View File

@@ -1498,6 +1498,11 @@ public final class UIComponentIdProvider {
*/ */
public static final String DISTRIBUTION_SET_TYPE_ID_PREFIXS = "dist.set.type"; public static final String DISTRIBUTION_SET_TYPE_ID_PREFIXS = "dist.set.type";
/**
* Id of the file upload cancel confirmation window
*/
public static final String UPLOAD_QUEUE_CLEAR_CONFIRMATION_DIALOG = "upload.queue.clear.confirmation.window";
/** /**
* /* Private Constructor. * /* Private Constructor.
*/ */

View File

@@ -227,6 +227,8 @@ public final class UIMessageIdProvider {
public static final String CAPTION_ARTIFACT_FILENAME = "artifact.filename.caption"; public static final String CAPTION_ARTIFACT_FILENAME = "artifact.filename.caption";
public static final String CAPTION_CLEAR_FILE_UPLOAD_QUEUE = "caption.clear.file.upload.queue";
public static final String CAPTION_ARTIFACT_FILESIZE_BYTES = "artifact.filesize.bytes.caption"; public static final String CAPTION_ARTIFACT_FILESIZE_BYTES = "artifact.filesize.bytes.caption";
public static final String CAPTION_SOFTWARE_MODULE = "caption.software.module"; public static final String CAPTION_SOFTWARE_MODULE = "caption.software.module";
@@ -235,6 +237,8 @@ public final class UIMessageIdProvider {
public static final String MESSAGE_TARGET_BULKUPLOAD_RESULT_FAIL = "message.bulk.upload.result.fail"; public static final String MESSAGE_TARGET_BULKUPLOAD_RESULT_FAIL = "message.bulk.upload.result.fail";
public static final String MESSAGE_CLEAR_FILE_UPLOAD_QUEUE = "message.clear.file.upload.queue.confirm";
public static final String VAADIN_SYSTEM_SESSIONEXPIRED_CAPTION = "vaadin.system.sessionexpired.caption"; public static final String VAADIN_SYSTEM_SESSIONEXPIRED_CAPTION = "vaadin.system.sessionexpired.caption";
public static final String VAADIN_SYSTEM_SESSIONEXPIRED_MESSAGE = "vaadin.system.sessionexpired.message"; public static final String VAADIN_SYSTEM_SESSIONEXPIRED_MESSAGE = "vaadin.system.sessionexpired.message";

View File

@@ -161,6 +161,8 @@ caption.maintenancewindow.schedule = Schedule
caption.maintenancewindow.duration = Duration caption.maintenancewindow.duration = Duration
caption.maintenancewindow.timezone = Time Zone (from GMT) caption.maintenancewindow.timezone = Time Zone (from GMT)
caption.clear.file.upload.queue = Clear file upload queue
# Labels prefix with - label # Labels prefix with - label
label.create.filter = Create Filter label.create.filter = Create Filter
label.edit.filter = Edit Filter label.edit.filter = Edit Filter
@@ -497,6 +499,7 @@ message.key.deleted.or.notAllowed = {0} with key {0} was deleted or you are not
message.forcedTime.cannotBeEmpty = Forced time can not be empty message.forcedTime.cannotBeEmpty = Forced time can not be empty
message.forcedTime.missing = Force time is not specified for the time-forced assignment message.forcedTime.missing = Force time is not specified for the time-forced assignment
message.scheduledTime.cannotBeEmpty = Scheduled time can not be empty message.scheduledTime.cannotBeEmpty = Scheduled time can not be empty
message.clear.file.upload.queue.confirm = There is still at least one queued file upload pending. By leaving this view the upload queue will be cleared. \nAre you sure you want to leave this view?
# action info # action info
action.target.table.selectall = Select all (Ctrl+A) action.target.table.selectall = Select all (Ctrl+A)