diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml
index 85aa51085..790188f26 100644
--- a/hawkbit-ui/pom.xml
+++ b/hawkbit-ui/pom.xml
@@ -214,10 +214,6 @@
org.vaadin.addons
flexibleoptiongroup
-
- org.vaadin.addons
- tokenfield
-
org.vaadin.alump.distributionbar
dbar-addon
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml
index 4dd1223d2..ad1e153c2 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/AppWidgetSet.gwt.xml
@@ -18,7 +18,7 @@
-
+
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java
index 0aa82ff99..ca77b8dfe 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java
@@ -158,7 +158,7 @@ public abstract class AbstractTableDetailsLayout extends
if (getSelectedBaseEntity() == null) {
return;
}
- getTagsLayout().addComponent(tagToken.getTokenField());
+ getTagsLayout().addComponent(tagToken.getTagPanel());
}
protected void populateLog() {
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java
index c0216d94e..6affcb36d 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java
@@ -9,34 +9,25 @@
package org.eclipse.hawkbit.ui.common.tagdetails;
import java.io.Serializable;
-import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.common.table.BaseUIEntityEvent;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagPanelLayout.TagAssignmentListener;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
-import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
-import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
+import org.springframework.hateoas.Identifiable;
+import org.springframework.util.CollectionUtils;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBus.UIEventBus;
-import org.vaadin.tokenfield.TokenField;
-import org.vaadin.tokenfield.TokenField.InsertPosition;
-import com.vaadin.data.Container;
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.data.util.IndexedContainer;
-import com.vaadin.server.FontAwesome;
-import com.vaadin.shared.ui.combobox.FilteringMode;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.CssLayout;
import com.vaadin.ui.UI;
-import com.vaadin.ui.themes.ValoTheme;
/**
* Abstract class for target/ds tag token layout.
@@ -44,25 +35,16 @@ import com.vaadin.ui.themes.ValoTheme;
* @param
* the special entity
*/
-public abstract class AbstractTagToken implements Serializable {
+public abstract class AbstractTagToken implements Serializable, TagAssignmentListener {
- private static final String ID_PROPERTY = "id";
- private static final String NAME_PROPERTY = "name";
- private static final String COLOR_PROPERTY = "color";
-
- protected static final int MAX_TAG_QUERY = 500;
+ protected static final int MAX_TAG_QUERY = 1000;
private static final long serialVersionUID = 6599386705285184783L;
- protected TokenField tokenField;
+ protected TagPanelLayout tagPanelLayout;
- protected IndexedContainer container;
-
- protected final transient Map tagDetails = new ConcurrentHashMap<>();
-
- protected final transient Map tokensAdded = new HashMap<>();
-
- protected CssLayout tokenLayout = new CssLayout();
+ protected final transient Map tagDetailsById = new ConcurrentHashMap<>();
+ protected final transient Map tagDetailsByName = new ConcurrentHashMap<>();
protected SpPermissionChecker checker;
@@ -86,8 +68,7 @@ public abstract class AbstractTagToken implements Serializ
this.uinotification = uinotification;
this.eventBus = eventBus;
this.managementUIState = managementUIState;
- createTokenField();
- checkIfTagAssignedIsAllowed();
+ createTagPanel();
if (doSubscribeToEventBus()) {
eventBus.subscribe(this);
}
@@ -110,267 +91,91 @@ public abstract class AbstractTagToken implements Serializ
final T entity = baseEntityEvent.getEntity();
if (entity != null) {
selectedEntity = entity;
- repopulateToken();
+ repopulateTags();
}
});
}
- private void createTokenField() {
- final Container tokenContainer = createContainer();
- tokenField = createTokenField(tokenContainer);
- tokenField.setContainerDataSource(tokenContainer);
- tokenField.setNewTokensAllowed(false);
- tokenField.setFilteringMode(FilteringMode.CONTAINS);
- tokenField.setInputPrompt(getTokenInputPrompt());
- tokenField.setTokenInsertPosition(InsertPosition.AFTER);
- tokenField.setImmediate(true);
- tokenField.addStyleName(ValoTheme.COMBOBOX_TINY);
- tokenField.setSizeFull();
- tokenField.setTokenCaptionPropertyId(NAME_PROPERTY);
+ private void createTagPanel() {
+ tagPanelLayout = new TagPanelLayout(i18n, !isToggleTagAssignmentAllowed());
+ tagPanelLayout.addTagAssignmentListener(this);
+ tagPanelLayout.setSizeFull();
}
- protected void repopulateToken() {
- populateContainer();
- displayAlreadyAssignedTags();
+ protected void repopulateTags() {
+ tagDetailsById.clear();
+ tagDetailsByName.clear();
+
+ final List allAssignableTags = getAllTags();
+ allAssignableTags.forEach(tagData -> {
+ tagDetailsByName.put(tagData.getName(), tagData);
+ tagDetailsById.put(tagData.getId(), tagData);
+ });
+ tagPanelLayout.initializeTags(allAssignableTags, getAssignedTags());
}
- private Container createContainer() {
- container = new IndexedContainer();
- container.addContainerProperty(NAME_PROPERTY, String.class, "");
- container.addContainerProperty(ID_PROPERTY, Long.class, "");
- container.addContainerProperty(COLOR_PROPERTY, String.class, "");
- return container;
+ protected void tagCreated(final TagData tagData) {
+ tagDetailsByName.put(tagData.getName(), tagData);
+ tagDetailsById.put(tagData.getId(), tagData);
+
+ tagPanelLayout.tagCreated(tagData);
}
- protected void addNewToken(final Long tagId) {
- tokenField.addToken(tagId);
- removeTagAssignedFromCombo(tagId);
- }
+ protected void tagDeleted(final Long id) {
+ final TagData tagData = tagDetailsById.get(id);
+ if (tagData != null) {
+ tagPanelLayout.tagDeleted(tagData);
- private void removeTagAssignedFromCombo(final Long tagId) {
- // might not yet exist or not anymore due to unprocessed events
- final Item item = tokenField.getContainerDataSource().getItem(tagId);
- if (item == null) {
- return;
- }
-
- tokensAdded.put(tagId, new TagData(tagId, getTagName(item), getColor(item)));
- container.removeItem(tagId);
- }
-
- protected void setContainerPropertValues(final Long tagId, final String tagName, final String tagColor) {
- final TagData tagData = tagDetails.putIfAbsent(tagId, new TagData(tagId, tagName, tagColor));
- if (tagData == null) {
- final Item item = container.addItem(tagId);
- if (item == null) {
- return;
- }
-
- item.getItemProperty(ID_PROPERTY).setValue(tagId);
- updateItem(tagName, tagColor, item);
+ tagDetailsByName.remove(tagData.getName());
+ tagDetailsById.remove(id);
}
}
- protected void updateItem(final String tagName, final String tagColor, final Item item) {
- item.getItemProperty(NAME_PROPERTY).setValue(tagName);
- item.getItemProperty(COLOR_PROPERTY).setValue(tagColor);
- }
-
- protected void checkIfTagAssignedIsAllowed() {
- if (!isToggleTagAssignmentAllowed()) {
- tokenField.addStyleName("hideTokenFieldcombo");
+ @Override
+ public void assignTag(final String tagName) {
+ final TagData tagData = tagDetailsByName.get(tagName);
+ if (tagData != null) {
+ assignTag(tagData);
}
}
- private TokenField createTokenField(final Container tokenContainer) {
- return new CustomTokenField(tokenLayout, tokenContainer);
+ @Override
+ public void unassignTag(final String tagName) {
+ final TagData tagData = tagDetailsByName.get(tagName);
+ if (tagData != null) {
+ unassignTag(tagData);
+ }
}
- class CustomTokenField extends TokenField {
- private static final long serialVersionUID = 694216966472937436L;
+ protected abstract void assignTag(TagData tagData);
- Container tokenContainer;
+ protected abstract void unassignTag(TagData tagData);
- CustomTokenField(final CssLayout cssLayout, final Container tokenContainer) {
- super(cssLayout);
- this.tokenContainer = tokenContainer;
- }
-
- @Override
- protected void configureTokenButton(final Object tokenId, final Button button) {
- super.configureTokenButton(tokenId, button);
- updateTokenStyle(tokenId, button);
- button.addStyleName(SPUIDefinitions.TEXT_STYLE + " " + SPUIStyleDefinitions.DETAILS_LAYOUT_STYLE);
- }
-
- @Override
- protected void onTokenInput(final Object tokenId) {
- super.addToken(tokenId);
- onTokenSearch(tokenId);
- }
-
- @Override
- protected void onTokenClick(final Object tokenId) {
- if (isToggleTagAssignmentAllowed()) {
- super.onTokenClick(tokenId);
- tokenClick(tokenId);
+ protected boolean checkAssignmentResult(final List extends Identifiable> assignedEntities,
+ final Long expectedAssignedEntityId) {
+ if (!CollectionUtils.isEmpty(assignedEntities) && expectedAssignedEntityId != null) {
+ final List assignedDsIds = assignedEntities.stream().map(Identifiable::getId)
+ .collect(Collectors.toList());
+ if (assignedDsIds.contains(expectedAssignedEntityId)) {
+ return true;
}
}
-
- private void updateTokenStyle(final Object tokenId, final Button button) {
- final Item item = tokenField.getContainerDataSource().getItem(tokenId);
- if (item == null) {
- return;
- }
-
- final String color = getColor(item);
- button.setCaption("" + FontAwesome.CIRCLE.getHtml()
- + "" + " " + getItemNameProperty(tokenId).getValue().toString().concat(" ×"));
- button.setCaptionAsHtml(true);
- }
-
- private void onTokenSearch(final Object tokenId) {
- assignTag(getItemNameProperty(tokenId).getValue().toString());
- removeTagAssignedFromCombo((Long) tokenId);
- }
-
- private void tokenClick(final Object tokenId) {
- final Item item = tokenField.getContainerDataSource().addItem(tokenId);
- item.getItemProperty(NAME_PROPERTY).setValue(tagDetails.get(tokenId).getName());
- item.getItemProperty(COLOR_PROPERTY).setValue(tagDetails.get(tokenId).getColor());
- unassignTag(tagDetails.get(tokenId).getName());
- }
-
- private Property getItemNameProperty(final Object tokenId) {
- final Item item = tokenField.getContainerDataSource().getItem(tokenId);
- return item.getItemProperty(NAME_PROPERTY);
- }
-
+ return false;
}
- private static String getColor(final Item item) {
- if (item.getItemProperty(COLOR_PROPERTY).getValue() != null) {
- return (String) item.getItemProperty(COLOR_PROPERTY).getValue();
- } else {
- return SPUIDefinitions.DEFAULT_COLOR;
- }
+ protected boolean checkUnassignmentResult(final Identifiable unAssignedEntity,
+ final Long expectedUnAssignedEntityId) {
+ return unAssignedEntity != null && expectedUnAssignedEntityId != null
+ && unAssignedEntity.getId().equals(expectedUnAssignedEntityId);
}
- private static String getTagName(final Item item) {
- return (String) item.getItemProperty(NAME_PROPERTY).getValue();
- }
-
- protected void removePreviouslyAddedTokens() {
- tokensAdded.keySet().forEach(previouslyAddedToken -> tokenField.removeToken(previouslyAddedToken));
- }
-
- protected Long getTagIdByTagName(final Long tagId) {
- return tagDetails.entrySet().stream().filter(entry -> entry.getValue().getId().equals(tagId)).findAny()
- .map(entry -> entry.getKey()).orElse(null);
-
- }
-
- protected void removeTokenItem(final Long tokenId, final String name) {
- tokenField.removeToken(tokenId);
- tagDetails.remove(tokenId);
- setContainerPropertValues(tokenId, name, tokensAdded.get(tokenId).getColor());
- }
-
- protected void removeTagFromCombo(final Long deletedTagId) {
- if (deletedTagId != null) {
- container.removeItem(deletedTagId);
- }
- }
-
- protected abstract String getTagStyleName();
-
- protected abstract String getTokenInputPrompt();
-
- protected abstract void assignTag(final String tagNameSelected);
-
- protected abstract void unassignTag(final String tagName);
-
protected abstract Boolean isToggleTagAssignmentAllowed();
- protected abstract void displayAlreadyAssignedTags();
+ protected abstract List getAllTags();
- protected abstract void populateContainer();
-
- public TokenField getTokenField() {
- return tokenField;
- }
-
- /**
- * Tag details.
- *
- */
- public static class TagData implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private String name;
-
- private Long id;
-
- private String color;
-
- /**
- * Tag data constructor.
- *
- * @param id
- * @param name
- * @param color
- */
- public TagData(final Long id, final String name, final String color) {
- this.color = color;
- this.id = id;
- this.name = name;
- }
-
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
-
- /**
- * @param name
- * the name to set
- */
- public void setName(final String name) {
- this.name = name;
- }
-
- /**
- * @return the id
- */
- public Long getId() {
- return id;
- }
-
- /**
- * @param id
- * the id to set
- */
- public void setId(final Long id) {
- this.id = id;
- }
-
- /**
- * @return the color
- */
- public String getColor() {
- return color;
- }
-
- /**
- * @param color
- * the color to set
- */
- public void setColor(final String color) {
- this.color = color;
- }
+ protected abstract List getAssignedTags();
+ public TagPanelLayout getTagPanel() {
+ return tagPanelLayout;
}
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java
index 6e2a6d35a..5d81bca09 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java
@@ -12,10 +12,12 @@ import java.util.List;
import java.util.Objects;
import org.eclipse.hawkbit.repository.TargetTagManagement;
+import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.ui.SpPermissionChecker;
+import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.push.TargetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagDeletedEventContainer;
@@ -25,8 +27,6 @@ import org.vaadin.spring.events.EventBus.UIEventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
-import com.vaadin.data.Item;
-
/**
* /** Abstract class for target tag token layout.
*
@@ -49,23 +49,24 @@ public abstract class AbstractTargetTagToken extends Abstr
@EventBusListenerMethod(scope = EventScope.UI)
void onEventTargetTagCreated(final TargetTagCreatedEventContainer container) {
container.getEvents().stream().filter(Objects::nonNull).map(TargetTagCreatedEvent::getEntity)
- .forEach(tag -> setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()));
+ .forEach(tag -> tagCreated(new TagData(tag.getId(), tag.getName(), tag.getColour())));
}
@EventBusListenerMethod(scope = EventScope.UI)
void onTargetTagDeletedEvent(final TargetTagDeletedEventContainer container) {
- container.getEvents().stream().map(event -> getTagIdByTagName(event.getEntityId()))
- .forEach(this::removeTagFromCombo);
+ container.getEvents().stream().filter(Objects::nonNull).map(TargetTagDeletedEvent::getEntityId)
+ .forEach(this::tagDeleted);
}
@EventBusListenerMethod(scope = EventScope.UI)
void onTargetTagUpdateEvent(final List events) {
- events.stream().map(TargetTagUpdatedEvent::getEntity).forEach(entity -> {
- final Item item = container.getItem(entity.getId());
- if (item != null) {
- updateItem(entity.getName(), entity.getColour(), item);
- }
- });
+ repopulateTags();
+
+ }
+
+ @EventBusListenerMethod(scope = EventScope.UI)
+ void onTargetTagUpdateEvent(final TargetTagTableEvent event) {
+ repopulateTags();
}
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java
index b66e9ca5e..7dc9e60da 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java
@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.ui.common.tagdetails;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -15,18 +16,15 @@ import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
-import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
-import org.eclipse.hawkbit.repository.model.DistributionSetTag;
-import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.ui.SpPermissionChecker;
+import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.push.DistributionSetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagUpdatedEventContainer;
-import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.data.domain.PageRequest;
@@ -35,7 +33,6 @@ import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Sets;
-import com.vaadin.data.Item;
/**
* Implementation of target/ds tag token layout.
@@ -49,9 +46,6 @@ public class DistributionTagToken extends AbstractTagToken {
private final transient DistributionSetManagement distributionSetManagement;
- // To Be Done : have to set this value based on view???
- private static final Boolean NOTAGS_SELECTED = Boolean.FALSE;
-
public DistributionTagToken(final SpPermissionChecker checker, final VaadinMessageSource i18n,
final UINotification uinotification, final UIEventBus eventBus, final ManagementUIState managementUIState,
final DistributionSetTagManagement distributionSetTagManagement,
@@ -62,40 +56,26 @@ public class DistributionTagToken extends AbstractTagToken {
}
@Override
- protected String getTagStyleName() {
- return "distribution-tag-";
- }
-
- @Override
- protected String getTokenInputPrompt() {
- return i18n.getMessage("combo.type.tag.name");
- }
-
- @Override
- protected void assignTag(final String tagNameSelected) {
- if (tagNameSelected != null) {
- final DistributionSetTagAssignmentResult result = toggleAssignment(tagNameSelected);
- if (result.getAssigned() >= 1 && NOTAGS_SELECTED) {
- eventBus.publish(this, ManagementUIEvent.ASSIGN_DISTRIBUTION_TAG);
- }
- } else {
- uinotification.displayValidationError(i18n.getMessage("message.error.missing.tagname"));
+ protected void assignTag(final TagData tagData) {
+ final List assignedDistributionSets = distributionSetManagement
+ .assignTag(Sets.newHashSet(selectedEntity.getId()), tagData.getId());
+ if (checkAssignmentResult(assignedDistributionSets, managementUIState.getLastSelectedDsIdName())) {
+ uinotification.displaySuccess(
+ i18n.getMessage("message.target.assigned.one", selectedEntity.getName(), tagData.getName()));
+ eventBus.publish(this, ManagementUIEvent.ASSIGN_DISTRIBUTION_TAG);
+ tagPanelLayout.setAssignedTag(tagData);
}
}
- private DistributionSetTagAssignmentResult toggleAssignment(final String tagNameSelected) {
- final DistributionSetTagAssignmentResult result = distributionSetManagement
- .toggleTagAssignment(Sets.newHashSet(selectedEntity.getId()), tagNameSelected);
- processTargetTagAssigmentResult(result);
- uinotification.displaySuccess(HawkbitCommonUtil.createAssignmentMessage(tagNameSelected, result, i18n));
- return result;
- }
-
@Override
- protected void unassignTag(final String tagName) {
- final DistributionSetTagAssignmentResult result = toggleAssignment(tagName);
- if (result.getUnassigned() >= 1) {
+ protected void unassignTag(final TagData tagData) {
+ final DistributionSet unAssignedDistributionSet = distributionSetManagement.unAssignTag(selectedEntity.getId(),
+ tagData.getId());
+ if (checkUnassignmentResult(unAssignedDistributionSet, managementUIState.getLastSelectedDsIdName())) {
+ uinotification.displaySuccess(
+ i18n.getMessage("message.target.unassigned.one", selectedEntity.getName(), tagData.getName()));
eventBus.publish(this, ManagementUIEvent.UNASSIGN_DISTRIBUTION_TAG);
+ tagPanelLayout.removeAssignedTag(tagData);
}
}
@@ -105,21 +85,21 @@ public class DistributionTagToken extends AbstractTagToken {
}
@Override
- public void displayAlreadyAssignedTags() {
- removePreviouslyAddedTokens();
- if (selectedEntity != null) {
- distributionSetTagManagement.findByDistributionSet(PageRequest.of(0, MAX_TAG_QUERY), selectedEntity.getId())
- .getContent().stream().forEach(tag -> addNewToken(tag.getId()));
- }
+ protected List getAllTags() {
+ return distributionSetTagManagement.findAll(PageRequest.of(0, MAX_TAG_QUERY)).getContent().stream()
+ .map(tag -> new TagData(tag.getId(), tag.getName(), tag.getColour())).collect(Collectors.toList());
}
@Override
- protected void populateContainer() {
- container.removeAllItems();
- tagDetails.clear();
- distributionSetTagManagement.findAll(PageRequest.of(0, MAX_TAG_QUERY)).getContent().stream()
- .forEach(tag -> setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()));
+ protected List getAssignedTags() {
+ if (selectedEntity != null) {
+ return distributionSetTagManagement
+ .findByDistributionSet(PageRequest.of(0, MAX_TAG_QUERY), selectedEntity.getId()).getContent()
+ .stream().map(tag -> new TagData(tag.getId(), tag.getName(), tag.getColour()))
+ .collect(Collectors.toList());
+ }
+ return Collections.emptyList();
}
@EventBusListenerMethod(scope = EventScope.UI)
@@ -128,58 +108,23 @@ public class DistributionTagToken extends AbstractTagToken {
}
@EventBusListenerMethod(scope = EventScope.UI)
- void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
+ void onDistributionSetTagCreatedEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
eventContainer.getEvents().stream().filter(Objects::nonNull).map(DistributionSetTagCreatedEvent::getEntity)
- .forEach(distributionSetTag -> setContainerPropertValues(distributionSetTag.getId(),
- distributionSetTag.getName(), distributionSetTag.getColour()));
+ .forEach(tag -> tagCreated(new TagData(tag.getId(), tag.getName(), tag.getColour())));
}
@EventBusListenerMethod(scope = EventScope.UI)
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEventContainer eventContainer) {
- eventContainer.getEvents().stream().map(event -> getTagIdByTagName(event.getEntityId()))
- .forEach(this::removeTagFromCombo);
+ eventContainer.getEvents().forEach(event -> tagDeleted(event.getEntityId()));
}
@EventBusListenerMethod(scope = EventScope.UI)
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) {
- eventContainer.getEvents().stream().filter(Objects::nonNull).map(DistributionSetTagUpdatedEvent::getEntity)
- .forEach(entity -> {
- final Item item = container.getItem(entity.getId());
- if (item != null) {
- updateItem(entity.getName(), entity.getColour(), item);
- }
- });
+ repopulateTags();
}
- private void processTargetTagAssigmentResult(final DistributionSetTagAssignmentResult assignmentResult) {
- final DistributionSetTag tag = assignmentResult.getDistributionSetTag();
- if (isAssign(assignmentResult)) {
- addNewToken(tag.getId());
- } else if (isUnassign(assignmentResult)) {
- removeTokenItem(tag.getId(), tag.getName());
- }
+ @EventBusListenerMethod(scope = EventScope.UI)
+ void onDistributionSetTagUpdateEvent(final DistributionSetTagTableEvent event) {
+ repopulateTags();
}
-
- protected boolean isAssign(final DistributionSetTagAssignmentResult assignmentResult) {
- if (assignmentResult.getAssigned() > 0 && managementUIState.getLastSelectedDsIdName() != null) {
- final List assignedDsNames = assignmentResult.getAssignedEntity().stream().map(t -> t.getId())
- .collect(Collectors.toList());
- if (assignedDsNames.contains(managementUIState.getLastSelectedDsIdName())) {
- return true;
- }
- }
- return false;
- }
-
- protected boolean isUnassign(final DistributionSetTagAssignmentResult assignmentResult) {
- if (assignmentResult.getUnassigned() > 0 && managementUIState.getLastSelectedDsIdName() != null) {
- final List assignedDsNames = assignmentResult.getUnassignedEntity().stream().map(t -> t.getId())
- .collect(Collectors.toList());
- if (assignedDsNames.contains(managementUIState.getLastSelectedDsIdName())) {
- return true;
- }
- }
- return false;
- }
-
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagAssignementComboBox.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagAssignementComboBox.java
new file mode 100644
index 000000000..cdb3b98b8
--- /dev/null
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagAssignementComboBox.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2019 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.common.tagdetails;
+
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.hawkbit.repository.model.DistributionSet;
+import org.eclipse.hawkbit.repository.model.Target;
+import org.eclipse.hawkbit.ui.common.builder.ComboBoxBuilder;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagPanelLayout.TagAssignmentListener;
+import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
+import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
+import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
+import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
+
+import com.google.common.collect.Sets;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.themes.ValoTheme;
+
+/**
+ * Combobox that lists all available Tags that can be assigned to a
+ * {@link Target} or {@link DistributionSet}.
+ */
+public class TagAssignementComboBox extends HorizontalLayout {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String NAME_PROPERTY = "name";
+ private static final String COLOR_PROPERTY = "color";
+
+ private final IndexedContainer allAssignableTags;
+ private final transient Set listeners = Sets.newConcurrentHashSet();
+
+ private final ComboBox assignableTagsComboBox;
+
+ private final boolean readOnlyMode;
+
+ /**
+ * Constructor.
+ *
+ * @param i18n
+ * the i18n
+ * @param readOnlyMode
+ * if true the combobox will be disabled so no assignment can be
+ * done.
+ */
+ TagAssignementComboBox(final VaadinMessageSource i18n, final boolean readOnlyMode) {
+
+ this.readOnlyMode = readOnlyMode;
+
+ setWidth("100%");
+
+ allAssignableTags = new IndexedContainer();
+ allAssignableTags.addContainerProperty(NAME_PROPERTY, String.class, "");
+ allAssignableTags.addContainerProperty(COLOR_PROPERTY, String.class, "");
+
+ assignableTagsComboBox = new ComboBoxBuilder().setId(UIComponentIdProvider.TAG_SELECTION_ID)
+ .setPrompt(i18n.getMessage(UIMessageIdProvider.TOOLTIP_SELECT_TAG))
+ .setValueChangeListener(this::onSelectionChanged).buildCombBox();
+ addComponent(assignableTagsComboBox);
+ assignableTagsComboBox.setContainerDataSource(allAssignableTags);
+ assignableTagsComboBox.setNullSelectionAllowed(true);
+ assignableTagsComboBox.addStyleName(SPUIStyleDefinitions.DETAILS_LAYOUT_STYLE);
+ assignableTagsComboBox.addStyleName(ValoTheme.COMBOBOX_TINY);
+ assignableTagsComboBox.setEnabled(!readOnlyMode);
+ assignableTagsComboBox.setWidth("100%");
+ clearComboBoxSelection();
+ }
+
+ /**
+ * Initializes the Combobox with all assignable tags.
+ *
+ * @param assignableTags
+ * assignable tags
+ */
+ void initializeAssignableTags(final List assignableTags) {
+ assignableTags.forEach(this::addAssignableTag);
+ }
+
+ private void onSelectionChanged(final ValueChangeEvent event) {
+ final Object selectedValue = event.getProperty().getValue();
+ if (!isValidTagSelection(selectedValue) || readOnlyMode) {
+ return;
+ }
+ assignTag((String) selectedValue);
+ }
+
+ private void assignTag(final String tagName) {
+ allAssignableTags.removeItem(tagName);
+ notifyListenersTagAssigned(tagName);
+ clearComboBoxSelection();
+ }
+
+ private boolean isValidTagSelection(final Object selectedValue) {
+ return selectedValue != null && selectedValue != assignableTagsComboBox.getNullSelectionItemId()
+ && selectedValue instanceof String;
+ }
+
+ /**
+ * Removes all Tags from Combobox.
+ */
+ void removeAllTags() {
+ allAssignableTags.removeAllItems();
+ clearComboBoxSelection();
+ }
+
+ /**
+ * Adds an assignable Tag to the combobox.
+ *
+ * @param tagData
+ * the data of the Tag
+ */
+ void addAssignableTag(final TagData tagData) {
+ final Item item = allAssignableTags.addItem(tagData.getName());
+ if (item == null) {
+ return;
+ }
+ item.getItemProperty(NAME_PROPERTY).setValue(tagData.getName());
+ item.getItemProperty(COLOR_PROPERTY).setValue(tagData.getColor());
+ }
+
+ /**
+ * Removes an assignable tag from the combobox.
+ *
+ * @param tagData
+ * the {@link TagData} of the Tag that should be removed.
+ */
+ void removeAssignableTag(final TagData tagData) {
+ allAssignableTags.removeItem(tagData.getName());
+ }
+
+ /**
+ * Registers an {@link TagAssignmentListener} on the combobox.
+ *
+ * @param listener
+ * the listener to register
+ */
+ void addTagAssignmentListener(final TagAssignmentListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Removes a {@link TagAssignmentListener} from the combobox,
+ *
+ * @param listener
+ * the listener that should be removed.
+ */
+ void removeTagAssignmentListener(final TagAssignmentListener listener) {
+ listeners.remove(listener);
+ }
+
+ private void notifyListenersTagAssigned(final String tagName) {
+ listeners.forEach(listener -> listener.assignTag(tagName));
+ }
+
+ private void clearComboBoxSelection() {
+ assignableTagsComboBox.select(assignableTagsComboBox.getNullSelectionItemId());
+ }
+}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagData.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagData.java
new file mode 100644
index 000000000..b3c1db33c
--- /dev/null
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagData.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2019 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.common.tagdetails;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import org.eclipse.hawkbit.repository.model.Tag;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Tag details. Represents the ui data for {@link Tag} entity.
+ */
+public class TagData implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String name;
+
+ private final Long id;
+
+ private final String color;
+
+ /**
+ * Tag data constructor.
+ *
+ * @param id
+ * the id of the {@link Tag}
+ * @param name
+ * the name of the {@link Tag}
+ * @param color
+ * the color of the {@link Tag}
+ */
+ public TagData(final Long id, final String name, final String color) {
+ this.color = color;
+ this.id = id;
+ this.name = name;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the id
+ */
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * @return the color
+ */
+ public String getColor() {
+ return color;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final TagData other = (TagData) obj;
+ return Objects.equals(this.id, other.id) && Objects.equals(this.name, other.name)
+ && Objects.equals(this.color, other.color);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, color);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("id", id).add("name", name).add("color", color).toString();
+ }
+}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagListField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagListField.java
new file mode 100644
index 000000000..c61c5ec7a
--- /dev/null
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagListField.java
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2019 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.common.tagdetails;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.hawkbit.repository.model.DistributionSet;
+import org.eclipse.hawkbit.repository.model.Target;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagPanelLayout.TagAssignmentListener;
+import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
+import org.eclipse.hawkbit.ui.decorators.SPUITagButtonStyle;
+import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
+import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
+import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
+import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
+import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import com.vaadin.server.FontAwesome;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CssLayout;
+
+/**
+ * A panel that shows the assigned tags. A click on a tag unsassigns the tag
+ * from the {@link Target} or {@link DistributionSet}.
+ */
+public class TagListField extends CssLayout {
+
+ private static final long serialVersionUID = 1L;
+
+ private final transient Map tagButtons = Maps.newTreeMap(Ordering.natural());
+ private final transient Set listeners = Sets.newConcurrentHashSet();
+ private final VaadinMessageSource i18n;
+ private final boolean readOnlyMode;
+
+ /**
+ * Constructor.
+ *
+ * @param i18n
+ * @param readOnlyMode
+ * if true no unassignment can be done
+ */
+ TagListField(final VaadinMessageSource i18n, final boolean readOnlyMode) {
+ this.i18n = i18n;
+ this.readOnlyMode = readOnlyMode;
+ setSizeFull();
+ }
+
+ /**
+ * Initializes the Tag panel with all assigned tags.
+ *
+ * @param assignedTags
+ * assigned tags
+ */
+ void initializeAssignedTags(final List assignedTags) {
+ removeAllComponents();
+
+ assignedTags.forEach(tag -> {
+ final Button tagButton = createButton(tag.getName(), tag.getColor());
+ tagButtons.put(tag.getName(), tagButton);
+ });
+
+ addTagButtonsAsComponents();
+ }
+
+ /**
+ * Adds a tag
+ *
+ * @param tagName
+ * @param tagColor
+ */
+ void addTag(final String tagName, final String tagColor) {
+ if (!tagButtons.containsKey(tagName)) {
+ removeAllComponents();
+
+ final Button tagButton = createButton(tagName, tagColor);
+ tagButtons.put(tagName, tagButton);
+
+ addTagButtonsAsComponents();
+ }
+ }
+
+ private void addTagButtonsAsComponents() {
+ tagButtons.keySet().forEach(sortedTagName -> addComponent(tagButtons.get(sortedTagName)));
+ }
+
+ private Button createButton(final String tagName, final String tagColor) {
+ final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.ASSIGNED_TAG_ID_PREFIX + tagName,
+ tagName, i18n.getMessage(UIMessageIdProvider.TOOLTIP_CLICK_TO_REMOVE), null, false, null,
+ SPUITagButtonStyle.class);
+ button.addClickListener(e -> removeTagAssignment(tagName));
+ button.addStyleName(SPUIStyleDefinitions.TAG_BUTTON_WITH_BACKGROUND);
+ button.addStyleName(SPUIDefinitions.TEXT_STYLE + " " + SPUIStyleDefinitions.DETAILS_LAYOUT_STYLE);
+ button.setEnabled(!readOnlyMode);
+ button.setCaption("" + FontAwesome.CIRCLE.getHtml()
+ + "" + " " + tagName.concat(" ×"));
+ button.setCaptionAsHtml(true);
+ return button;
+ }
+
+ private void removeTagAssignment(final String tagName) {
+ removeTag(tagName);
+ notifyListenersTagAssignmentRemoved(tagName);
+ }
+
+ /**
+ * Removes a tag from the field.
+ *
+ * @param tagName
+ */
+ void removeTag(final String tagName) {
+ final Button button = tagButtons.get(tagName);
+ if (button != null) {
+ tagButtons.remove(tagName);
+ removeComponent(button);
+ }
+ }
+
+ /**
+ * Removes all tags from the field.
+ */
+ void removeAllTags() {
+ removeAllComponents();
+ tagButtons.clear();
+ }
+
+ /**
+ * Registers a {@link TagAssignmentListener}.
+ *
+ * @param listener
+ * the listener to register
+ */
+ void addTagAssignmentListener(final TagAssignmentListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Removes a {@link TagAssignmentListener}.
+ *
+ * @param listener
+ * the listener to remove
+ */
+ void removeTagAssignmentListener(final TagAssignmentListener listener) {
+ listeners.remove(listener);
+ }
+
+ private void notifyListenersTagAssignmentRemoved(final String tagName) {
+ listeners.forEach(listener -> listener.unassignTag(tagName));
+ }
+
+ /**
+ * Returns all assigned tags shown in the field.
+ *
+ * @return a {@link List} with tags
+ */
+ List getTags() {
+ return Lists.newArrayList(tagButtons.keySet());
+ }
+}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagPanelLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagPanelLayout.java
new file mode 100644
index 000000000..e6d140254
--- /dev/null
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TagPanelLayout.java
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2019 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.common.tagdetails;
+
+import java.util.List;
+
+import org.eclipse.hawkbit.repository.model.DistributionSet;
+import org.eclipse.hawkbit.repository.model.Target;
+import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
+
+import com.google.common.collect.Lists;
+import com.vaadin.ui.VerticalLayout;
+
+/**
+ * A layout that shows a combobox with available tags that can be assigned to a
+ * {@link Target} or {@link DistributionSet}. The layout also shows all already
+ * assigned tags. This tags can also be removed.
+ */
+public class TagPanelLayout extends VerticalLayout {
+
+ private static final long serialVersionUID = 1L;
+
+ private final TagListField assignedTagField;
+ private final TagAssignementComboBox assignableTagsComboBox;
+
+ /**
+ * Constructor.
+ *
+ * @param i18n
+ * i18n
+ * @param readOnlyMode
+ * if true no assignments and unassignements can be
+ * done.
+ */
+ TagPanelLayout(final VaadinMessageSource i18n, final boolean readOnlyMode) {
+
+ assignableTagsComboBox = new TagAssignementComboBox(i18n, readOnlyMode);
+ addComponent(assignableTagsComboBox);
+
+ assignedTagField = new TagListField(i18n, readOnlyMode);
+ addComponent(assignedTagField);
+ setExpandRatio(assignedTagField, 1.0F);
+ setExpandRatio(assignableTagsComboBox, 0.0F);
+ }
+
+ /**
+ * Initializes the panel with all available tags and all assigned tags.
+ *
+ * @param allTags
+ * all tags
+ * @param assignedTags
+ * assigned tags
+ */
+ void initializeTags(final List allTags, final List assignedTags) {
+ assignableTagsComboBox.removeAllTags();
+ assignedTagField.removeAllTags();
+
+ final List assignableTags = Lists.newArrayList(allTags);
+ assignableTags.removeAll(assignedTags);
+
+ assignableTagsComboBox.initializeAssignableTags(assignableTags);
+ assignedTagField.initializeAssignedTags(assignedTags);
+
+ }
+
+ /**
+ * Sets a tag that is assigned.
+ *
+ * @param tagData
+ * the {@link TagData}
+ */
+ public void setAssignedTag(final TagData tagData) {
+ // the assigned tag is no longer assignable
+ assignableTagsComboBox.removeAssignableTag(tagData);
+ // show it as an assigned tag
+ assignedTagField.addTag(tagData.getName(), tagData.getColor());
+ }
+
+ /**
+ * Removes an assigned tag.
+ *
+ * @param tagData
+ * the {@link TagData}
+ */
+ public void removeAssignedTag(final TagData tagData) {
+ // the un-assigned tag is now assignable
+ assignableTagsComboBox.addAssignableTag(tagData);
+ // remove ot from the assigned tags
+ assignedTagField.removeTag(tagData.getName());
+ }
+
+ /**
+ * Informs the panel that a new tag was created.
+ *
+ * @param tagData
+ * the {@link TagData}
+ */
+ void tagCreated(final TagData tagData) {
+ assignableTagsComboBox.addAssignableTag(tagData);
+ }
+
+ /**
+ * Informs the panel that a tag was deleted.
+ *
+ * @param tagData
+ * the {@link TagData}
+ */
+ void tagDeleted(final TagData tagData) {
+ assignableTagsComboBox.removeAssignableTag(tagData);
+ assignedTagField.removeTag(tagData.getName());
+ }
+
+ /**
+ * Callback interface if user triggers a tag assignment or tag unassignment
+ * via UI controls.
+ *
+ */
+ interface TagAssignmentListener {
+
+ /**
+ * User triggers a tag assignment.
+ *
+ * @param tagName
+ * the name of the tag that should be assigned.
+ */
+ void assignTag(String tagName);
+
+ /**
+ * User triggers a tag unassignment.
+ *
+ * @param tagName
+ * the name of the tag that should be unassigned.
+ */
+ void unassignTag(String tagName);
+ }
+
+ /**
+ * Registers a {@link TagAssignmentListener}.
+ *
+ * @param listener
+ * the listener
+ */
+ void addTagAssignmentListener(final TagAssignmentListener listener) {
+ assignableTagsComboBox.addTagAssignmentListener(listener);
+ assignedTagField.addTagAssignmentListener(listener);
+ }
+
+ /**
+ * Removes a {@link TagAssignmentListener}.
+ *
+ * @param listener
+ * the listener
+ */
+ void removeTagAssignmentListener(final TagAssignmentListener listener) {
+ assignableTagsComboBox.removeTagAssignmentListener(listener);
+ assignedTagField.removeTagAssignmentListener(listener);
+ }
+
+ /**
+ * Returns all assigned tags.
+ *
+ * @return {@link List} with tags.
+ */
+ public List getAssignedTags() {
+ return assignedTagField.getTags();
+ }
+}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java
index f95d39c4a..6448ec35b 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java
@@ -9,18 +9,16 @@
package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.Arrays;
-import java.util.Optional;
+import java.util.List;
+import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.model.Target;
-import org.eclipse.hawkbit.repository.model.TargetTag;
-import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
-import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.data.domain.PageRequest;
@@ -28,6 +26,8 @@ import org.vaadin.spring.events.EventBus.UIEventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
+import com.google.common.collect.Lists;
+
/**
* Implementation of Target tag token.
*
@@ -37,11 +37,6 @@ public class TargetTagToken extends AbstractTargetTagToken {
private static final long serialVersionUID = 7124887018280196721L;
- private static final int MAX_TAGS = 500;
-
- // To Be Done : have to set this value based on view???
- private static final Boolean NOTAGS_SELECTED = Boolean.FALSE;
-
private final transient TargetManagement targetManagement;
public TargetTagToken(final SpPermissionChecker checker, final VaadinMessageSource i18n,
@@ -52,40 +47,25 @@ public class TargetTagToken extends AbstractTargetTagToken {
}
@Override
- protected String getTagStyleName() {
- return "target-tag-";
- }
-
- @Override
- protected String getTokenInputPrompt() {
- return i18n.getMessage("combo.type.tag.name");
- }
-
- @Override
- protected void assignTag(final String tagNameSelected) {
- if (tagNameSelected != null) {
- final TargetTagAssignmentResult result = toggleAssignment(tagNameSelected);
- if (result.getAssigned() >= 1 && NOTAGS_SELECTED) {
- eventBus.publish(this, ManagementUIEvent.ASSIGN_TARGET_TAG);
- }
- } else {
- uinotification.displayValidationError(i18n.getMessage("message.error.missing.tagname"));
+ protected void assignTag(final TagData tagData) {
+ final List assignedTargets = targetManagement.assignTag(Arrays.asList(selectedEntity.getControllerId()),
+ tagData.getId());
+ if (checkAssignmentResult(assignedTargets, selectedEntity.getId())) {
+ uinotification.displaySuccess(
+ i18n.getMessage("message.target.assigned.one", selectedEntity.getName(), tagData.getName()));
+ eventBus.publish(this, ManagementUIEvent.ASSIGN_TARGET_TAG);
+ tagPanelLayout.setAssignedTag(tagData);
}
}
- private TargetTagAssignmentResult toggleAssignment(final String tagNameSelected) {
- final TargetTagAssignmentResult result = targetManagement
- .toggleTagAssignment(Arrays.asList(selectedEntity.getControllerId()), tagNameSelected);
- processTargetTagAssigmentResult(result);
- uinotification.displaySuccess(HawkbitCommonUtil.createAssignmentMessage(tagNameSelected, result, i18n));
- return result;
- }
-
@Override
- protected void unassignTag(final String tagName) {
- final TargetTagAssignmentResult result = toggleAssignment(tagName);
- if (result.getUnassigned() >= 1) {
+ protected void unassignTag(final TagData tagData) {
+ final Target unassignedTarget = targetManagement.unAssignTag(selectedEntity.getControllerId(), tagData.getId());
+ if (checkUnassignmentResult(unassignedTarget, selectedEntity.getId())) {
+ uinotification.displaySuccess(
+ i18n.getMessage("message.target.unassigned.one", selectedEntity.getName(), tagData.getName()));
eventBus.publish(this, ManagementUIEvent.UNASSIGN_TARGET_TAG);
+ tagPanelLayout.removeAssignedTag(tagData);
}
}
@@ -95,50 +75,19 @@ public class TargetTagToken extends AbstractTargetTagToken {
}
@Override
- protected void displayAlreadyAssignedTags() {
- removePreviouslyAddedTokens();
- if (selectedEntity != null) {
- for (final TargetTag tag : tagManagement.findByTarget(PageRequest.of(0, MAX_TAGS),
- selectedEntity.getControllerId())) {
- addNewToken(tag.getId());
- }
- }
+ protected List getAllTags() {
+ return tagManagement.findAll(PageRequest.of(0, MAX_TAG_QUERY)).stream()
+ .map(tag -> new TagData(tag.getId(), tag.getName(), tag.getColour())).collect(Collectors.toList());
}
@Override
- protected void populateContainer() {
- container.removeAllItems();
- tagDetails.clear();
- for (final TargetTag tag : tagManagement.findAll(PageRequest.of(0, MAX_TAGS))) {
- setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour());
+ protected List getAssignedTags() {
+ if (selectedEntity != null) {
+ return tagManagement.findByTarget(PageRequest.of(0, MAX_TAG_QUERY), selectedEntity.getControllerId())
+ .stream().map(tag -> new TagData(tag.getId(), tag.getName(), tag.getColour()))
+ .collect(Collectors.toList());
}
- }
-
- public void processTargetTagAssigmentResult(final TargetTagAssignmentResult assignmentResult) {
- final TargetTag targetTag = assignmentResult.getTargetTag();
- if (isAssign(assignmentResult)) {
- addNewToken(targetTag.getId());
- } else if (isUnassign(assignmentResult)) {
- removeTokenItem(targetTag.getId(), targetTag.getName());
- }
- }
-
- protected boolean isAssign(final TargetTagAssignmentResult assignmentResult) {
- final Optional targetId = managementUIState.getLastSelectedTargetId();
- if (assignmentResult.getAssigned() > 0 && targetId.isPresent()) {
- return assignmentResult.getAssignedEntity().stream().map(Target::getId)
- .anyMatch(controllerId -> controllerId.equals(targetId.get()));
- }
- return false;
- }
-
- protected boolean isUnassign(final TargetTagAssignmentResult assignmentResult) {
- final Optional targetId = managementUIState.getLastSelectedTargetId();
- if (assignmentResult.getUnassigned() > 0 && targetId.isPresent()) {
- return assignmentResult.getUnassignedEntity().stream().map(Target::getId)
- .anyMatch(controllerId -> controllerId.equals(targetId.get()));
- }
- return false;
+ return Lists.newArrayList();
}
@EventBusListenerMethod(scope = EventScope.UI)
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/CustomRendererWidgetSet.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/CustomRendererWidgetSet.gwt.xml
index 04e0de679..8b9a6c66d 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/CustomRendererWidgetSet.gwt.xml
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/customrenderers/CustomRendererWidgetSet.gwt.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/CustomAcceptCriteria.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/CustomAcceptCriteria.gwt.xml
index fe4a19781..475237479 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/CustomAcceptCriteria.gwt.xml
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/CustomAcceptCriteria.gwt.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java
index 0564061ad..f7b3ca531 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java
@@ -40,6 +40,7 @@ import org.eclipse.hawkbit.ui.distributions.smtype.filter.DistSMTypeFilterButton
import org.eclipse.hawkbit.ui.distributions.smtype.filter.DistSMTypeFilterLayout;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
+import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.menu.DashboardMenuItem;
import org.eclipse.hawkbit.ui.push.DistributionSetCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetDeletedEventContainer;
@@ -95,8 +96,8 @@ public class DistributionsView extends AbstractNotificationView implements Brows
@Autowired
DistributionsView(final SpPermissionChecker permChecker, final UIEventBus eventBus, final VaadinMessageSource i18n,
- final UINotification uiNotification, final ManageDistUIState manageDistUIState,
- final SoftwareModuleManagement softwareModuleManagement,
+ final UINotification uiNotification, final ManagementUIState managementUIState,
+ final ManageDistUIState manageDistUIState, final SoftwareModuleManagement softwareModuleManagement,
final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final DistributionSetManagement distributionSetManagement,
final DistributionSetTypeManagement distributionSetTypeManagement, final TargetManagement targetManagement,
@@ -117,10 +118,10 @@ public class DistributionsView extends AbstractNotificationView implements Brows
this.filterByDSTypeLayout = new DSTypeFilterLayout(manageDistUIState, i18n, permChecker, eventBus,
entityFactory, uiNotification, softwareModuleTypeManagement, distributionSetTypeManagement,
dsTypeFilterButtons);
- this.distributionTableLayout = new DistributionSetTableLayout(i18n, eventBus, permChecker, manageDistUIState,
- softwareModuleManagement, distributionSetManagement, distributionSetTypeManagement, targetManagement,
- entityFactory, uiNotification, distributionSetTagManagement, distributionsViewClientCriterion,
- systemManagement, configManagement, systemSecurityContext);
+ this.distributionTableLayout = new DistributionSetTableLayout(i18n, eventBus, permChecker, managementUIState,
+ manageDistUIState, softwareModuleManagement, distributionSetManagement, distributionSetTypeManagement,
+ targetManagement, entityFactory, uiNotification, distributionSetTagManagement,
+ distributionsViewClientCriterion, systemManagement, configManagement, systemSecurityContext);
this.softwareModuleTableLayout = new SwModuleTableLayout(i18n, uiNotification, eventBus,
softwareModuleManagement, softwareModuleTypeManagement, entityFactory, manageDistUIState, permChecker,
distributionsViewClientCriterion, artifactUploadState, artifactManagement);
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java
index 3ee0a78f1..b5a01612a 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java
@@ -22,6 +22,7 @@ import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout;
import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
import org.eclipse.hawkbit.ui.management.dstable.DistributionAddUpdateWindowLayout;
+import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.vaadin.spring.events.EventBus.UIEventBus;
@@ -36,8 +37,8 @@ public class DistributionSetTableLayout extends AbstractTableLayout
+
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java
index 83ab708a4..cd02aed92 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java
@@ -227,11 +227,27 @@ public class DistributionTable extends AbstractNamedVersionTable {
- if (managementUIEvent == ManagementUIEvent.UNASSIGN_DISTRIBUTION_TAG
- || managementUIEvent == ManagementUIEvent.ASSIGN_DISTRIBUTION_TAG) {
+ if (tableIsFilteredByTagsAndTagWasUnassignedFromDistSet(managementUIEvent)
+ || tableIsFilteredByNoTagAndTagWasAssignedToDistSet(managementUIEvent)) {
refreshFilter();
}
});
@@ -263,8 +279,8 @@ public class DistributionTable extends AbstractNamedVersionTable list = new ArrayList<>();
queryConfig.put(SPUIDefinitions.FILTER_BY_NO_TAG,
managementUIState.getDistributionTableFilters().isNoTagSelected());
- if (!managementUIState.getDistributionTableFilters().getDistSetTags().isEmpty()) {
- list.addAll(managementUIState.getDistributionTableFilters().getDistSetTags());
+ if (!managementUIState.getDistributionTableFilters().getClickedDistSetTags().isEmpty()) {
+ list.addAll(managementUIState.getDistributionTableFilters().getClickedDistSetTags());
}
queryConfig.put(SPUIDefinitions.FILTER_BY_TAG, list);
return queryConfig;
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java
index 9e4e9d26e..9a2aae5d8 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java
@@ -39,7 +39,7 @@ public class DistributionTagButtonClick extends AbstractFilterMultiButtonClick {
if (clickedButton.getData().equals(SPUIDefinitions.NO_TAG_BUTTON_ID)) {
managementUIState.getDistributionTableFilters().setNoTagSelected(false);
} else {
- managementUIState.getDistributionTableFilters().getDistSetTags().remove(clickedButton.getId());
+ managementUIState.getDistributionTableFilters().getClickedDistSetTags().remove(clickedButton.getId());
}
eventBus.publish(this, new RefreshDistributionTableByFilterEvent());
}
@@ -49,7 +49,7 @@ public class DistributionTagButtonClick extends AbstractFilterMultiButtonClick {
if (clickedButton.getData().equals(SPUIDefinitions.NO_TAG_BUTTON_ID)) {
managementUIState.getDistributionTableFilters().setNoTagSelected(true);
} else {
- managementUIState.getDistributionTableFilters().getDistSetTags().add(clickedButton.getId());
+ managementUIState.getDistributionTableFilters().getClickedDistSetTags().add(clickedButton.getId());
}
eventBus.publish(this, new RefreshDistributionTableByFilterEvent());
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java
index f9a871edc..78de4cfe0 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java
@@ -107,8 +107,8 @@ public class DistributionTagButtons extends AbstractFilterButtons {
@Override
protected boolean isClickedByDefault(final String tagName) {
- return null != managementUIState.getDistributionTableFilters().getDistSetTags()
- && managementUIState.getDistributionTableFilters().getDistSetTags().contains(tagName);
+ return null != managementUIState.getDistributionTableFilters().getClickedDistSetTags()
+ && managementUIState.getDistributionTableFilters().getClickedDistSetTags().contains(tagName);
}
@Override
@@ -173,7 +173,7 @@ public class DistributionTagButtons extends AbstractFilterButtons {
protected void deleteEntity(final String entityToDelete) {
final Optional tagToDelete = distributionSetTagManagement.getByName(entityToDelete);
tagToDelete.ifPresent(tag -> {
- if (managementUIState.getDistributionTableFilters().getDistSetTags().contains(entityToDelete)) {
+ if (managementUIState.getDistributionTableFilters().getClickedDistSetTags().contains(entityToDelete)) {
uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityToDelete));
removeUpdateAndDeleteColumn();
} else {
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java
index bd2f0f6ef..15f4e021c 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java
@@ -139,7 +139,7 @@ public class DistributionTagDropEvent implements DropHandler {
final String distTagName = HawkbitCommonUtil.removePrefix(targetDetails.getTarget().getId(),
SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS);
- final List tagsClickedList = distFilterParameters.getDistSetTags();
+ final List tagsClickedList = distFilterParameters.getClickedDistSetTags();
final DistributionSetTagAssignmentResult result = distributionSetManagement.toggleTagAssignment(distSelected,
distTagName);
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java
index 1fb45182a..3730f28a7 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java
@@ -35,7 +35,7 @@ public class DistributionTableFilters implements Serializable {
private TargetIdName pinnedTarget;
- private final List distSetTags = new ArrayList<>();
+ private final List clickedDistSetTags = new ArrayList<>();
private Boolean noTagSelected = Boolean.FALSE;
@@ -47,8 +47,8 @@ public class DistributionTableFilters implements Serializable {
return noTagSelected;
}
- public List getDistSetTags() {
- return distSetTags;
+ public List getClickedDistSetTags() {
+ return clickedDistSetTags;
}
public Optional getDistId() {
@@ -74,5 +74,4 @@ public class DistributionTableFilters implements Serializable {
public void setSearchText(final String searchText) {
this.searchText = searchText;
}
-
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java
index 3c7549ab7..627f263d4 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java
@@ -23,7 +23,6 @@ import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.Executor;
import org.eclipse.hawkbit.repository.DeploymentManagement;
@@ -33,7 +32,7 @@ import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
-import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken.TagData;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagData;
import org.eclipse.hawkbit.ui.components.HawkbitErrorNotificationMessage;
import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
@@ -287,7 +286,7 @@ public class BulkUploadHandler extends CustomComponent
String dsAssignmentFailedMsg = null;
String tagAssignmentFailedMsg = null;
if (ifTargetsCreatedSuccessfully()) {
- if (ifTagsSelected()) {
+ if (targetBulkTokenTags.isTagSelectedForAssignment()) {
tagAssignmentFailedMsg = tagAssignment();
}
if (ifDsSelected()) {
@@ -312,9 +311,8 @@ public class BulkUploadHandler extends CustomComponent
}
private String tagAssignment() {
- final Map tokensSelected = targetBulkTokenTags.getTokensAdded();
final List deletedTags = new ArrayList<>();
- for (final TagData tagData : tokensSelected.values()) {
+ for (final TagData tagData : targetBulkTokenTags.getSelectedTagsForAssignment()) {
if (!tagManagement.get(tagData.getId()).isPresent()) {
deletedTags.add(tagData.getName());
} else {
@@ -332,10 +330,6 @@ public class BulkUploadHandler extends CustomComponent
return i18n.getMessage("message.bulk.upload.tag.assignments.failed");
}
- private boolean ifTagsSelected() {
- return targetBulkTokenTags.getTokenField().getValue() != null;
- }
-
private boolean ifDsSelected() {
return comboBox.getValue() != null;
}
@@ -375,6 +369,7 @@ public class BulkUploadHandler extends CustomComponent
} catch (final EntityAlreadyExistsException ex) {
// Targets that exist already are simply ignored
+ LOG.info("Entity {} - {} already exists and will be ignored", newControllerId, name);
}
}
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java
index 8febaf76e..69b55f84e 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java
@@ -8,12 +8,15 @@
*/
package org.eclipse.hawkbit.ui.management.targettable;
-import java.util.Map;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TargetTagManagement;
-import org.eclipse.hawkbit.repository.model.TargetTag;
+import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTargetTagToken;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagData;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
@@ -24,11 +27,9 @@ import org.vaadin.spring.events.EventBus.UIEventBus;
* Target tag layout in bulk upload popup.
*
*/
-public class TargetBulkTokenTags extends AbstractTargetTagToken {
+public class TargetBulkTokenTags extends AbstractTargetTagToken {
private static final long serialVersionUID = 4159616629565523717L;
- private static final int MAX_TAGS = 500;
-
TargetBulkTokenTags(final SpPermissionChecker checker, final VaadinMessageSource i18n,
final UINotification uinotification, final UIEventBus eventBus, final ManagementUIState managementUIState,
final TargetTagManagement tagManagement) {
@@ -36,24 +37,15 @@ public class TargetBulkTokenTags extends AbstractTargetTagToken {
}
@Override
- protected void assignTag(final String tagNameSelected) {
- managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames().add(tagNameSelected);
-
+ protected void assignTag(final TagData tagData) {
+ managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames().add(tagData.getName());
+ tagPanelLayout.setAssignedTag(tagData);
}
@Override
- protected void unassignTag(final String tagName) {
- managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames().remove(tagName);
- }
-
- @Override
- protected String getTagStyleName() {
- return "target-tag-";
- }
-
- @Override
- protected String getTokenInputPrompt() {
- return i18n.getMessage("combo.type.tag.name");
+ protected void unassignTag(final TagData tagData) {
+ managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames().remove(tagData.getName());
+ tagPanelLayout.removeAssignedTag(tagData);
}
@Override
@@ -61,29 +53,32 @@ public class TargetBulkTokenTags extends AbstractTargetTagToken {
return checker.hasCreateTargetPermission();
}
- @Override
- public void displayAlreadyAssignedTags() {
- removePreviouslyAddedTokens();
- addAlreadySelectedTags();
+ /**
+ * Initializes the Tags
+ */
+ public void initializeTags() {
+ repopulateTags();
}
- protected void addAlreadySelectedTags() {
- for (final String tagName : managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames()) {
- tagManagement.getByName(tagName).map(TargetTag::getId).ifPresent(this::addNewToken);
- }
+ public boolean isTagSelectedForAssignment() {
+ return !tagPanelLayout.getAssignedTags().isEmpty();
}
@Override
- protected void populateContainer() {
- container.removeAllItems();
- tagDetails.clear();
- for (final TargetTag tag : tagManagement.findAll(PageRequest.of(0, MAX_TAGS))) {
- setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour());
- }
-
+ protected List getAllTags() {
+ return tagManagement.findAll(PageRequest.of(0, MAX_TAG_QUERY)).stream()
+ .map(tag -> new TagData(tag.getId(), tag.getName(), tag.getColour())).collect(Collectors.toList());
}
- public Map getTokensAdded() {
- return tokensAdded;
+ @Override
+ protected List getAssignedTags() {
+ // this view doesn't belong to a specific target, so the current
+ // selected target in the target table is ignored and therefore there
+ // are no assigned tags
+ return Collections.emptyList();
+ }
+
+ public List getSelectedTagsForAssignment() {
+ return tagPanelLayout.getAssignedTags().stream().map(tagDetailsByName::get).collect(Collectors.toList());
}
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java
index 7f0ab9ae6..93e0a3fe7 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java
@@ -21,6 +21,7 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder;
import org.eclipse.hawkbit.ui.common.builder.WindowBuilder;
+import org.eclipse.hawkbit.ui.common.tagdetails.TagPanelLayout;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder;
import org.eclipse.hawkbit.ui.management.dstable.DistributionBeanQuery;
@@ -39,7 +40,6 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBus.UIEventBus;
-import org.vaadin.tokenfield.TokenField;
import com.google.common.collect.Maps;
import com.vaadin.data.Container;
@@ -220,10 +220,11 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
}
private VerticalLayout getTokenFieldLayout() {
- final TokenField tokenField = targetBulkTokenTags.getTokenField();
+ final TagPanelLayout tagPanelLayout = targetBulkTokenTags.getTagPanel();
+ tagPanelLayout.setMargin(false);
final VerticalLayout tokenLayout = SPUIComponentProvider.getDetailTabLayout();
tokenLayout.addStyleName("bulk-target-tags-layout");
- tokenLayout.addComponent(tokenField);
+ tokenLayout.addComponent(tagPanelLayout);
tokenLayout.setSpacing(false);
tokenLayout.setMargin(false);
tokenLayout.setSizeFull();
@@ -249,7 +250,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
managementUIState.getDistributionTableFilters().isNoTagSelected());
queryConfiguration.put(SPUIDefinitions.FILTER_BY_TAG,
- managementUIState.getDistributionTableFilters().getDistSetTags());
+ managementUIState.getDistributionTableFilters().getClickedDistSetTags());
final BeanQueryFactory distributionQF = new BeanQueryFactory<>(
DistributionBeanQuery.class);
@@ -286,8 +287,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
public void resetComponents() {
dsNamecomboBox.clear();
descTextArea.clear();
- targetBulkTokenTags.getTokenField().clear();
- targetBulkTokenTags.populateContainer();
+ targetBulkTokenTags.initializeTags();
progressBar.setValue(0F);
progressBar.setVisible(false);
managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(0F);
@@ -308,12 +308,11 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent {
* Restore the target bulk upload layout field values.
*/
public void restoreComponentsValue() {
- targetBulkTokenTags.populateContainer();
final TargetBulkUpload targetBulkUpload = managementUIState.getTargetTableFilters().getBulkUpload();
progressBar.setValue(targetBulkUpload.getProgressBarCurrentValue());
dsNamecomboBox.setValue(targetBulkUpload.getDsNameAndVersion());
descTextArea.setValue(targetBulkUpload.getDescription());
- targetBulkTokenTags.addAlreadySelectedTags();
+ targetBulkTokenTags.initializeTags();
if (targetBulkUpload.getProgressBarCurrentValue() >= 1) {
targetsCountLabel.setVisible(true);
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java
index 71189f0a8..982ba28d2 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java
@@ -221,13 +221,21 @@ public class TargetTable extends AbstractTable {
@EventBusListenerMethod(scope = EventScope.UI)
void onEvent(final ManagementUIEvent managementUIEvent) {
UI.getCurrent().access(() -> {
- if (managementUIEvent == ManagementUIEvent.UNASSIGN_TARGET_TAG
- || managementUIEvent == ManagementUIEvent.ASSIGN_TARGET_TAG) {
+ if (tableIsFilteredByTagsAndTagWasUnassignedFromTarget(managementUIEvent)
+ || tableIsFilteredByNoTagAndTagWasAssignedToTarget(managementUIEvent)) {
refreshFilter();
}
});
}
+ private boolean tableIsFilteredByTagsAndTagWasUnassignedFromTarget(final ManagementUIEvent managementUIEvent) {
+ return managementUIEvent == ManagementUIEvent.UNASSIGN_TARGET_TAG && isFilteredByTags();
+ }
+
+ private boolean tableIsFilteredByNoTagAndTagWasAssignedToTarget(final ManagementUIEvent managementUIEvent) {
+ return managementUIEvent == ManagementUIEvent.ASSIGN_TARGET_TAG && isFilteredByNoTag();
+ }
+
@EventBusListenerMethod(scope = EventScope.UI)
void onEvent(final SaveActionWindowEvent event) {
if (event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) {
@@ -842,6 +850,10 @@ public class TargetTable extends AbstractTable {
return !managementUIState.getTargetTableFilters().getClickedTargetTags().isEmpty();
}
+ private boolean isFilteredByNoTag() {
+ return managementUIState.getTargetTableFilters().isNoTagSelected();
+ }
+
private void assignDsToTarget(final DragAndDropEvent event) {
final TableTransferable transferable = (TableTransferable) event.getTransferable();
final AbstractTable> source = (AbstractTable>) transferable.getSourceComponent();
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/GroupsPieChart.gwt.xml b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/GroupsPieChart.gwt.xml
index bf6f30341..010971890 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/GroupsPieChart.gwt.xml
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/GroupsPieChart.gwt.xml
@@ -16,7 +16,7 @@
-
+
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java
index 9b5e67a94..a521fb071 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java
@@ -119,6 +119,14 @@ public final class SPUIStyleDefinitions {
*/
public static final String SIMPLE_FILTER_HEADER = "simple-tag-filter-header";
+ /**
+ * Simple tag filter header layout.
+ */
+ public static final String TAG_BUTTON_WITH_BACKGROUND = "button-tag-with-background";
+ /**
+ * Simple tag filter header layout.
+ */
+ public static final String ASSIGN_TAG_BUTTON = "button-assign-tag";
/**
* Style to disable top border.
*/
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java
index b96e67f48..aa4fbbd35 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java
@@ -693,6 +693,16 @@ public final class UIComponentIdProvider {
*/
public static final String LINK_USERMANAGEMENT = "link.usermanagement";
+ /**
+ * Prefix for assigned tag button ids.
+ */
+ public static final String ASSIGNED_TAG_ID_PREFIX = "tag.assigned.";
+
+ /**
+ * Assign tag icon id.
+ */
+ public static final String ASSIGN_TAG = "tag.assign";
+
/**
* New Target tag add icon id.
*/
@@ -973,7 +983,10 @@ public final class UIComponentIdProvider {
* Rollout group remove button id
*/
public static final String ROLLOUT_GROUP_REMOVE_ID = "rollout.group.remove.id";
-
+ /**
+ * Tag selection combo id.
+ */
+ public static final String TAG_SELECTION_ID = "tag.selection.id";
/**
* Rollout distribution set combo id.
*/
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIMessageIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIMessageIdProvider.java
index 05e874c9f..a810877df 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIMessageIdProvider.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIMessageIdProvider.java
@@ -113,6 +113,12 @@ public final class UIMessageIdProvider {
public static final String TOOLTIP_SHOW_TAGS = "tooltip.showTags";
+ public static final String TOOLTIP_ASSIGN_TAG = "tooltip.assignTag";
+
+ public static final String TOOLTIP_SELECT_TAG = "tooltip.selectTag";
+
+ public static final String TOOLTIP_CLICK_TO_REMOVE = "tooltip.click.to.remove";
+
public static final String TOOLTIP_BULK_UPLOAD = "tooltip.bulkUpload";
public static final String TOOLTIP_CONFIGURE = "tooltip.configure";
diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-window.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-window.scss
index cb936685b..809547aa8 100644
--- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-window.scss
+++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-window.scss
@@ -182,6 +182,7 @@
border-right: 1px solid #bfc3c8;
border-bottom: 1px solid #bfc3c8;
border-radius: 4px;
+ overflow-y: auto;
}
.bulk-upload-ds-combo{
margin-top: 2px !important;
diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss
index c268df035..7a1231e12 100644
--- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss
+++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss
@@ -121,4 +121,12 @@
#target\.tag\.drop\.area .v-slot-icon-only {
height: 32px;
}
+
+ .button-tag-with-background {
+ background-color: lightgrey !important;
+ }
+
+ .button-assign-tag {
+ padding-top: 5px;
+ }
}
diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties
index c67d0959f..613428475 100644
--- a/hawkbit-ui/src/main/resources/messages.properties
+++ b/hawkbit-ui/src/main/resources/messages.properties
@@ -298,6 +298,7 @@ tooltip.timeforced.forced.since=Auto forced since {0}
tooltip.check.for.mandatory=Check to make Mandatory
tooltip.artifact.icon=Show Artifact Details
tooltip.click.to.edit = Click to edit
+tooltip.click.to.remove = Click to remove
tooltip.metadata.icon = Manage Metadata..
tooltip.next.maintenance.window = next on {0}
tooltip.target.attributes.update.request = Request attributes update
@@ -334,6 +335,8 @@ tooltip.maximize = Maximize
tooltip.minimize = Minimize
tooltip.bulkUpload = Bulk Upload..
tooltip.showTags = Show Tags
+tooltip.assignTag = Assign Tag
+tooltip.selectTag = Select Tag
tooltip.update = Edit..
tooltip.reset = Reset
tooltip.configure = Configure..
@@ -609,7 +612,6 @@ header.caption.typename = SoftwareModuleType
header.caption.softwaremodule = SoftwareModule
message.sw.unassigned = Software Module {0} successfully unassigned
header.caption.upload.details = Upload details
-combo.type.tag.name = Type tag name
label.yes = Yes
label.no = No
diff --git a/pom.xml b/pom.xml
index 7f7e5b66a..9f4dd376a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -152,8 +152,7 @@
7.7.13
${vaadin.version}
7.6.1.3
- 2.2.0
- 7.0.1
+ 2.2.0
2.0.0
@@ -594,11 +593,6 @@
flexibleoptiongroup
${vaadin.addon.flexibleoptiongroup.version}
-
- org.vaadin.addons
- tokenfield
- ${vaadin.addon.tokenfield.version}
-
org.vaadin.alump.distributionbar
dbar-addon