From 11fa4469dd6b12a787c6cb7663d649907ee72dcd Mon Sep 17 00:00:00 2001 From: Marcel Mager Date: Tue, 6 Dec 2016 19:56:10 +0100 Subject: [PATCH] Replace server-side dnd validation with client-side validation: (#368) * Replace server-side dnd validation with client-side validation: Client-side validation means: * Custom widgetset is used to introduce the client-side validation * Accept-calculation is performed on client-side * Drop-hints are calculated on client-side (show/hide) * Row count decoration is calculated on client-side (multi-selection) * Notification box is triggered from client-side Beside the migration from server-side validation to client-side validation there are few improvements: * Improvement1: If drag is aborted outside the components by releasing the mouse or the drag aborts by pressing the ESC key) -> drop area hints are removed * Improvement2: If multiple rows are selected in table, but drag is performed on a non-selected single element from table -> the single drag-element is not decorated with the row selection count * Improvement3: Upload View: Component 'Drop files to upload' only accepts files (and no drags from filter and software module component) Signed-off-by: Marcel Mager (INST-IOT/ESB) * Improve code quality Signed-off-by: Marcel Mager (INST-IOT/ESB) * Fix formatting of license headers Signed-off-by: Marcel Mager (INST-IOT/ESB) * Fix scopes and modifiers Signed-off-by: Marcel Mager (INST-IOT/ESB) * Externalize key-strings used for dnd-data transfer from server to client Minor issues: * improve naming schema of control variables (no more i-s) * add final modifier Signed-off-by: Marcel Mager (INST-IOT/ESB) * Add license header Signed-off-by: Marcel Mager (INST-IOT/ESB) --- hawkbit-ui/pom.xml | 6 +- .../eclipse/hawkbit/ui/AppWidgetSet.gwt.xml | 2 + .../ui/artifacts/UploadArtifactView.java | 25 +- .../event/UploadViewAcceptCriteria.java | 79 ----- .../footer/SMDeleteActionsLayout.java | 24 +- .../smtable/SoftwareModuleTable.java | 10 +- .../smtable/SoftwareModuleTableLayout.java | 6 +- .../artifacts/smtype/SMTypeFilterButtons.java | 14 +- .../artifacts/smtype/SMTypeFilterLayout.java | 6 +- .../ui/artifacts/upload/UploadLayout.java | 11 +- .../ui/common/AbstractAcceptCriteria.java | 193 ----------- .../footer/AbstractDeleteActionsLayout.java | 21 -- .../ui/dd/CustomAcceptCriteria.gwt.xml | 38 +++ .../criteria/ItemIdClientCriterion.java | 64 ++++ .../client/criteria/ViewClientCriterion.java | 303 ++++++++++++++++++ .../ViewComponentClientCriterion.java | 168 ++++++++++ .../dd/criteria/AcceptCriteriaConstants.java | 86 +++++ .../DistributionsViewClientCriterion.java | 76 +++++ .../ManagementViewClientCriterion.java | 83 +++++ .../criteria/ServerItemIdClientCriterion.java | 127 ++++++++ .../criteria/ServerViewClientCriterion.java | 81 +++++ .../ServerViewComponentClientCriterion.java | 208 ++++++++++++ .../criteria/UploadViewClientCriterion.java | 60 ++++ .../ui/distributions/DistributionsView.java | 26 +- .../disttype/DSTypeFilterButtons.java | 12 +- .../disttype/DSTypeFilterLayout.java | 6 +- .../dstable/DistributionSetTable.java | 28 +- .../dstable/DistributionSetTableHeader.java | 2 - .../dstable/DistributionSetTableLayout.java | 6 +- .../DistributionsViewAcceptCriteria.java | 101 ------ .../ui/distributions/event/DragEvent.java | 20 -- .../footer/DSDeleteActionsLayout.java | 30 +- .../distributions/smtable/SwModuleTable.java | 10 +- .../smtable/SwModuleTableLayout.java | 6 +- .../smtype/DistSMTypeFilterButtons.java | 14 +- .../smtype/DistSMTypeFilterLayout.java | 6 +- .../hawkbit/ui/management/DeploymentView.java | 28 +- .../DistributionAddUpdateWindowLayout.java | 2 - .../management/dstable/DistributionTable.java | 24 +- .../dstable/DistributionTableHeader.java | 2 - .../dstable/DistributionTableLayout.java | 6 +- .../dstag/DistributionTagButtons.java | 18 +- .../dstag/DistributionTagLayout.java | 6 +- .../event/DistributionTagDropEvent.java | 13 +- .../ui/management/event/DragEvent.java | 18 -- .../event/ManagementViewAcceptCriteria.java | 109 ------- .../footer/DeleteActionsLayout.java | 37 +-- .../TargetAddUpdateWindowLayout.java | 2 - .../management/targettable/TargetTable.java | 21 +- .../targettable/TargetTableHeader.java | 26 +- .../targettable/TargetTableLayout.java | 6 +- .../targettag/MultipleTargetFilter.java | 12 +- .../targettag/TargetTagFilterButtons.java | 27 +- .../targettag/TargetTagFilterLayout.java | 7 +- .../hawkbit/ui/utils/HawkbitCommonUtil.java | 88 +---- .../ui/utils/SPUIStyleDefinitions.java | 20 -- .../ui/utils/UIComponentIdProvider.java | 6 + .../hawkbit/customstyles/drop-hint.scss | 36 +-- .../themes/hawkbit/customstyles/table.scss | 4 +- .../client/criteria/CriterionTestHelper.java | 68 ++++ .../criteria/ItemIdClientCriterionTest.java | 139 ++++++++ .../criteria/ViewClientCriterionTest.java | 241 ++++++++++++++ .../ViewComponentClientCriterionTest.java | 242 ++++++++++++++ pom.xml | 7 + 64 files changed, 2181 insertions(+), 992 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractAcceptCriteria.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/CustomAcceptCriteria.gwt.xml create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ItemIdClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewComponentClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/AcceptCriteriaConstants.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/DistributionsViewClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ManagementViewClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ServerItemIdClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ServerViewClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ServerViewComponentClientCriterion.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/UploadViewClientCriterion.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionsViewAcceptCriteria.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DragEvent.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DragEvent.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/ManagementViewAcceptCriteria.java create mode 100644 hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/dd/client/criteria/CriterionTestHelper.java create mode 100644 hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/dd/client/criteria/ItemIdClientCriterionTest.java create mode 100644 hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterionTest.java create mode 100644 hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewComponentClientCriterionTest.java diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml index 9b136204c..cda6da026 100644 --- a/hawkbit-ui/pom.xml +++ b/hawkbit-ui/pom.xml @@ -252,7 +252,6 @@ spring-boot-configuration-processor true - org.eclipse.hawkbit @@ -265,6 +264,11 @@ mockito-core test + + com.google.gwt.gwtmockito + gwtmockito + test + org.easytesting fest-assert-core diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml index 5479eab26..8cd465d82 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml @@ -33,9 +33,11 @@ + + diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java index 427eabf66..4b7b8860f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java @@ -20,14 +20,13 @@ import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout; import org.eclipse.hawkbit.ui.artifacts.event.ArtifactDetailsEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria; import org.eclipse.hawkbit.ui.artifacts.footer.SMDeleteActionsLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleTableLayout; import org.eclipse.hawkbit.ui.artifacts.smtype.SMTypeFilterLayout; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.artifacts.upload.UploadLayout; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.management.event.DragEvent; +import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -38,7 +37,6 @@ import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; -import com.vaadin.event.MouseEvents.ClickListener; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.server.Page; @@ -50,7 +48,6 @@ import com.vaadin.ui.Alignment; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; /** @@ -94,7 +91,7 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW UploadArtifactView(final UIEventBus eventBus, final SpPermissionChecker permChecker, final I18N i18n, final UINotification uiNotification, final ArtifactUploadState artifactUploadState, final TagManagement tagManagement, final EntityFactory entityFactory, - final SoftwareManagement softwareManagement, final UploadViewAcceptCriteria uploadViewAcceptCriteria, + final SoftwareManagement softwareManagement, final UploadViewClientCriterion uploadViewClientCriterion, final SPInfo spInfo, final ArtifactManagement artifactManagement) { this.eventBus = eventBus; this.permChecker = permChecker; @@ -102,15 +99,15 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW this.uiNotification = uiNotification; this.artifactUploadState = artifactUploadState; this.filterByTypeLayout = new SMTypeFilterLayout(artifactUploadState, i18n, permChecker, eventBus, - tagManagement, entityFactory, uiNotification, softwareManagement, uploadViewAcceptCriteria); + tagManagement, entityFactory, uiNotification, softwareManagement, uploadViewClientCriterion); this.smTableLayout = new SoftwareModuleTableLayout(i18n, permChecker, artifactUploadState, uiNotification, - eventBus, softwareManagement, entityFactory, uploadViewAcceptCriteria); + eventBus, softwareManagement, entityFactory, uploadViewClientCriterion); this.artifactDetailsLayout = new ArtifactDetailsLayout(i18n, eventBus, artifactUploadState, uiNotification, artifactManagement); this.uploadLayout = new UploadLayout(i18n, uiNotification, eventBus, artifactUploadState, spInfo, artifactManagement); this.deleteActionsLayout = new SMDeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, - artifactUploadState, softwareManagement, uploadViewAcceptCriteria); + artifactUploadState, softwareManagement, uploadViewClientCriterion); } @PostConstruct @@ -161,7 +158,6 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW createMainLayout(); addComponents(mainLayout); setExpandRatio(mainLayout, 1); - hideDropHints(); } } @@ -257,17 +253,6 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW } - private void hideDropHints() { - UI.getCurrent().addClickListener(new ClickListener() { - private static final long serialVersionUID = 1L; - - @Override - public void click(final com.vaadin.event.MouseEvents.ClickEvent event) { - eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - } - }); - } - private void checkNoDataAvaialble() { if (artifactUploadState.isNoDataAvilableSoftwareModule()) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java deleted file mode 100644 index 98d9b49c8..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.event; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.springframework.beans.factory.annotation.Autowired; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.google.common.collect.Maps; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.UIScope; -import com.vaadin.ui.Component; - -/** - * Upload UI View for Accept criteria. - * - */ -@SpringComponent -@UIScope -public class UploadViewAcceptCriteria extends AbstractAcceptCriteria { - - private static final long serialVersionUID = 5158811326115667378L; - - private static final Map> DROP_CONFIGS = createDropConfigurations(); - - private static final Map DROP_HINTS_CONFIGS = createDropHintConfigurations(); - - @Autowired - UploadViewAcceptCriteria(final UINotification uiNotification, final UIEventBus eventBus) { - super(uiNotification, eventBus); - } - - @Override - protected String getComponentId(final Component component) { - String id = component.getId(); - if (id != null && id.startsWith(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)) { - id = UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX; - } - return id; - } - - @Override - protected Map getDropHintConfigurations() { - return DROP_HINTS_CONFIGS; - } - - @Override - protected Map> getDropConfigurations() { - return DROP_CONFIGS; - } - - private static Map> createDropConfigurations() { - final Map> config = Maps.newHashMapWithExpectedSize(1); - // Delete drop area droppable components - config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID, Arrays.asList( - UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)); - - return config; - } - - private static Map createDropHintConfigurations() { - final Map config = Maps.newHashMapWithExpectedSize(2); - config.put(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX, UploadArtifactUIEvent.SOFTWARE_TYPE_DRAG_START); - config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UploadArtifactUIEvent.SOFTWARE_DRAG_START); - return config; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java index b6bdb4546..8910fcc8d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java @@ -13,11 +13,10 @@ import java.util.Set; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout; import org.eclipse.hawkbit.ui.common.table.AbstractTable; -import org.eclipse.hawkbit.ui.management.event.DragEvent; +import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; @@ -44,16 +43,16 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { private final UploadViewConfirmationWindowLayout uploadViewConfirmationWindowLayout; - private final UploadViewAcceptCriteria uploadViewAcceptCriteria; + private final UploadViewClientCriterion uploadViewClientCriterion; public SMDeleteActionsLayout(final I18N i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, final UINotification notification, final ArtifactUploadState artifactUploadState, - final SoftwareManagement softwareManagement, final UploadViewAcceptCriteria uploadViewAcceptCriteria) { + final SoftwareManagement softwareManagement, final UploadViewClientCriterion uploadViewClientCriterion) { super(i18n, permChecker, eventBus, notification); this.artifactUploadState = artifactUploadState; this.uploadViewConfirmationWindowLayout = new UploadViewConfirmationWindowLayout(i18n, eventBus, softwareManagement, artifactUploadState); - this.uploadViewAcceptCriteria = uploadViewAcceptCriteria; + this.uploadViewClientCriterion = uploadViewClientCriterion; init(); } @@ -74,10 +73,6 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { updateSWActionCount(); }); } - if (event == UploadArtifactUIEvent.SOFTWARE_DRAG_START - || event == UploadArtifactUIEvent.SOFTWARE_TYPE_DRAG_START) { - showDropHints(); - } } private boolean isSoftwareEvent(final UploadArtifactUIEvent event) { @@ -92,14 +87,6 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { || event == UploadArtifactUIEvent.DISCARD_DELETE_SOFTWARE_TYPE; } - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final DragEvent event) { - if (event == DragEvent.HIDE_DROP_HINT) { - UI.getCurrent().access(() -> hideDropHints()); - } - - } - @Override protected boolean hasDeletePermission() { return permChecker.hasDeleteDistributionPermission(); @@ -127,7 +114,7 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { @Override protected AcceptCriterion getDeleteLayoutAcceptCriteria() { - return uploadViewAcceptCriteria; + return uploadViewClientCriterion; } @Override @@ -152,7 +139,6 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { } } - hideDropHints(); } private void deleteSWModuleType(final String swModuleTypeName) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index c9f4589b9..3ee219a0a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -16,11 +16,11 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.artifacts.event.SMFilterEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; @@ -59,18 +59,18 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable targetSelectedList = new HashSet<>((Set) compsource.getValue()); - /** - * Remove null value if any . - */ - targetSelectedList.remove(null); - - if (previousRowCount != targetSelectedList.size()) { - previousRowCount = targetSelectedList.size(); - /* - * Prepare the hava script to add the