Merge branch 'master' into feature_auto_assignment_squashed

This commit is contained in:
Dominik Herbst
2016-10-07 14:57:11 +02:00
211 changed files with 5164 additions and 2794 deletions

View File

@@ -11,34 +11,31 @@
-->
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd">
<module>
<!-- This file is automatically updated based on new dependencies by the
goal "vaadin:update-widgetset". -->
<!-- This file is automatically updated based on new dependencies by the goal "vaadin:update-widgetset". -->
<!-- Inherit DefaultWidgetSet -->
<inherits name="com.vaadin.DefaultWidgetSet" />
<!-- Inherit DefaultWidgetSet -->
<inherits name="com.vaadin.DefaultWidgetSet" />
<inherits
name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset" />
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset" />
<inherits
name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
<inherits name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
<inherits name="org.vaadin.peter.contextmenu.ContextmenuWidgetset" />
<inherits name="org.vaadin.peter.contextmenu.ContextmenuWidgetset" />
<inherits
name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits
name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
<inherits name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
<inherits name="org.eclipse.hawkbit.ui.customrenderers.CustomRendererWidgetSet" />
<inherits name="org.eclipse.hawkbit.ui.customrenderers.CustomRendererWidgetSet" />
<inherits name="org.eclipse.hawkbit.ui.filtermanagement.TextFieldSuggestionBox" />
<inherits name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
<inherits name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
</module>

View File

@@ -9,8 +9,8 @@
package org.eclipse.hawkbit.ui.artifacts.details;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -46,6 +46,7 @@ import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
@@ -207,8 +208,7 @@ public class ArtifactDetailsLayout extends VerticalLayout {
}
private Container createArtifactLazyQueryContainer() {
final Map<String, Object> queryConfiguration = new HashMap<>();
return getArtifactLazyQueryContainer(queryConfiguration);
return getArtifactLazyQueryContainer(Collections.emptyMap());
}
private LazyQueryContainer getArtifactLazyQueryContainer(final Map<String, Object> queryConfig) {
@@ -429,9 +429,12 @@ public class ArtifactDetailsLayout extends VerticalLayout {
titleOfArtifactDetails.setContentMode(ContentMode.HTML);
}
}
final Map<String, Object> queryConfiguration = new HashMap<>();
final Map<String, Object> queryConfiguration;
if (baseSwModuleId != null) {
queryConfiguration = Maps.newHashMapWithExpectedSize(1);
queryConfiguration.put(SPUIDefinitions.BY_BASE_SOFTWARE_MODULE, baseSwModuleId);
} else {
queryConfiguration = Collections.emptyMap();
}
final LazyQueryContainer artifactContainer = getArtifactLazyQueryContainer(queryConfiguration);
artifactDetailsTable.setContainerDataSource(artifactContainer);

View File

@@ -9,13 +9,13 @@
package org.eclipse.hawkbit.ui.artifacts.event;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import com.google.common.collect.Maps;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Component;
@@ -54,7 +54,7 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, List<String>> createDropConfigurations() {
final Map<String, List<String>> config = new HashMap<>();
final Map<String, List<String>> 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));
@@ -63,7 +63,7 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, Object> createDropHintConfigurations() {
final Map<String, Object> config = new HashMap<>();
final Map<String, Object> 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;

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.artifacts.footer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -21,11 +20,12 @@ import org.eclipse.hawkbit.ui.artifacts.state.CustomFile;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
@@ -64,7 +64,7 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
@Override
protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<>();
final Map<String, ConfirmationTab> tabs = Maps.newHashMapWithExpectedSize(2);
if (!artifactUploadState.getDeleteSofwareModules().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
}

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.ui.artifacts.smtable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -25,11 +24,11 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
@@ -37,6 +36,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -97,7 +97,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(2);
artifactUploadState.getSoftwareModuleFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));

View File

@@ -32,11 +32,11 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -572,6 +572,9 @@ public class UploadConfirmationWindow implements Button.ClickListener {
}
// Exception squid:S3655 - Optional access is checked in
// checkIfArtifactDetailsDispalyed subroutine
@SuppressWarnings("squid:S3655")
private void processArtifactUpload() {
final List<String> itemIds = (List<String>) uploadDetailsTable.getItemIds();
if (preUploadValidation(itemIds)) {
@@ -593,6 +596,7 @@ public class UploadConfirmationWindow implements Button.ClickListener {
}
refreshArtifactDetailsLayout = checkIfArtifactDetailsDispalyed(bSoftwareModule.getId());
}
if (refreshArtifactDetailsLayout) {
uploadLayout.refreshArtifactDetailsLayout(artifactUploadState.getSelectedBaseSoftwareModule().get());
}

View File

@@ -34,10 +34,10 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.util.SPInfo;
import org.slf4j.Logger;
@@ -254,6 +254,11 @@ public class UploadLayout extends VerticalLayout {
final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles();
// selected software module at the time of file drop is
// considered for upload
if (!artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) {
return;
}
final SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get();
// reset the flag
hasDirectory = Boolean.FALSE;
@@ -589,7 +594,9 @@ public class UploadLayout extends VerticalLayout {
// delete file system zombies
artifactUploadState.getFileSelected().forEach(customFile -> {
final File file = new File(customFile.getFilePath());
file.delete();
if (!file.delete()) {
LOG.warn("Failed to delete file {} in upload dialog", customFile.getFilePath());
}
});
artifactUploadState.getFileSelected().clear();

View File

@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -28,11 +27,12 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Container.ItemSetChangeListener;
@@ -129,8 +129,8 @@ public class CommonDialogWindow extends Window {
this.helpLink = helpLink;
this.closeListener = closeListener;
this.cancelButtonClickListener = cancelButtonClickListener;
this.orginalValues = new HashMap<>();
this.allComponents = getAllComponents(layout);
this.orginalValues = Maps.newHashMapWithExpectedSize(allComponents.size());
this.i18n = i18n;
init();
}

View File

@@ -30,8 +30,8 @@ import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.Transferable;

View File

@@ -96,7 +96,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
private VerticalLayout tagsLayout;
private final Map<String, StringBuilder> assignedSWModule = new HashMap<>();
private Map<String, StringBuilder> assignedSWModule;
/**
* softwareLayout Initialize the component.
@@ -153,6 +153,10 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
}
if (null != softwareModuleIdNameList) {
if (assignedSWModule == null) {
assignedSWModule = new HashMap<>();
}
for (final SoftwareModuleIdName swIdName : softwareModuleIdNameList) {
final SoftwareModule softwareModule = softwareManagement.findSoftwareModuleById(swIdName.getId());
if (assignedSWModule.containsKey(softwareModule.getType().getName())) {
@@ -178,9 +182,11 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
}
private Button assignSoftModuleButton(final String softwareModuleName) {
if (getPermissionChecker().hasUpdateDistributionPermission() && distributionSetManagement
.findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId())
.getAssignedTargets().isEmpty()) {
if (getPermissionChecker().hasUpdateDistributionPermission()
&& manageDistUIState.getLastSelectedDistribution().isPresent()
&& distributionSetManagement
.findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId())
.getAssignedTargets().isEmpty()) {
final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true,
FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
reassignSoftModule.setEnabled(false);
@@ -195,6 +201,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
@SuppressWarnings("unchecked")
private void updateSoftwareModule(final SoftwareModule module) {
if (assignedSWModule == null) {
assignedSWModule = new HashMap<>();
}
softwareModuleTable.getContainerDataSource().getItemIds();
if (assignedSWModule.containsKey(module.getType().getName())) {
@@ -377,7 +386,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
if ((saveActionWindowEvent == SaveActionWindowEvent.SAVED_ASSIGNMENTS
|| saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS)
&& getSelectedBaseEntity() != null) {
assignedSWModule.clear();
if (assignedSWModule != null) {
assignedSWModule.clear();
}
setSelectedBaseEntity(
distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()));
UI.getCurrent().access(() -> populateModule());
@@ -389,7 +400,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
if (saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ASSIGNMENT
|| saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS
|| saveActionWindowEvent == SaveActionWindowEvent.DELETE_ALL_SOFWARE) {
assignedSWModule.clear();
if (assignedSWModule != null) {
assignedSWModule.clear();
}
showUnsavedAssignment();
}
}

View File

@@ -57,6 +57,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -167,7 +168,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(2);
manageDistUIState.getManageDistFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
@@ -530,7 +531,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
return manageMetadataBtn;
}
private void showMetadataDetails(final Long itemId) {
private void showMetadataDetails(final Long itemId) {
final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(itemId);
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null));
}

View File

@@ -79,7 +79,6 @@ public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout<Distribut
@Override
protected void deleteMetadata(final DistributionSet entity, final String key, final String value) {
final DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value);
distributionSetManagement.deleteDistributionSetMetadata(entity, key);
}

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.distributions.event;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -17,6 +16,7 @@ import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import com.google.common.collect.Maps;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Component;
@@ -66,7 +66,7 @@ public class DistributionsViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, List<String>> createDropConfigurations() {
final Map<String, List<String>> config = new HashMap<>();
final Map<String, List<String>> config = Maps.newHashMapWithExpectedSize(2);
// Delete drop area droppable components
config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID,
@@ -82,7 +82,7 @@ public class DistributionsViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, Object> createDropHintConfigurations() {
final Map<String, Object> config = new HashMap<>();
final Map<String, Object> config = Maps.newHashMapWithExpectedSize(4);
config.put(SPUIDefinitions.DISTRIBUTION_TYPE_ID_PREFIXS, DragEvent.DISTRIBUTION_TYPE_DRAG);
config.put(UIComponentIdProvider.DIST_TABLE_ID, DragEvent.DISTRIBUTION_DRAG);
config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, DragEvent.SOFTWAREMODULE_DRAG);

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.ui.distributions.footer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -37,6 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
@@ -90,7 +90,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
@Override
protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<>();
final Map<String, ConfirmationTab> tabs = Maps.newHashMapWithExpectedSize(5);
/* Create tab for SW Modules delete */
if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
@@ -112,7 +112,6 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
}
/* Create tab for Assign Software Module */
if (!manageDistUIState.getAssignedList().isEmpty()) {
tabs.put(i18n.get("caption.assign.dist.accordion.tab"), createAssignSWModuleConfirmationTab());
}

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.ui.distributions.smtable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -40,6 +39,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -143,7 +143,7 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(3);
manageDistUIState.getSoftwareModuleFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));

View File

@@ -13,8 +13,7 @@ import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.Sof
import static org.eclipse.hawkbit.ui.utils.UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID;
import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_NAME;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent;
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
@@ -59,10 +58,9 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons {
@Override
protected LazyQueryContainer createButtonsLazyQueryContainer() {
final Map<String, Object> queryConfig = new HashMap<>();
final BeanQueryFactory<SoftwareModuleTypeBeanQuery> typeQF = new BeanQueryFactory<>(
SoftwareModuleTypeBeanQuery.class);
typeQF.setQueryConfiguration(queryConfig);
typeQF.setQueryConfiguration(Collections.emptyMap());
return new LazyQueryContainer(new LazyQueryDefinition(true, 20, VAR_NAME), typeQF);
}

View File

@@ -52,7 +52,7 @@ public class ManageDistUIState implements ManagmentEntityState<DistributionSetId
private Set<Long> selectedSoftwareModules = emptySet();
private Set<String> selectedDeleteDistSetTypes = new HashSet<>();
private final Set<String> selectedDeleteDistSetTypes = new HashSet<>();
private Set<String> selectedDeleteSWModuleTypes = new HashSet<>();
@@ -201,10 +201,6 @@ public class ManageDistUIState implements ManagmentEntityState<DistributionSetId
return selectedDeleteDistSetTypes;
}
public void setSelectedDeleteDistSetTypes(final Set<String> selectedDeleteDistSetTypes) {
this.selectedDeleteDistSetTypes = selectedDeleteDistSetTypes;
}
public Set<String> getSelectedDeleteSWModuleTypes() {
return selectedDeleteSWModuleTypes;
}

View File

@@ -1,27 +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.filter;
/**
* A filter expression interface definition to implement the UI filter
* mechanism. The filter expression can evaluate if e.g. Targets should
* currently be added to the target list or if the current enabled filtered will
* filter the target and not show the newly created target.
*
*/
@FunctionalInterface
public interface FilterExpression {
/**
* @return {@code true} if the expression evaluate that it should be
* filtered and not shown on the UI, otherwise {@code false}
*/
boolean doFilter();
}

View File

@@ -1,77 +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.filter;
import java.util.Arrays;
import java.util.List;
/**
* {@link Filters} which provides the functionality to combine
* {@link FilterExpression}s.
*
*
*
* @see FilterExpression
*
*/
public final class Filters {
/**
* private.
*/
private Filters() {
}
/**
* Combines the given filter to an or-expression and evaluate them.
*
* @param expressions
* the expressions to combine with an or-filter
* @return an or-combined filter expression
*/
public static FilterExpression or(final List<FilterExpression> expressions) {
return or(expressions.toArray(new FilterExpression[expressions.size()]));
}
/**
* Combines the given filter to an or-expression and evaluate them.
*
* @param expressions
* the expressions to combine with an or-filter
* @return an or-combined filter expression
*/
public static FilterExpression or(final FilterExpression... expressions) {
return new OrFilterExpression(expressions);
}
private static final class OrFilterExpression implements FilterExpression {
private final FilterExpression[] expresssions;
private OrFilterExpression(final FilterExpression[] expresssions) {
this.expresssions = Arrays.copyOf(expresssions, expresssions.length);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
for (final FilterExpression filterExpression : expresssions) {
if (filterExpression.doFilter()) {
return true;
}
}
return false;
}
}
}

View File

@@ -1,48 +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.filter.target;
import java.util.Optional;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
* Checks if custom target filter is applied.
*
*/
public class CustomTargetFilter implements FilterExpression {
private final Optional<TargetFilterQuery> targetFilterQuery;
/**
* Initialize.
*
* @param targetFilterQuery
* custom target filter applied
*/
public CustomTargetFilter(final Optional<TargetFilterQuery> targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.ui.filter.FilterExpression#doFilter()
*/
@Override
public boolean doFilter() {
if (!targetFilterQuery.isPresent()) {
return false;
}
return true;
}
}

View File

@@ -1,67 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.net.URI;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
*
*
*
*/
public class TargetSearchTextFilter implements FilterExpression {
private final Target target;
private final String searchTextUpper;
/**
* @param target
* the target to check against the search text
* @param searchText
* the search text check against the given target
*/
public TargetSearchTextFilter(final Target target, final String searchText) {
this.target = target;
this.searchTextUpper = searchText.toUpperCase();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
return !(descriptionIgnoreCase() || nameIgnoreCase() || controllerIdIgnoreCase() || ipAddressIgnoreCase());
}
private boolean descriptionIgnoreCase() {
if (target.getDescription() == null) {
return false;
}
return target.getDescription().toUpperCase().contains(searchTextUpper);
}
private boolean nameIgnoreCase() {
if (target.getName() == null) {
return false;
}
return target.getName().toUpperCase().contains(searchTextUpper);
}
private boolean controllerIdIgnoreCase() {
return target.getControllerId().toUpperCase().contains(searchTextUpper);
}
private boolean ipAddressIgnoreCase() {
final URI targetAddress = target.getTargetInfo().getAddress();
if (targetAddress == null || targetAddress.getHost() == null) {
return false;
}
return targetAddress.getHost().toUpperCase().contains(searchTextUpper);
}
}

View File

@@ -1,42 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.util.List;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
*
*
*
*/
public class TargetStatusFilter implements FilterExpression {
private final List<TargetUpdateStatus> targetUpdateStatus;
/**
* @param target
* the target to check the update status against
* @param updateStatus
* the target update status to check against the given target
*/
public TargetStatusFilter(final List<TargetUpdateStatus> updateStatus) {
this.targetUpdateStatus = updateStatus;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
if (targetUpdateStatus.isEmpty()) {
return false;
}
return true;
}
}

View File

@@ -1,54 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
import org.springframework.util.CollectionUtils;
/**
*
*
*
*/
public class TargetTagFilter implements FilterExpression {
private final Target target;
private final Collection<String> tags;
private final boolean noTag;
/**
* @param target
* the target to check the filter against
* @param tags
* the tags to check the target against it
* @param noTag
* {@code true} indicates that targets which have no tags should
* not be filtered, otherwise {@code false}
*/
public TargetTagFilter(final Target target, final Collection<String> tags, final boolean noTag) {
this.target = target;
this.tags = tags;
this.noTag = noTag;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
final List<String> targetTags = target.getTags().stream().map(targetTag -> targetTag.getName())
.collect(Collectors.toList());
if (targetTags.isEmpty() || (noTag && targetTags.isEmpty())) {
return false;
}
return !CollectionUtils.containsAny(targetTags, tags);
}
}

View File

@@ -0,0 +1,264 @@
/**
* 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.filtermanagement;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder;
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
/**
* An textfield with the {@link TextFieldSuggestionBox} extension which shows
* suggestions in a suggestion-pop-up window while typing.
*/
@SpringComponent
@ViewScope
public class AutoCompleteTextFieldComponent extends HorizontalLayout {
private static final long serialVersionUID = 1L;
@Autowired
private FilterManagementUIState filterManagementUIState;
@Autowired
private transient EventBus.SessionEventBus eventBus;
@Autowired
private transient RsqlValidationOracle rsqlValidationOracle;
@Autowired
@Qualifier("uiExecutor")
private transient Executor executor;
private transient List<FilterQueryChangeListener> listeners = new LinkedList<>();
private final Label validationIcon;
private final TextField queryTextField;
/**
* Constructor.
*/
public AutoCompleteTextFieldComponent() {
queryTextField = createSearchField();
validationIcon = createStatusIcon();
setSizeUndefined();
setSpacing(true);
addStyleName("custom-search-layout");
addComponents(validationIcon, queryTextField);
setComponentAlignment(validationIcon, Alignment.TOP_CENTER);
}
/**
* Called by the spring-framework when this bean has be post-constructed.
*/
@PostConstruct
public void postConstruct() {
eventBus.subscribe(this);
new TextFieldSuggestionBox(rsqlValidationOracle, this).extend(queryTextField);
}
@PreDestroy
void destroy() {
eventBus.unsubscribe(this);
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final CustomFilterUIEvent custFUIEvent) {
if (custFUIEvent == CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON) {
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
if (!isValidationError()) {
validationIcon.setStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
} else {
validationIcon.setStyleName(SPUIStyleDefinitions.ERROR_ICON);
}
}
}
/**
* Clears the textfield and resets the validation icon.
*/
public void clear() {
queryTextField.clear();
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
validationIcon.setStyleName("hide-status-label");
}
@Override
public void focus() {
queryTextField.focus();
}
/**
* Adds the given listener
*
* @param textChangeListener
* the listener to be called in case of text changed
*/
public void addTextChangeListener(final FilterQueryChangeListener textChangeListener) {
listeners.add(textChangeListener);
}
public void setValue(final String textValue) {
queryTextField.setValue(textValue);
}
public String getValue() {
return queryTextField.getValue();
}
/**
* Called when the filter-query has been changed in the textfield, e.g. from
* client-side.
*
* @param currentText
* the current text of the textfield which has been changed
* @param valid
* {@code boolean} if the current text is RSQL syntax valid
* otherwise {@code false}
* @param validationMessage
* a message shown in case of syntax errors as tooltip
*/
public void onQueryFilterChange(final String currentText, final boolean valid, final String validationMessage) {
if (valid) {
showValidationSuccesIcon(currentText);
} else {
showValidationFailureIcon(validationMessage);
}
listeners.forEach(listener -> listener.queryChanged(valid, currentText));
}
/**
* Shows the validation success icon in the textfield
*
* @param text
* the text to store in the UI state object
*/
public void showValidationSuccesIcon(final String text) {
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
filterManagementUIState.setFilterQueryValue(text);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.FALSE);
}
/**
* Shows the validation error icon in the textfield
*
* @param validationMessage
* the validation message which should be added to the error-icon
* tooltip
*/
public void showValidationFailureIcon(final String validationMessage) {
validationIcon.setValue(FontAwesome.TIMES_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.ERROR_ICON);
validationIcon.setDescription(validationMessage);
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.TRUE);
}
public boolean isValidationError() {
return validationIcon.getStyleName().equals(SPUIStyleDefinitions.ERROR_ICON);
}
private TextField createSearchField() {
final TextField textField = new TextFieldBuilder().immediate(true).id("custom.query.text.Id")
.maxLengthAllowed(SPUILabelDefinitions.TARGET_FILTER_QUERY_TEXT_FIELD_LENGTH).buildTextComponent();
textField.addStyleName("target-filter-textfield");
textField.setWidth(900.0F, Unit.PIXELS);
textField.setTextChangeEventMode(TextChangeEventMode.EAGER);
textField.setImmediate(true);
textField.setTextChangeTimeout(100);
return textField;
}
private static Label createStatusIcon() {
final Label statusIcon = new Label();
statusIcon.setImmediate(true);
statusIcon.setContentMode(ContentMode.HTML);
statusIcon.setSizeFull();
setInitialStatusIconStyle(statusIcon);
statusIcon.setId(UIComponentIdProvider.VALIDATION_STATUS_ICON_ID);
return statusIcon;
}
private static void setInitialStatusIconStyle(final Label statusIcon) {
statusIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
statusIcon.setStyleName("hide-status-label");
}
class StatusCircledAsync implements Runnable {
private final UI current;
public StatusCircledAsync(final UI current) {
this.current = current;
}
@Override
public void run() {
UI.setCurrent(current);
eventBus.publish(this, CustomFilterUIEvent.FILTER_TARGET_BY_QUERY);
}
}
/**
* Sets the spinner as progress indicator.
*/
public void showValidationInProgress() {
validationIcon.setValue(null);
validationIcon.addStyleName("show-status-label");
validationIcon.setStyleName(SPUIStyleDefinitions.TARGET_FILTER_SEARCH_PROGRESS_INDICATOR_STYLE);
}
public Executor getExecutor() {
return executor;
}
/**
* Change listener on the textfield.
*/
@FunctionalInterface
public interface FilterQueryChangeListener {
/**
* Called when the text has been changed and validated.
*
* @param valid
* indicates if the entered query text is valid
* @param query
* the entered query text
*/
void queryChanged(final boolean valid, final String query);
}
}

View File

@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.ui.filtermanagement;
import java.util.concurrent.Executor;
import java.util.Optional;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -23,15 +23,15 @@ import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder;
import org.eclipse.hawkbit.ui.components.SPUIButton;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.filtermanagement.AutoCompleteTextFieldComponent.FilterQueryChangeListener;
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
@@ -40,16 +40,11 @@ import com.google.common.base.Strings;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.TextChangeEvent;
import com.vaadin.event.FieldEvents.TextChangeListener;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
@@ -94,11 +89,10 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private transient UiProperties uiProperties;
@Autowired
@Qualifier("uiExecutor")
private transient Executor executor;
private transient EntityFactory entityFactory;
@Autowired
private transient EntityFactory entityFactory;
private AutoCompleteTextFieldComponent queryTextField;
private HorizontalLayout breadcrumbLayout;
@@ -108,8 +102,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private Label headerCaption;
private TextField queryTextField;
private TextField nameTextField;
private Label nameLabel;
@@ -120,9 +112,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private Link helpLink;
private Label validationIcon;
private HorizontalLayout searchLayout;
private Button searchIcon;
private String oldFilterName;
@@ -136,8 +126,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private LayoutClickListener nameLayoutClickListner;
private boolean validationFailed = false;
/**
* Initialize the Campaign Status History Header.
*/
@@ -170,8 +158,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
} else if (custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
setUpCaptionLayout(true);
resetComponents();
} else if (custFUIEvent == CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON) {
UI.getCurrent().access(() -> updateStatusIconAfterTablePopulated());
}
}
@@ -183,38 +169,22 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
oldFilterQuery = filterManagementUIState.getTfQuery().get().getQuery();
}
breadcrumbName.setValue(nameLabel.getValue());
showValidationSuccesIcon();
queryTextField.showValidationSuccesIcon(filterManagementUIState.getFilterQueryValue());
titleFilterIconsLayout.addStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
headerCaption.setVisible(false);
setUpCaptionLayout(false);
}
private void resetComponents() {
queryTextField.clear();
queryTextField.focus();
headerCaption.setVisible(true);
breadcrumbName.setValue(headerCaption.getValue());
nameLabel.setValue("");
queryTextField.setValue("");
setInitialStatusIconStyle(validationIcon);
validationFailed = false;
saveButton.setEnabled(false);
titleFilterIconsLayout.removeStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
}
private Label createStatusIcon() {
final Label statusIcon = new Label();
statusIcon.setImmediate(true);
statusIcon.setContentMode(ContentMode.HTML);
statusIcon.setSizeFull();
setInitialStatusIconStyle(statusIcon);
statusIcon.setId(UIComponentIdProvider.VALIDATION_STATUS_ICON_ID);
return statusIcon;
}
private void setInitialStatusIconStyle(final Label statusIcon) {
statusIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
statusIcon.setStyleName("hide-status-label");
}
private void createComponents() {
breadcrumbButton = createBreadcrumbButton();
@@ -227,11 +197,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
nameTextField = createNameTextField();
nameTextField.setWidth(380, Unit.PIXELS);
queryTextField = createSearchField();
addSearchLisenter();
validationIcon = createStatusIcon();
saveButton = createSaveButton();
searchIcon = createSearchIcon();
helpLink = SPUIComponentProvider.getHelpLink(uiProperties.getLinks().getDocumentation().getTargetfilterView());
@@ -282,6 +249,14 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
}
};
queryTextField.addTextChangeListener(new FilterQueryChangeListener() {
@Override
public void queryChanged(final boolean valid, final String query) {
enableDisableSaveButton(!valid, query);
}
});
}
private void onFilterNameChange(final TextChangeEvent event) {
@@ -318,24 +293,15 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
titleFilterLayout.setComponentAlignment(titleFilterIconsLayout, Alignment.TOP_LEFT);
titleFilterLayout.setComponentAlignment(closeIcon, Alignment.TOP_RIGHT);
validationIcon = createStatusIcon();
searchLayout = new HorizontalLayout();
searchLayout.setSizeUndefined();
searchLayout.setSpacing(false);
searchLayout.addComponents(validationIcon, queryTextField);
searchLayout.addStyleName("custom-search-layout");
searchLayout.setComponentAlignment(validationIcon, Alignment.TOP_CENTER);
final HorizontalLayout iconLayout = new HorizontalLayout();
iconLayout.setSizeUndefined();
iconLayout.setSpacing(false);
iconLayout.addComponents(helpLink, saveButton);
iconLayout.addComponents(helpLink, searchIcon, saveButton);
final HorizontalLayout queryLayout = new HorizontalLayout();
queryLayout.setSizeUndefined();
queryLayout.setSpacing(true);
queryLayout.addComponents(searchLayout, iconLayout);
queryLayout.addComponents(queryTextField, iconLayout);
addComponent(breadcrumbLayout);
addComponent(titleFilterLayout);
@@ -358,66 +324,16 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
}
private void addSearchLisenter() {
queryTextField.addTextChangeListener(new TextChangeListener() {
private static final long serialVersionUID = -6668604418942689391L;
@Override
public void textChange(final TextChangeEvent event) {
validationIcon.addStyleName("show-status-label");
showValidationInProgress();
onQueryChange(event.getText());
executor.execute(new StatusCircledAsync(UI.getCurrent()));
}
});
}
class StatusCircledAsync implements Runnable {
private final UI current;
public StatusCircledAsync(final UI current) {
this.current = current;
}
@Override
public void run() {
UI.setCurrent(current);
eventBus.publish(this, CustomFilterUIEvent.FILTER_TARGET_BY_QUERY);
}
}
private void onQueryChange(final String input) {
if (!Strings.isNullOrEmpty(input)) {
final ValidationResult validationResult = FilterQueryValidation.getExpectedTokens(input);
if (!validationResult.getIsValidationFailed()) {
filterManagementUIState.setFilterQueryValue(input);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.FALSE);
validationFailed = false;
} else {
validationFailed = true;
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.TRUE);
validationIcon.setDescription(validationResult.getMessage());
showValidationFailureIcon();
}
enableDisableSaveButton(validationFailed, input);
} else {
setInitialStatusIconStyle(validationIcon);
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setIsFilterByInvalidFilterQuery(Boolean.TRUE);
}
queryTextField.setValue(input);
}
private void enableDisableSaveButton(final boolean validationFailed, final String query) {
if (validationFailed || (isNameAndQueryEmpty(nameTextField.getValue(), query)
|| (query.equals(oldFilterQuery) && nameTextField.getValue().equals(oldFilterName)))) {
saveButton.setEnabled(false);
searchIcon.setEnabled(false);
} else {
if (hasSavePermission()) {
saveButton.setEnabled(true);
}
searchIcon.setEnabled(true);
}
}
@@ -428,21 +344,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return false;
}
private void showValidationSuccesIcon() {
validationIcon.setValue(FontAwesome.CHECK_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.SUCCESS_ICON);
}
private void showValidationFailureIcon() {
validationIcon.setValue(FontAwesome.TIMES_CIRCLE.getHtml());
validationIcon.setStyleName(SPUIStyleDefinitions.ERROR_ICON);
}
private void showValidationInProgress() {
validationIcon.setValue(null);
validationIcon.setStyleName(SPUIStyleDefinitions.TARGET_FILTER_SEARCH_PROGRESS_INDICATOR_STYLE);
}
private SPUIButton createSearchResetIcon() {
final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(
UIComponentIdProvider.CUSTOM_FILTER_CLOSE, "", "", null, false, FontAwesome.TIMES,
@@ -451,18 +352,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return button;
}
private static TextField createSearchField() {
final TextField textField = new TextFieldBuilder().immediate(true).id("custom.query.text.Id")
.maxLengthAllowed(SPUILabelDefinitions.TARGET_FILTER_QUERY_TEXT_FIELD_LENGTH).buildTextComponent();
textField.addStyleName("target-filter-textfield");
textField.setWidth(900.0F, Unit.PIXELS);
textField.setTextChangeEventMode(TextChangeEventMode.LAZY);
textField.setTextChangeTimeout(1000);
textField.addShortcutListener(new AbstractField.FocusShortcut(textField, KeyCode.ENTER));
return textField;
}
private void closeFilterLayout() {
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setCreateFilterBtnClicked(false);
@@ -480,12 +369,26 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return saveButton;
}
/*
* (non-Javadoc)
*
* @see com.vaadin.ui.Button.ClickListener#buttonClick(com.vaadin.ui.Button.
* ClickEvent)
*/
private Button createSearchIcon() {
searchIcon = SPUIComponentProvider.getButton(UIComponentIdProvider.FILTER_SEARCH_ICON_ID, "", "", null, false,
FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class);
searchIcon.addClickListener(event -> onSearchIconClick());
searchIcon.setEnabled(false);
searchIcon.setData(false);
return searchIcon;
}
private void onSearchIconClick() {
if (queryTextField.isValidationError()) {
return;
}
queryTextField.showValidationInProgress();
queryTextField.getExecutor().execute(queryTextField.new StatusCircledAsync(UI.getCurrent()));
}
@Override
public void buttonClick(final ClickEvent event) {
if (UIComponentIdProvider.CUSTOM_FILTER_SAVE_ICON.equals(event.getComponent().getId())
@@ -509,7 +412,11 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
}
private void updateCustomFilter() {
final TargetFilterQuery targetFilterQuery = filterManagementUIState.getTfQuery().get();
final Optional<TargetFilterQuery> tfQuery = filterManagementUIState.getTfQuery();
if (!tfQuery.isPresent()) {
return;
}
final TargetFilterQuery targetFilterQuery = tfQuery.get();
targetFilterQuery.setName(nameTextField.getValue());
targetFilterQuery.setQuery(queryTextField.getValue());
final TargetFilterQuery updatedTargetFilter = targetFilterQueryManagement
@@ -546,13 +453,6 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
return true;
}
private void updateStatusIconAfterTablePopulated() {
queryTextField.focus();
if (!validationFailed && !Strings.isNullOrEmpty(queryTextField.getValue())) {
showValidationSuccesIcon();
}
}
private void showCustomFiltersView() {
eventBus.publish(this, CustomFilterUIEvent.SHOW_FILTER_MANAGEMENT);
}

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.filtermanagement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -37,6 +36,7 @@ import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.vaadin.data.Item;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
@@ -142,7 +142,7 @@ public class CreateOrUpdateFilterTable extends Table {
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(2);
if (!Strings.isNullOrEmpty(filterManagementUIState.getFilterQueryValue())) {
queryConfig.put(SPUIDefinitions.FILTER_BY_QUERY, filterManagementUIState.getFilterQueryValue());
}

View File

@@ -94,8 +94,7 @@ public class FilterManagementView extends VerticalLayout implements View {
void onEvent(final CustomFilterUIEvent custFilterUIEvent) {
if (custFilterUIEvent == CustomFilterUIEvent.TARGET_FILTER_DETAIL_VIEW) {
viewTargetFilterDetailLayout();
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK
|| custFilterUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK) {
this.getUI().access(() -> viewCreateTargetFilterLayout());
} else if (custFilterUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW
|| custFilterUIEvent == CustomFilterUIEvent.SHOW_FILTER_MANAGEMENT) {

View File

@@ -1,182 +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.filtermanagement;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import cz.jirutka.rsql.parser.ParseException;
import cz.jirutka.rsql.parser.RSQLParserException;
/**
*
* Validates the target filter query.
*
*/
public final class FilterQueryValidation {
private static final Logger LOGGER = LoggerFactory.getLogger(FilterQueryValidation.class);
private FilterQueryValidation() {
}
/**
* method for get ExpectedTokens.
*
* @param input
* @param entityManager
* @return
*/
public static ValidationResult getExpectedTokens(final String input) {
final TokenDescription tokenDesc = new TokenDescription();
final ValidationResult result = new ValidationResult();
final List<String> expectedTokens = new ArrayList<>();
try {
final TargetManagement management = SpringContextHelper.getBean(TargetManagement.class);
management.findTargetsAll(input, new PageRequest(0, 100));
} catch (final RSQLParameterSyntaxException ex) {
setExceptionDetails(new Exception(ex.getCause().getCause()), expectedTokens, result, tokenDesc);
result.setMessage(getCustomMessage(ex.getCause().getMessage(), result.getExpectedTokens()));
result.setIsValidationFailed(Boolean.TRUE);
LOGGER.trace("Syntax exception on parsing :", ex);
} catch (final RSQLParserException ex) {
setExceptionDetails(ex, expectedTokens, result, tokenDesc);
result.setMessage(getCustomMessage(ex.getMessage(), result.getExpectedTokens()));
result.setIsValidationFailed(Boolean.TRUE);
LOGGER.trace("Exception on parsing :", ex);
} catch (final IllegalArgumentException ex) {
result.setMessage(getCustomMessage(ex.getMessage(), null));
result.setIsValidationFailed(Boolean.TRUE);
LOGGER.trace("Illegal argument on parsing :", ex);
} catch (final RSQLParameterUnsupportedFieldException ex) {
result.setMessage(getCustomMessage(ex.getMessage(), null));
result.setIsValidationFailed(Boolean.TRUE);
LOGGER.trace("Unsupported field on parsing :", ex);
}
return result;
}
private static void setExceptionDetails(final Exception ex, final List<String> expectedTokens,
final ValidationResult result, final TokenDescription tokenDesc) {
for (final Integer node : getNextTokens(ex)) {
if (node != 12) {
expectedTokens.add(tokenDesc.getTokenImage()[node]);
}
}
final List<String> customExpectTokenList = processExpectedTokens(getNextTokens(ex));
if (!customExpectTokenList.isEmpty()) {
result.setExpectedTokens(customExpectTokenList);
} else {
result.setExpectedTokens(expectedTokens);
}
}
/**
* method for process ExpectedTokens.
*
* @param expectedTokens
* @return
*/
// Exception squid:S2095 - see
// https://jira.sonarsource.com/browse/SONARJAVA-1478
@SuppressWarnings({ "squid:S2095" })
public static List<String> processExpectedTokens(final List<Integer> expectedTokens) {
final List<String> expectToken = new ArrayList<>();
if (expectedTokens.size() == 2 && expectedTokens.contains(9) && expectedTokens.contains(4)) {
final List<String> expectedFieldList = Arrays.stream(TargetFields.values()).map(v -> v.name().toLowerCase())
.collect(Collectors.toList());
expectToken.addAll(expectedFieldList);
expectToken.add("assignedds.name");
expectToken.add("assignedds.version");
}
return expectToken;
}
/**
* Method To Get Next Token.
*
* @param e
* .
* @return list.
*/
public static List<Integer> getNextTokens(final Exception e) {
Throwable parseException = e.getCause();
final List<Integer> listTokens = new ArrayList<>();
if (parseException != null) {
do {
if (parseException instanceof ParseException) {
try {
Field declaredField;
declaredField = parseException.getClass().getDeclaredField("expectedTokenSequences");
int[][] tokens;
tokens = (int[][]) declaredField.get(parseException);
for (final int[] is : tokens) {
for (final int i : is) {
listTokens.add(i);
}
}
return listTokens;
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException
| IllegalAccessException ex) {
LOGGER.info("Exception on parsing :", ex);
}
} else {
return listTokens;
}
} while ((parseException = parseException.getCause()) != null);
}
return Collections.emptyList();
}
/**
* To Get Custom Message.
*
* @param message
* @param expectedTokens
* @return String.
*/
public static String getCustomMessage(final String message, final List<String> expectedTokens) {
String builder = message;
if (message.contains(":")) {
builder = message.substring(message.indexOf(':') + 1, message.length());
if (builder.indexOf("Was expecting") != -1) {
builder = builder.substring(0, builder.lastIndexOf("Was expecting"));
}
if (null != expectedTokens && !expectedTokens.isEmpty()) {
final StringBuilder tokens = new StringBuilder();
expectedTokens.stream().forEach(value -> tokens.append(value + ","));
builder = builder.concat("Was expecting :" + tokens.toString().substring(0, tokens.length() - 1));
}
builder = builder.replace('\r', ' ');
builder = builder.replace('\n', ' ');
builder = builder.replaceAll(">", " ");
builder = builder.replaceAll("<", " ");
}
return builder;
}
}

View File

@@ -114,6 +114,7 @@ public class TargetFilterHeader extends VerticalLayout {
}
private void addNewFilter() {
filterManagementUIState.setTfQuery(null);
filterManagementUIState.setFilterQueryValue(null);
filterManagementUIState.setCreateFilterBtnClicked(true);
eventBus.publish(this, CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK);

View File

@@ -44,6 +44,7 @@ import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.server.FontAwesome;
@@ -136,7 +137,7 @@ public class TargetFilterTable extends Table {
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(1);
filterManagementUIState.getCustomFilterSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
return queryConfig;
@@ -266,9 +267,8 @@ public class TargetFilterTable extends Table {
final String targetFilterName = (String) ((Button) event.getComponent()).getData();
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
.findTargetFilterQueryByName(targetFilterName);
filterManagementUIState.setTfQuery(targetFilterQuery);
filterManagementUIState.setFilterQueryValue(targetFilterQuery.getQuery());
filterManagementUIState.setTfQuery(targetFilterQuery);
filterManagementUIState.setEditViewDisplayed(true);
eventBus.publish(this, CustomFilterUIEvent.TARGET_FILTER_DETAIL_VIEW);
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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
-->
<module>
<inherits name="com.vaadin.DefaultWidgetSet" />
<inherits name="org.eclipse.hawkbit.ui.AppWidgetSet" />
<inherits name="org.vaadin.peter.contextmenu.ContextmenuWidgetset" />
<inherits name="org.vaadin.tokenfield.TokenfieldWidgetset" />
<inherits name="org.eclipse.hawkbit.ui.customrenderers.CustomRendererWidgetSet" />
<inherits name="org.vaadin.hene.flexibleoptiongroup.widgetset.FlexibleOptionGroupWidgetset" />
<inherits name="org.vaadin.alump.distributionbar.gwt.DistributionBarWidgetset" />
</module>

View File

@@ -0,0 +1,93 @@
/**
* 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.filtermanagement;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
import org.eclipse.hawkbit.repository.rsql.SuggestionContext;
import org.eclipse.hawkbit.repository.rsql.ValidationOracleContext;
import org.eclipse.hawkbit.ui.filtermanagement.client.SuggestTokenDto;
import org.eclipse.hawkbit.ui.filtermanagement.client.SuggestionContextDto;
import org.eclipse.hawkbit.ui.filtermanagement.client.TextFieldSuggestionBoxClientRpc;
import org.eclipse.hawkbit.ui.filtermanagement.client.TextFieldSuggestionBoxServerRpc;
import com.vaadin.server.AbstractExtension;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
/**
* Extension for the AutoCompleteTexfield.
*
*/
public class TextFieldSuggestionBox extends AbstractExtension implements TextFieldSuggestionBoxServerRpc {
private static final long serialVersionUID = 1L;
private final transient RsqlValidationOracle rsqlValidationOracle;
private final AutoCompleteTextFieldComponent autoCompleteTextFieldComponent;
/**
* Constructor.
*
* @param autoCompleteTextFieldComponent
* @param rsqlValidationOracle
* the suggestion oracle where to retrieve the suggestions from
*/
public TextFieldSuggestionBox(final RsqlValidationOracle rsqlValidationOracle,
final AutoCompleteTextFieldComponent autoCompleteTextFieldComponent) {
this.rsqlValidationOracle = rsqlValidationOracle;
this.autoCompleteTextFieldComponent = autoCompleteTextFieldComponent;
registerRpc(this, TextFieldSuggestionBoxServerRpc.class);
}
/**
* Add this extension to the target connector. This method is protected to
* allow subclasses to require a more specific type of target.
*
* @param target
* the connector to attach this extension to
*/
public void extend(final TextField target) {
super.extend(target);
}
@Override
public void suggest(final String text, final int cursor) {
final ValidationOracleContext suggest = rsqlValidationOracle.suggest(text, cursor);
updateValidationIcon(suggest, text);
getRpcProxy(TextFieldSuggestionBoxClientRpc.class).showSuggestions(mapToDto(suggest.getSuggestionContext()));
}
@Override
public void executeQuery(final String text, final int cursor) {
if (!autoCompleteTextFieldComponent.isValidationError()) {
autoCompleteTextFieldComponent.showValidationInProgress();
autoCompleteTextFieldComponent.getExecutor()
.execute(autoCompleteTextFieldComponent.new StatusCircledAsync(UI.getCurrent()));
}
}
private static SuggestionContextDto mapToDto(final SuggestionContext suggestionContext) {
return new SuggestionContextDto(suggestionContext.getCursorPosition(),
suggestionContext.getSuggestions().stream()
.filter(suggestion -> suggestion.getTokenImageName() == null
|| suggestion.getSuggestion().contains(suggestion.getTokenImageName()))
.map(suggestion -> new SuggestTokenDto(suggestion.getStart(), suggestion.getEnd(),
suggestion.getSuggestion()))
.collect(Collectors.toList()));
}
private void updateValidationIcon(final ValidationOracleContext suggest, final String text) {
final String errorMessage = (suggest.getSyntaxErrorContext() != null)
? suggest.getSyntaxErrorContext().getErrorMessage() : null;
autoCompleteTextFieldComponent.onQueryFilterChange(text, !suggest.isSyntaxError(), errorMessage);
}
}

View File

@@ -1,30 +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.filtermanagement;
import java.util.Arrays;
/**
*
* Available token details.
*
*
*
*/
public class TokenDescription {
/** Literal token values. */
private static final String[] TOKEN_IMAGE = { "<EOF>", "\" \"", "\"\\t\"", "<ALPHA>", "<UNRESERVED_STR>",
"<SINGLE_QUOTED_STR>", "<DOUBLE_QUOTED_STR>", "<AND>", "<OR>", "\"(\"", "\")\"", "<==>|<!=>", ">=|<=", };
public String[] getTokenImage() {
return Arrays.copyOf(TOKEN_IMAGE, TOKEN_IMAGE.length);
}
}

View File

@@ -1,73 +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.filtermanagement;
import java.util.ArrayList;
import java.util.List;
/**
* Query validation result with expected token on error.
*
*
*
*/
public class ValidationResult {
private List<String> expectedTokens = new ArrayList<>();
private String message;
private Boolean isValidationFailed = Boolean.FALSE;
/**
* @return the isValidationFailed
*/
public Boolean getIsValidationFailed() {
return isValidationFailed;
}
/**
* @param isValidationFailed
* the isValidationFailed to set
*/
public void setIsValidationFailed(final Boolean isValidationFailed) {
this.isValidationFailed = isValidationFailed;
}
/**
* @return the expectedTokens
*/
public List<String> getExpectedTokens() {
return expectedTokens;
}
/**
* @param expectedTokens
* the expectedTokens to set
*/
public void setExpectedTokens(final List<String> expectedTokens) {
this.expectedTokens = expectedTokens;
}
/**
* @return the message
*/
public String getMessage() {
return message;
}
/**
* @param message
* the message to set
*/
public void setMessage(final String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,141 @@
/**
* 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.filtermanagement.client;
import java.util.List;
import org.eclipse.hawkbit.ui.filtermanagement.TextFieldSuggestionBox;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.MenuItem;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.client.ui.VOverlay;
import com.vaadin.client.ui.VTextField;
import com.vaadin.shared.ui.Connect;
/**
* Connector for the AutoCompleteTextField which automatically listens to
* key-events to show pop-up panel with entered suggestions based on the
* {@link TextFieldSuggestionBoxServerRpc} call.
*
*/
@SuppressWarnings({ "deprecation", "squid:CallToDeprecatedMethod" })
// need to use VOverlay because otherwise it's not in the correct theme
// widget @see com.vaadin.client.ui.VOverlay.getOverlayContainer()
@Connect(TextFieldSuggestionBox.class)
public class AutoCompleteTextFieldConnector extends AbstractExtensionConnector {
private static final long serialVersionUID = 1L;
private final transient SuggestionsSelectList select = new SuggestionsSelectList();
private transient VTextField textFieldWidget;
private final TextFieldSuggestionBoxServerRpc rpc = getRpcProxy(TextFieldSuggestionBoxServerRpc.class);
private final transient VOverlay panel = new VOverlay(true, false, true);
@Override
protected void init() {
super.init();
registerRpc(TextFieldSuggestionBoxClientRpc.class, new TextFieldSuggestionBoxClientRpc() {
private static final long serialVersionUID = 1L;
@Override
public void showSuggestions(final SuggestionContextDto suggestContext) {
select.clearItems();
if (suggestContext == null) {
panel.hide();
return;
}
final List<SuggestTokenDto> suggestions = suggestContext.getSuggestions();
if (suggestions != null && !suggestions.isEmpty()) {
select.addItems(suggestions, textFieldWidget, panel, rpc);
panel.showRelativeTo(textFieldWidget);
select.moveSelectionDown();
return;
}
panel.hide();
}
});
}
@Override
protected void extend(final ServerConnector target) {
textFieldWidget = (VTextField) ((ComponentConnector) target).getWidget();
textFieldWidget.setImmediate(true);
textFieldWidget.textChangeEventMode = "EAGER";
panel.setWidget(select);
panel.setStyleName("suggestion-popup");
panel.setOwner(textFieldWidget);
textFieldWidget.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(final KeyUpEvent event) {
if (panel.isAttached()) {
handlePanelEventDelegation(event);
} else if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
rpc.executeQuery(textFieldWidget.getValue(), textFieldWidget.getCursorPos());
} else {
doAskForSuggestion();
}
}
});
}
private void handlePanelEventDelegation(final KeyUpEvent event) {
switch (event.getNativeKeyCode()) {
case KeyCodes.KEY_DOWN:
arrowKeyDown(event);
break;
case KeyCodes.KEY_UP:
arrorKeyUp(event);
break;
case KeyCodes.KEY_ESCAPE:
escapeKey();
break;
case KeyCodes.KEY_ENTER:
enterKey();
break;
default:
doAskForSuggestion();
}
}
private void escapeKey() {
panel.hide();
}
private void enterKey() {
final MenuItem item = select.getSelectedItem();
if (item != null) {
item.getScheduledCommand().execute();
}
}
private void arrorKeyUp(final KeyUpEvent event) {
select.moveSelectionUp();
event.preventDefault();
event.stopPropagation();
}
private void arrowKeyDown(final KeyUpEvent event) {
select.moveSelectionDown();
event.preventDefault();
event.stopPropagation();
}
private void doAskForSuggestion() {
rpc.suggest(textFieldWidget.getValue(), textFieldWidget.getCursorPos());
}
}

View File

@@ -0,0 +1,76 @@
/**
* 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.filtermanagement.client;
import java.io.Serializable;
/**
* A suggestion which contains the start and the end character position of the
* suggested token of the suggestion of the token and the actual suggestion.
*/
public class SuggestTokenDto implements Serializable {
private static final long serialVersionUID = 1L;
private int start;
private int end;
private String suggestion;
/**
* Default constructor.
*/
public SuggestTokenDto() {
// necessary for java serialization with GWT.
}
/**
* Constructor.
*
* @param start
* the character position of the start of the token
* @param end
* the character position of the end of the token
* @param suggestion
* the token suggestion
*/
public SuggestTokenDto(final int start, final int end, final String suggestion) {
this.start = start;
this.end = end;
this.suggestion = suggestion;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
public String getSuggestion() {
return suggestion;
}
public void setStart(final int start) {
this.start = start;
}
public void setEnd(final int end) {
this.end = end;
}
public void setSuggestion(final String suggestion) {
this.suggestion = suggestion;
}
@Override
public String toString() {
return "SuggestTokenDto [start=" + start + ", end=" + end + ", suggestion=" + suggestion + "]";
}
}

View File

@@ -0,0 +1,63 @@
/**
* 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.filtermanagement.client;
import java.io.Serializable;
import java.util.List;
public class SuggestionContextDto implements Serializable {
private static final long serialVersionUID = 1L;
private int cursorPosition;
private List<SuggestTokenDto> suggestions;
/**
* Default constructor.
*/
public SuggestionContextDto() {
// necessary for java serialization with GWT.
}
/**
* Constructor.
*
* @param rsqlQuery
* the original RSQL based query the suggestions based on
* @param cursorPosition
* the current cursor position
* @param suggestions
* the suggestions for the current cursor position
*/
public SuggestionContextDto(final int cursorPosition, final List<SuggestTokenDto> suggestions) {
this.cursorPosition = cursorPosition;
this.suggestions = suggestions;
}
public List<SuggestTokenDto> getSuggestions() {
return suggestions;
}
public int getCursorPosition() {
return cursorPosition;
}
public void setCursorPosition(final int cursorPosition) {
this.cursorPosition = cursorPosition;
}
public void setSuggestions(final List<SuggestTokenDto> suggestions) {
this.suggestions = suggestions;
}
@Override
public String toString() {
return "SuggestionContextDto [cursorPosition=" + cursorPosition + ", suggestions=" + suggestions + "]";
}
}

View File

@@ -0,0 +1,116 @@
/**
* 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.filtermanagement.client;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.ui.VTextField;
/**
* The suggestion list within the suggestion pop-up panel.
*/
public class SuggestionsSelectList extends MenuBar {
public static final String CLASSNAME = "autocomplete";
private final Map<String, TokenStartEnd> tokenMap = new HashMap<>();
/**
* Constructor.
*/
public SuggestionsSelectList() {
super(true);
setFocusOnHoverEnabled(false);
}
/**
* Adds suggestions to the suggestion menu bar.
*
* @param suggestions
* the suggestions to be added
* @param textFieldWidget
* the text field which the suggestion is attached to to bring
* back the focus after selection
* @param popupPanel
* pop-up panel where the menu bar is shown to hide it after
* selection
* @param suggestionServerRpc
* server RPC to ask for new suggestion after a selection
*/
public void addItems(final List<SuggestTokenDto> suggestions, final VTextField textFieldWidget,
final PopupPanel popupPanel, final TextFieldSuggestionBoxServerRpc suggestionServerRpc) {
for (int index = 0; index < suggestions.size(); index++) {
final SuggestTokenDto suggestToken = suggestions.get(index);
final MenuItem mi = new MenuItem(suggestToken.getSuggestion(), true, new ScheduledCommand() {
@Override
public void execute() {
final String tmpSuggestion = suggestToken.getSuggestion();
final TokenStartEnd tokenStartEnd = tokenMap.get(tmpSuggestion);
final String text = textFieldWidget.getValue();
final StringBuilder builder = new StringBuilder(text);
builder.replace(tokenStartEnd.getStart(), tokenStartEnd.getEnd() + 1, tmpSuggestion);
textFieldWidget.setValue(builder.toString(), true);
popupPanel.hide();
textFieldWidget.setFocus(true);
suggestionServerRpc.suggest(builder.toString(), textFieldWidget.getCursorPos());
}
});
tokenMap.put(suggestToken.getSuggestion(),
new TokenStartEnd(suggestToken.getStart(), suggestToken.getEnd()));
Roles.getListitemRole().set(mi.getElement());
WidgetUtil.sinkOnloadForImages(mi.getElement());
addItem(mi);
}
}
@Override
public void setStyleName(final String style) {
super.setStyleName(style + "-" + CLASSNAME);
}
@Override
public MenuItem getSelectedItem() {
return super.getSelectedItem();
}
/**
* Suggestion Token start and end index.
*
*/
public static final class TokenStartEnd {
final int start;
final int end;
/**
* Constructor.
*
* @param start
* @param end
*/
public TokenStartEnd(final int start, final int end) {
this.start = start;
this.end = end;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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.filtermanagement.client;
import com.vaadin.shared.communication.ClientRpc;
/**
* Client RPC for the AutocompleteTextField. The Client RPC interface is used to
* make server to client calls in Vaadin. Only void methods are allowed in
* ClientRpc calls.
*
*/
@FunctionalInterface
public interface TextFieldSuggestionBoxClientRpc extends ClientRpc {
/**
* Notifies the client about showing the given suggestions in the suggestion
* box.
*
* @param suggestionContext
* the suggestion context which contains all informations about
* showing suggestions
*/
void showSuggestions(final SuggestionContextDto suggestionContext);
}

View File

@@ -0,0 +1,44 @@
/**
* 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.filtermanagement.client;
import com.vaadin.shared.communication.ServerRpc;
/**
* Server RPC for the AutoCompleteTextField. The Server RPC interface is used to
* make client to server calls in Vaadin. Only void methods are allowed in
* ServerRpc calls.
*/
public interface TextFieldSuggestionBoxServerRpc extends ServerRpc {
/**
* Parses the given RSQL based query and try finding suggestions at the
* current given cursor position. When suggestions are possible the
* {@link TextFieldSuggestionBoxClientRpc#showSuggestions(org.eclipse.hawkbit.rsql.SuggestionContext)}
* is called as a callback mechanism back to the client.
*
* @param text
* the current entered text e.g. in a text field to retrieve
* suggestion for
* @param cursor
* the current cursor position
*/
void suggest(final String text, final int cursor);
/**
* Executes the query text to get the filtered data.
*
* @param text
* the current entered text e.g. in a text field to retrieve
* suggestion for
* @param cursor
* the current cursor position
*/
void executeQuery(final String text, final int cursor);
}

View File

@@ -8,9 +8,8 @@
*/
package org.eclipse.hawkbit.ui.management.dstable;
import java.util.HashMap;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.PostConstruct;
@@ -178,10 +177,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
* @return
*/
private LazyQueryContainer getDistSetTypeLazyQueryContainer() {
final Map<String, Object> queryConfig = new HashMap<>();
final BeanQueryFactory<DistributionSetTypeBeanQuery> dtQF = new BeanQueryFactory<>(
DistributionSetTypeBeanQuery.class);
dtQF.setQueryConfiguration(queryConfig);
dtQF.setQueryConfiguration(Collections.emptyMap());
final LazyQueryContainer disttypeContainer = new LazyQueryContainer(
new LazyQueryDefinition(true, SPUIDefinitions.DIST_TYPE_SIZE, SPUILabelDefinitions.VAR_NAME), dtQF);

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.management.dstable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -43,11 +42,11 @@ import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -56,6 +55,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -240,7 +240,7 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(4);
managementUIState.getDistributionTableFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
managementUIState.getDistributionTableFilters().getPinnedTargetId()
@@ -525,6 +525,10 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
}
private void styleDistributionTableOnPinning() {
if (!managementUIState.getDistributionTableFilters().getPinnedTargetId().isPresent()) {
return;
}
final Target targetObj = targetService.findTargetByControllerIDWithDetails(
managementUIState.getDistributionTableFilters().getPinnedTargetId().get());

View File

@@ -8,8 +8,7 @@
*/
package org.eclipse.hawkbit.ui.management.dstag;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
@@ -101,9 +100,8 @@ public class DistributionTagButtons extends AbstractFilterButtons {
@Override
protected LazyQueryContainer createButtonsLazyQueryContainer() {
final Map<String, Object> queryConfig = new HashMap<>();
final BeanQueryFactory<DistributionTagBeanQuery> tagQF = new BeanQueryFactory<>(DistributionTagBeanQuery.class);
tagQF.setQueryConfiguration(queryConfig);
tagQF.setQueryConfiguration(Collections.emptyMap());
return HawkbitCommonUtil.createDSLazyQueryContainer(
new BeanQueryFactory<DistributionTagBeanQuery>(DistributionTagBeanQuery.class));

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.management.event;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -17,6 +16,7 @@ import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import com.google.common.collect.Maps;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Component;
@@ -67,7 +67,7 @@ public class ManagementViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, List<String>> createDropConfigurations() {
final Map<String, List<String>> config = new HashMap<>();
final Map<String, List<String>> config = Maps.newHashMapWithExpectedSize(6);
// Delete drop area acceptable components
config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID,
@@ -94,7 +94,7 @@ public class ManagementViewAcceptCriteria extends AbstractAcceptCriteria {
}
private static Map<String, Object> createDropHintConfigurations() {
final Map<String, Object> config = new HashMap<>();
final Map<String, Object> config = Maps.newHashMapWithExpectedSize(4);
config.put(SPUIDefinitions.TARGET_TAG_ID_PREFIXS, DragEvent.TARGET_TAG_DRAG);
config.put(UIComponentIdProvider.TARGET_TABLE_ID, DragEvent.TARGET_DRAG);
config.put(UIComponentIdProvider.DIST_TABLE_ID, DragEvent.DISTRIBUTION_DRAG);

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.management.footer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -39,6 +38,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.collect.Maps;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.server.FontAwesome;
@@ -88,7 +88,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin
@Override
protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<>();
final Map<String, ConfirmationTab> tabs = Maps.newHashMapWithExpectedSize(3);
if (!managementUIState.getDeletedDistributionList().isEmpty()) {
tabs.put(i18n.get("caption.delete.dist.accordion.tab"), createDeletedDistributionTab());
}
@@ -150,7 +150,7 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin
? actionTypeOptionGroupLayout.getForcedTimeDateField().getValue().getTime()
: RepositoryModelConstants.NO_FORCE_TIME;
final Map<Long, ArrayList<TargetIdName>> saveAssignedList = new HashMap<>();
final Map<Long, ArrayList<TargetIdName>> saveAssignedList = Maps.newHashMapWithExpectedSize(itemIds.size());
int successAssignmentCount = 0;
int duplicateAssignmentCount = 0;

View File

@@ -87,10 +87,9 @@ public class ManagementUIState implements ManagmentEntityState<DistributionSetId
private boolean customFilterSelected;
private boolean bulkUploadWindowMinimised;
private DistributionSetIdName lastSelectedDistribution;
/**
* @return the lastSelectedDistribution
*/
@@ -98,12 +97,10 @@ public class ManagementUIState implements ManagmentEntityState<DistributionSetId
return Optional.ofNullable(lastSelectedDistribution);
}
public void setLastSelectedDistribution(final DistributionSetIdName value) {
this.lastSelectedDistribution = value;
}
/**
* @return the bulkUploadWindowMinimised
*/

View File

@@ -9,12 +9,9 @@
package org.eclipse.hawkbit.ui.management.targettable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.ui.UiProperties;
@@ -40,6 +37,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventBus;
import org.vaadin.tokenfield.TokenField;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.combobox.FilteringMode;
@@ -112,12 +110,6 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
buildLayout();
setImmediate(true);
setCompositionRoot(mainLayout);
eventBus.subscribe(this);
}
@PreDestroy
void destroy() {
eventBus.unsubscribe(this);
}
protected void onStartOfUpload() {
@@ -242,7 +234,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
*/
private Container createContainer() {
final Map<String, Object> queryConfiguration = new HashMap<>();
final Map<String, Object> queryConfiguration = Maps.newHashMapWithExpectedSize(2);
final List<String> list = new ArrayList<>();
queryConfiguration.put(SPUIDefinitions.FILTER_BY_NO_TAG,

View File

@@ -19,10 +19,10 @@ import static org.eclipse.hawkbit.ui.management.event.TargetFilterEvent.REMOVE_F
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -43,12 +43,6 @@ import org.eclipse.hawkbit.ui.common.ManagmentEntityState;
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
import org.eclipse.hawkbit.ui.common.table.AbstractTable;
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
import org.eclipse.hawkbit.ui.filter.Filters;
import org.eclipse.hawkbit.ui.filter.target.CustomTargetFilter;
import org.eclipse.hawkbit.ui.filter.target.TargetSearchTextFilter;
import org.eclipse.hawkbit.ui.filter.target.TargetStatusFilter;
import org.eclipse.hawkbit.ui.filter.target.TargetTagFilter;
import org.eclipse.hawkbit.ui.management.event.DragEvent;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.ManagementViewAcceptCriteria;
@@ -78,6 +72,7 @@ import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -140,11 +135,14 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
if (TargetCreatedEvent.class.isInstance(firstEvent)) {
onTargetCreatedEvents();
} else if (TargetInfoUpdateEvent.class.isInstance(firstEvent)) {
onTargetInfoUpdateEvents((List<TargetInfoUpdateEvent>) events);
onTargetUpdateEvents(((List<TargetInfoUpdateEvent>) events).stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity().getTarget())
.collect(Collectors.toList()));
} else if (TargetDeletedEvent.class.isInstance(firstEvent)) {
onTargetDeletedEvent((List<TargetDeletedEvent>) events);
} else if (TargetUpdatedEvent.class.isInstance(firstEvent)) {
onTargetUpdateEvents((List<TargetUpdatedEvent>) events);
onTargetUpdateEvents(((List<TargetUpdatedEvent>) events).stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity()).collect(Collectors.toList()));
}
}
@@ -348,7 +346,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
}
private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>();
final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(7);
managementUIState.getTargetTableFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
managementUIState.getTargetTableFilters().getDistributionSet()
@@ -746,16 +744,17 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
}
@SuppressWarnings("unchecked")
private void updateVisibleItemOnEvent(final TargetInfo targetInfo, final Target target,
final TargetIdName targetIdName) {
private void updateVisibleItemOnEvent(final TargetInfo targetInfo) {
final Target target = targetInfo.getTarget();
final TargetIdName targetIdName = target.getTargetIdName();
final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource();
final Item item = targetContainer.getItem(targetIdName);
item.getItemProperty(SPUILabelDefinitions.VAR_NAME).setValue(target.getName());
if (targetInfo != null) {
item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP)
.setValue(HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n));
item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus());
}
item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP)
.setValue(HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n));
item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus());
}
private boolean isLastSelectedTarget(final TargetIdName targetIdName) {
@@ -767,62 +766,30 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
* EventListener method which is called by the event bus to notify about a
* list of {@link TargetInfoUpdateEvent}.
*
* @param targetInfoUpdateEvents
* list of target info update event
* @param updatedTargets
* list of updated targets
*/
private void onTargetInfoUpdateEvents(final List<TargetInfoUpdateEvent> targetInfoUpdateEvents) {
private void onTargetUpdateEvents(final List<Target> updatedTargets) {
@SuppressWarnings("unchecked")
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shoulTargetsUpdated = false;
Target lastSelectedTarget = null;
for (final TargetInfoUpdateEvent targetInfoUpdateEvent : targetInfoUpdateEvents) {
final TargetInfo targetInfo = targetInfoUpdateEvent.getEntity();
final Target target = targetInfo.getTarget();
final TargetIdName targetIdName = target.getTargetIdName();
if (Filters.or(getTargetTableFilters(target)).doFilter()) {
shoulTargetsUpdated = true;
} else {
if (visibleItemIds.contains(targetIdName)) {
updateVisibleItemOnEvent(targetInfo, target, targetIdName);
}
}
// workaround until push is available for action history, re-select
// the updated target so the action history gets refreshed.
if (isLastSelectedTarget(targetIdName)) {
lastSelectedTarget = target;
}
}
if (shoulTargetsUpdated) {
refreshTargets();
}
if (lastSelectedTarget != null) {
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, lastSelectedTarget));
}
}
private void onTargetUpdateEvents(final List<TargetUpdatedEvent> events) {
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shoulTargetsUpdated = false;
Target lastSelectedTarget = null;
for (final TargetUpdatedEvent targetUpdatedEvent : events) {
final Target target = targetUpdatedEvent.getEntity();
final TargetIdName targetIdName = target.getTargetIdName();
if (Filters.or(getTargetTableFilters(target)).doFilter()) {
shoulTargetsUpdated = true;
} else {
if (visibleItemIds.contains(targetIdName)) {
updateVisibleItemOnEvent(null, target, targetIdName);
}
}
if (isLastSelectedTarget(targetIdName)) {
lastSelectedTarget = target;
}
}
if (shoulTargetsUpdated) {
if (isFilterEnabled()) {
LOG.debug("Filter enabled on UI {}. Refresh targets from database.", getUI().getUIId());
refreshTargets();
} else {
updatedTargets.stream().filter(target -> visibleItemIds.contains(target.getTargetIdName()))
.forEach(target -> updateVisibleItemOnEvent(target.getTargetInfo()));
}
if (lastSelectedTarget != null) {
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, lastSelectedTarget));
// workaround until push is available for action
// history, re-select
// the updated target so the action history gets
// refreshed.
final Optional<Target> selected = updatedTargets.stream()
.filter(target -> isLastSelectedTarget(target.getTargetIdName())).findAny();
if (selected.isPresent()) {
LOG.debug("Selected element has changed on UI {}. Reselect to update action history.", getUI().getUIId());
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, selected.get()));
}
}
@@ -830,17 +797,11 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
refreshTargets();
}
private List<FilterExpression> getTargetTableFilters(final Target target) {
private boolean isFilterEnabled() {
final TargetTableFilters targetTableFilters = managementUIState.getTargetTableFilters();
final List<FilterExpression> filters = new ArrayList<>();
if (targetTableFilters.getSearchText().isPresent()) {
filters.add(new TargetSearchTextFilter(target, targetTableFilters.getSearchText().get()));
}
filters.add(new TargetStatusFilter(targetTableFilters.getClickedStatusTargetTags()));
filters.add(new TargetTagFilter(target, targetTableFilters.getClickedTargetTags(),
targetTableFilters.isNoTagSelected()));
filters.add(new CustomTargetFilter(targetTableFilters.getTargetFilterQuery()));
return filters;
return targetTableFilters.getSearchText().isPresent() || !targetTableFilters.getClickedTargetTags().isEmpty()
|| !targetTableFilters.getClickedStatusTargetTags().isEmpty()
|| targetTableFilters.getTargetFilterQuery().isPresent();
}
/**

View File

@@ -9,9 +9,8 @@
package org.eclipse.hawkbit.ui.management.targettag;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.annotation.PreDestroy;
@@ -102,8 +101,7 @@ public class TargetFilterQueryButtons extends Table {
protected LazyQueryContainer createButtonsLazyQueryContainer() {
final BeanQueryFactory<TargetFilterBeanQuery> queryFactory = new BeanQueryFactory<>(
TargetFilterBeanQuery.class);
final Map<String, Object> queryConfig = new HashMap<>();
queryFactory.setQueryConfiguration(queryConfig);
queryFactory.setQueryConfiguration(Collections.emptyMap());
return new LazyQueryContainer(new LazyQueryDefinition(true, 20, "id"), queryFactory);
}

View File

@@ -296,7 +296,7 @@ public final class DashboardMenu extends CustomComponent {
final Optional<DashboardMenuItem> findFirst = dashboardVaadinViews.stream()
.filter(view -> view.getViewName().equals(viewName)).findFirst();
if (findFirst == null || !findFirst.isPresent()) {
if (!findFirst.isPresent()) {
return null;
}

View File

@@ -8,11 +8,11 @@
*/
package org.eclipse.hawkbit.ui.push;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.slf4j.Logger;
@@ -57,10 +58,11 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
private static final Logger LOG = LoggerFactory.getLogger(DelayedEventBusPushStrategy.class);
private static final int BLOCK_SIZE = 10_000;
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private final BlockingDeque<org.eclipse.hawkbit.eventbus.event.Event> queue = new LinkedBlockingDeque<>(BLOCK_SIZE);
private final ScheduledExecutorService executorService;
private final BlockingDeque<Event> queue = new LinkedBlockingDeque<>(BLOCK_SIZE);
private final EventBus.SessionEventBus eventBus;
private final com.google.common.eventbus.EventBus systemEventBus;
private int uiid = -1;
private ScheduledFuture<?> jobHandle;
@@ -68,15 +70,20 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
/**
* Constructor.
*
*
* @param executorService
* for scheduled execution of event forwarding to the UI
* @param eventBus
* the session event bus to where the events should be dispatched
* @param systemEventBus
* the system event bus where to retrieve the events from the
* back-end
* @param eventProvider
* for event delegation to UI
*/
public DelayedEventBusPushStrategy(final SessionEventBus eventBus,
public DelayedEventBusPushStrategy(final ScheduledExecutorService executorService, final SessionEventBus eventBus,
final com.google.common.eventbus.EventBus systemEventBus, final UIEventProvider eventProvider) {
this.executorService = executorService;
this.eventBus = eventBus;
this.systemEventBus = systemEventBus;
this.eventProvider = eventProvider;
@@ -92,7 +99,7 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
*/
@Subscribe
@AllowConcurrentEvents
public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) {
public void dispatch(final Event event) {
// to dispatch too many events which are not interested on the UI
if (!isEventProvided(event)) {
LOG.trace("Event is not supported in the UI!!! Dropped event is {}", event);
@@ -100,19 +107,24 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
}
if (!queue.offer(event)) {
LOG.warn("Deque limit is reached, cannot add more events!!! Dropped event is {}", event);
LOG.trace("Deque limit is reached, cannot add more events for UI {}! Dropped event is {}", uiid, event);
return;
}
}
private boolean isEventProvided(final org.eclipse.hawkbit.eventbus.event.Event event) {
private boolean isEventProvided(final Event event) {
return eventProvider.getSingleEvents().contains(event.getClass())
|| eventProvider.getBulkEvents().contains(event.getClass());
}
@Override
public void init(final UI vaadinUI) {
LOG.debug("Initialize delayed event push strategy");
uiid = vaadinUI.getUIId();
LOG.info("Initialize delayed event push strategy for UI {}", uiid);
if (vaadinUI.getSession() == null) {
LOG.error("Vaadin session of UI {} is null! Event push disabled!", uiid);
}
jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()), 500,
2000, TimeUnit.MILLISECONDS);
systemEventBus.register(this);
@@ -120,10 +132,9 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
@Override
public void clean() {
LOG.debug("Cleanup resources");
jobHandle.cancel(true);
LOG.info("Cleanup delayed event push strategy for UI", uiid);
systemEventBus.unregister(this);
executorService.shutdownNow();
jobHandle.cancel(true);
queue.clear();
}
@@ -138,8 +149,7 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
* @return {@code true} if the event can be dispatched to the UI otherwise
* {@code false}
*/
protected boolean eventSecurityCheck(final SecurityContext userContext,
final org.eclipse.hawkbit.eventbus.event.Event event) {
protected static boolean eventSecurityCheck(final SecurityContext userContext, final Event event) {
if (userContext == null || userContext.getAuthentication() == null) {
return false;
}
@@ -163,43 +173,39 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
@Override
public void run() {
LOG.debug("UI EventBus aggregator started");
LOG.debug("UI EventBus aggregator started for UI {}", vaadinUI.getUIId());
final long timestamp = System.currentTimeMillis();
final List<org.eclipse.hawkbit.eventbus.event.Event> events = new LinkedList<>();
for (int i = 0; i < BLOCK_SIZE; i++) {
final org.eclipse.hawkbit.eventbus.event.Event pollEvent = queue.poll();
if (pollEvent == null) {
continue;
}
events.add(pollEvent);
final int size = queue.size();
if (size <= 0) {
LOG.debug("UI EventBus aggregator for UI {} has nothing to do.", vaadinUI.getUIId());
return;
}
final List<Event> events = new ArrayList<>(size);
final int eventsSize = queue.drainTo(events);
if (events.isEmpty()) {
LOG.debug("UI EventBus aggregator for UI {} has nothing to do.", vaadinUI.getUIId());
return;
}
if (vaadinSession == null) {
return;
}
LOG.debug("UI EventBus aggregator session: {}", vaadinSession);
final WrappedSession wrappedSession = vaadinSession.getSession();
if (wrappedSession == null) {
return;
}
final int eventsSize = events.size();
LOG.debug("UI EventBus aggregator dispatches {} events for session {} for UI {}", eventsSize, vaadinSession,
vaadinUI.getUIId());
doDispatch(events, wrappedSession);
LOG.debug("UI EventBus aggregator done with sending {} events in {} ms", eventsSize,
System.currentTimeMillis() - timestamp);
LOG.debug("UI EventBus aggregator done with sending {} events in {} ms for UI {}", eventsSize,
System.currentTimeMillis() - timestamp, vaadinUI.getUIId());
}
private void doDispatch(final List<org.eclipse.hawkbit.eventbus.event.Event> events,
final WrappedSession wrappedSession) {
private void doDispatch(final List<Event> events, final WrappedSession wrappedSession) {
final SecurityContext userContext = (SecurityContext) wrappedSession
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
final SecurityContext oldContext = SecurityContextHolder.getContext();
@@ -210,25 +216,24 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
if (vaadinSession.getState() != State.OPEN) {
return;
}
LOG.debug("UI EventBus aggregator of UI {} got lock on session.", vaadinUI.getUIId());
fowardSingleEvents(events, userContext);
fowardBulkEvents(events, userContext);
});
LOG.debug("UI EventBus aggregator of UI {} left lock on session.", vaadinUI.getUIId());
}).get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Wait for Vaadin session for UI {} interrupted!", vaadinUI.getUIId(), e);
} finally {
SecurityContextHolder.setContext(oldContext);
}
}
private void fowardBulkEvents(final List<org.eclipse.hawkbit.eventbus.event.Event> events,
final SecurityContext userContext) {
private void fowardBulkEvents(final List<Event> events, final SecurityContext userContext) {
final Set<Class<?>> filterBulkEvenTypes = eventProvider.getFilteredBulkEventsType(events);
publishBulkEvent(events, userContext, filterBulkEvenTypes);
}
private void publishBulkEvent(final List<org.eclipse.hawkbit.eventbus.event.Event> events,
final SecurityContext userContext, final Set<Class<?>> filterBulkEvenTypes) {
for (final Class<?> bulkType : filterBulkEvenTypes) {
final List<org.eclipse.hawkbit.eventbus.event.Event> listBulkEvents = events.stream()
.filter(event -> DelayedEventBusPushStrategy.this.eventSecurityCheck(userContext, event)
final List<Event> listBulkEvents = events.stream()
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event)
&& bulkType.isInstance(event))
.collect(Collectors.toList());
if (!listBulkEvents.isEmpty()) {
@@ -237,10 +242,9 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
}
}
private void fowardSingleEvents(final List<org.eclipse.hawkbit.eventbus.event.Event> events,
final SecurityContext userContext) {
private void fowardSingleEvents(final List<Event> events, final SecurityContext userContext) {
events.stream()
.filter(event -> DelayedEventBusPushStrategy.this.eventSecurityCheck(userContext, event)
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event)
&& eventProvider.getSingleEvents().contains(event.getClass()))
.forEach(event -> eventBus.publish(vaadinUI, event));
}

View File

@@ -43,10 +43,10 @@ import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -610,26 +610,15 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
@Override
public void validate(final Object value) {
try {
if (isNoOfGroupsOrTargetFilterEmpty()) {
uiNotification
.displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing"));
} else {
if (value != null) {
final int groupSize = getGroupSize();
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0,
groupSize).validate(Integer.valueOf(value.toString()));
}
if (isNoOfGroupsOrTargetFilterEmpty()) {
uiNotification.displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing"));
} else {
if (value != null) {
final int groupSize = getGroupSize();
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize)
.validate(Integer.valueOf(value.toString()));
}
}
// suppress the need of preserve original exception, will blow
// up the
// log and not necessary here
catch (final InvalidValueException ex) {
// we have to throw the exception here, otherwise the UI won't
// show the vaadin validation error!
throw ex;
}
}
private boolean isNoOfGroupsOrTargetFilterEmpty() {
@@ -648,19 +637,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
@Override
public void validate(final Object value) {
try {
if (value != null) {
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
.validate(Integer.valueOf(value.toString()));
}
}
// suppress the need of preserve original exception, will blow
// up the
// log and not necessary here
catch (final InvalidValueException ex) {
// we have to throw the exception here, otherwise the UI won't
// show the vaadin validation error!
throw ex;
if (value != null) {
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
.validate(Integer.valueOf(value.toString()));
}
}
}
@@ -670,19 +649,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
@Override
public void validate(final Object value) {
try {
if (value != null) {
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
.validate(Integer.valueOf(value.toString()));
}
}
// suppress the need of preserve original exception, will blow
// up the
// log and not necessary here
catch (final InvalidValueException ex) {
// we have to throw the exception here, otherwise the UI won't
// show the vaadin validation error!
throw ex;
if (value != null) {
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
.validate(Integer.valueOf(value.toString()));
}
}
}

View File

@@ -21,7 +21,6 @@ import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_TOTAL_TARGET
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -57,6 +56,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.converter.Converter;
@@ -495,7 +495,8 @@ public class RolloutListGrid extends AbstractGrid {
* Contains all expected rollout status per column to enable or disable
* the button.
*/
private static final Map<String, RolloutStatus> EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON = new HashMap<>();
private static final Map<String, RolloutStatus> EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON = Maps
.newHashMapWithExpectedSize(2);
private final Container.Indexed containerDataSource;
static {

View File

@@ -9,8 +9,8 @@
package org.eclipse.hawkbit.ui.utils;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
@@ -435,8 +435,7 @@ public final class HawkbitCommonUtil {
*/
public static LazyQueryContainer createLazyQueryContainer(
final BeanQueryFactory<? extends AbstractBeanQuery<?>> queryFactory) {
final Map<String, Object> queryConfig = new HashMap<>();
queryFactory.setQueryConfiguration(queryConfig);
queryFactory.setQueryConfiguration(Collections.emptyMap());
return new LazyQueryContainer(new LazyQueryDefinition(true, 20, SPUILabelDefinitions.VAR_NAME), queryFactory);
}
@@ -448,8 +447,7 @@ public final class HawkbitCommonUtil {
*/
public static LazyQueryContainer createDSLazyQueryContainer(
final BeanQueryFactory<? extends AbstractBeanQuery<?>> queryFactory) {
final Map<String, Object> queryConfig = new HashMap<>();
queryFactory.setQueryConfiguration(queryConfig);
queryFactory.setQueryConfiguration(Collections.emptyMap());
return new LazyQueryContainer(new LazyQueryDefinition(true, 20, "tagIdName"), queryFactory);
}

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.utils;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
@@ -19,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import com.google.common.collect.Maps;
import com.vaadin.server.WebBrowser;
/**
@@ -32,7 +32,7 @@ import com.vaadin.server.WebBrowser;
public final class SPDateTimeUtil {
private static final String DURATION_FORMAT = "y','M','d','H','m','s";
private static final Map<Integer, CalendarI18N> DURATION_I18N = new HashMap<>();
private static final Map<Integer, CalendarI18N> DURATION_I18N = Maps.newHashMapWithExpectedSize(6);
static {
DURATION_I18N.put(0, CalendarI18N.YEAR);

View File

@@ -876,6 +876,10 @@ public final class UIComponentIdProvider {
* ID for download anonymous checkbox
*/
public static final String DOWNLOAD_ANONYMOUS_CHECKBOX = "downloadanonymouscheckbox";
/**
* Id of custom filter query search Icon.
*/
public static final String FILTER_SEARCH_ICON_ID = "filter.search.icon";
/**
* Distribution set select table id

View File

@@ -8,6 +8,39 @@
*/
@mixin target-filter-query {
.gwt-MenuBar-autocomplete {
cursor: default;
}
.gwt-MenuBar-autocomplete .gwt-MenuItem{
border-radius: 3px !important;
cursor: pointer !important;
font-weight: 400 !important;
line-height: 27px !important;
padding: 0 20px 0 10px !important;
position: relative !important;
white-space: nowrap !important;
}
.gwt-MenuBar-autocomplete .gwt-MenuItem-selected {
background-color: $hawkbit-primary-color;
background-image: linear-gradient(to bottom, #1b87e3 2%, #166ed5 98%) !important;
color: #ecf2f8 !important;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05) !important;
}
.suggestion-popup{
backface-visibility: hidden;
background-color: white;
border-radius: 4px;
box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09);
box-sizing: border-box;
color: #474747;
padding: 4px;
position: relative;
z-index: 1;
}
.caption-header-layout{
padding-left:10px;
}
@@ -23,15 +56,17 @@
.target-filter-textfield, .target-filter-textfield:focus{
border:none !important;
box-shadow: none !important;
height:26px !important;
height: 26px !important;
}
.error-icon{
margin-left: 5px;
color:$success-icon-color !important;
padding-left:2px !important;
}
.success-icon{
margin-left: 5px;
color:$error-icon-color !important;
padding-left:2px !important;
}
@@ -42,10 +77,12 @@
}
.target-filter-spinner{
@include valo-spinner(
$size: $v-font-size--small,
$color: $bosch-color-light-blue
);
margin-top: 5px;
margin-left: 5px;
@include valo-spinner(
$size:16px,
$speed:500ms
);
}
.hide-status-label {