Implement target type CRUD UI operations (#1184)
* implement target type CRUD UI operations Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix licenses Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * code clean up Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * code clean up Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * refactor proxy target type Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * refactor proxy target type Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * update class description Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix review comments Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix sonar issue Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix sonar issue Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix sonar issue Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * fix showing assigned ds types Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io> * remove unused import Signed-off-by: Virginijus Kandrotas <Virginijus.Kandrotas@bosch.io>
This commit is contained in:
committed by
GitHub
parent
d5661d2fe2
commit
d80d0d6349
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.data.mappers;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
|
||||
/**
|
||||
* Maps {@link TargetType} entities, fetched from backend, to the {@link ProxyTargetType}
|
||||
* entities.
|
||||
*
|
||||
* @param <T>
|
||||
* Generic type of TargetType
|
||||
*/
|
||||
public class TargetTypeToProxyTargetTypeMapper<T extends TargetType> extends AbstractNamedEntityToProxyNamedEntityMapper<ProxyTargetType, T> {
|
||||
|
||||
@Override
|
||||
public ProxyTargetType map(final T targetType) {
|
||||
final ProxyTargetType proxyTargetType = new ProxyTargetType();
|
||||
|
||||
mapNamedEntityAttributes(targetType, proxyTargetType);
|
||||
|
||||
proxyTargetType.setColour(targetType.getColour());
|
||||
|
||||
return proxyTargetType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.springframework.util.StringUtils;
|
||||
* Data provider for {@link TargetTypeManagement}, which dynamically loads a
|
||||
* batch of {@link TargetType} entities from backend and maps them to
|
||||
* corresponding output type.
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* output type
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.data.proxies;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import java.util.Set;
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Proxy for {@link TargetType}.
|
||||
*/
|
||||
public class ProxyTargetType extends ProxyFilterButton {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private boolean isNoTargetType;
|
||||
|
||||
private Set<ProxyType> selectedDsTypes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ProxyTargetType() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ProxyTargetType
|
||||
*
|
||||
* @param id
|
||||
* Type id
|
||||
* @param name
|
||||
* Type name
|
||||
* @param colour
|
||||
* Type colour
|
||||
*/
|
||||
public ProxyTargetType(final Long id, final String name, final String colour) {
|
||||
setId(id);
|
||||
setName(name);
|
||||
setColour(colour);
|
||||
}
|
||||
|
||||
public boolean isNoTargetType() {
|
||||
return isNoTargetType;
|
||||
}
|
||||
|
||||
public void setNoTargetType(boolean noTargetType) {
|
||||
isNoTargetType = noTargetType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selected distribution sets types
|
||||
*
|
||||
* @return selectedDsTypes
|
||||
*/
|
||||
public Set<ProxyType> getSelectedDsTypes() {
|
||||
return selectedDsTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selectedDsTypes
|
||||
*
|
||||
* @param selectedDsTypes
|
||||
* Selected distribution sets types
|
||||
*/
|
||||
public void setSelectedDsTypes(final Set<ProxyType> selectedDsTypes) {
|
||||
this.selectedDsTypes = selectedDsTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ProxyTargetType other = (ProxyTargetType) obj;
|
||||
return Objects.equals(this.getId(), other.getId()) && Objects.equals(this.getName(), other.getName())
|
||||
&& Objects.equals(this.getColour(), other.getColour());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getId(), getName(), getColour());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this).add("id", getId()).add("name", getName()).add("color", getColour())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -12,5 +12,5 @@ package org.eclipse.hawkbit.ui.common.event;
|
||||
* Enum constants for filter type
|
||||
*/
|
||||
public enum FilterType {
|
||||
SEARCH, TYPE, TAG, NO_TAG, STATUS, OVERDUE, QUERY, DISTRIBUTION, MASTER;
|
||||
SEARCH, TYPE, TARGET_TYPE, TAG, NO_TAG, STATUS, OVERDUE, QUERY, DISTRIBUTION, MASTER;
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ package org.eclipse.hawkbit.ui.common.event;
|
||||
* Enum constants for target filter tab change event
|
||||
*/
|
||||
public enum TargetFilterTabChangedEventPayload {
|
||||
SIMPLE, CUSTOM;
|
||||
SIMPLE, CUSTOM, TARGET_TYPE;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.common.filterlayout;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTag;
|
||||
@@ -32,10 +34,6 @@ import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
|
||||
/**
|
||||
* Class for defining the tag filter buttons.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.filterlayout;
|
||||
|
||||
import com.vaadin.ui.Button;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventTopics;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventView;
|
||||
import org.eclipse.hawkbit.ui.common.event.FilterChangedEventPayload;
|
||||
import org.eclipse.hawkbit.ui.common.event.FilterType;
|
||||
import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtonClickBehaviour.ClickBehaviourType;
|
||||
import org.eclipse.hawkbit.ui.common.state.TagFilterLayoutUiState;
|
||||
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.UIMessageIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Class for defining the type filter buttons.
|
||||
*/
|
||||
public abstract class AbstractTargetTypeFilterButtons extends AbstractFilterButtons<ProxyTargetType, Void> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final TagFilterLayoutUiState tagFilterLayoutUiState;
|
||||
|
||||
protected final UINotification uiNotification;
|
||||
private final Button noTargetTypeButton;
|
||||
|
||||
private final TargetTypeFilterButtonClick targetTypeFilterButtonClick;
|
||||
|
||||
/**
|
||||
* Constructor for AbstractTargetTypeFilterButtons
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param tagFilterLayoutUiState
|
||||
* TagFilterLayoutUiState
|
||||
*/
|
||||
protected AbstractTargetTypeFilterButtons(final CommonUiDependencies uiDependencies,
|
||||
final TagFilterLayoutUiState tagFilterLayoutUiState) {
|
||||
super(uiDependencies.getEventBus(), uiDependencies.getI18n(), uiDependencies.getUiNotification(),
|
||||
uiDependencies.getPermChecker());
|
||||
|
||||
this.uiNotification = uiDependencies.getUiNotification();
|
||||
this.tagFilterLayoutUiState = tagFilterLayoutUiState;
|
||||
this.noTargetTypeButton = buildNoTargetTypeButton();
|
||||
this.targetTypeFilterButtonClick = new TargetTypeFilterButtonClick(this::onFilterChangedEvent);
|
||||
}
|
||||
|
||||
private Button buildNoTargetTypeButton() {
|
||||
final Button noTargetType = SPUIComponentProvider.getButton(
|
||||
getFilterButtonIdPrefix() + "." + SPUIDefinitions.NO_TARGET_TYPE_BUTTON_ID,
|
||||
i18n.getMessage(UIMessageIdProvider.LABEL_NO_TARGET_TYPE),
|
||||
i18n.getMessage(UIMessageIdProvider.TOOLTIP_CLICK_TO_FILTER), "button-no-tag", false, null,
|
||||
SPUITagButtonStyle.class);
|
||||
|
||||
final ProxyTargetType proxyTargetType = new ProxyTargetType();
|
||||
proxyTargetType.setNoTargetType(true);
|
||||
|
||||
return noTargetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TargetTypeFilterButtonClick getFilterButtonClickBehaviour(){
|
||||
return targetTypeFilterButtonClick;
|
||||
}
|
||||
|
||||
private void onFilterChangedEvent(final ProxyTargetType targetType,
|
||||
final ClickBehaviourType clickType) {
|
||||
final Long targetTypeId = ClickBehaviourType.CLICKED == clickType ? targetType.getId()
|
||||
: null;
|
||||
publishFilterChangedEvent(targetTypeId);
|
||||
}
|
||||
|
||||
private void publishFilterChangedEvent(final Long targetTypeId) {
|
||||
eventBus.publish(EventTopics.FILTER_CHANGED, this, new FilterChangedEventPayload<>(ProxyTarget.class,
|
||||
FilterType.TARGET_TYPE, targetTypeId, EventView.DEPLOYMENT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides type of the master entity.
|
||||
*
|
||||
* @return type of the master entity
|
||||
*/
|
||||
protected abstract Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType();
|
||||
|
||||
/**
|
||||
* Provides event view filter.
|
||||
*
|
||||
* @return event view filter.
|
||||
*/
|
||||
protected abstract EventView getView();
|
||||
|
||||
/**
|
||||
* Target type deletion operation.
|
||||
*
|
||||
* @param targetTypeToDelete
|
||||
* target type to delete
|
||||
*
|
||||
* @return true if target type is deleted, in error case false.
|
||||
*/
|
||||
protected abstract boolean deleteTargetType(final ProxyTargetType targetTypeToDelete);
|
||||
|
||||
/**
|
||||
* @return Button component of no target type
|
||||
*/
|
||||
public Button getNoTargetTypeButton() {
|
||||
return noTargetTypeButton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState() {
|
||||
final Map<Long, String> targetTypesToRestore = tagFilterLayoutUiState.getClickedTagIdsWithName();
|
||||
|
||||
if (!CollectionUtils.isEmpty(targetTypesToRestore)) {
|
||||
removeNonExistingTargetTypes(targetTypesToRestore);
|
||||
}
|
||||
|
||||
if (tagFilterLayoutUiState.isNoTagClicked()) {
|
||||
getNoTargetTypeButton().addStyleName(SPUIStyleDefinitions.SP_NO_TAG_BTN_CLICKED_STYLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeNonExistingTargetTypes(final Map<Long, String> targetTypeIdsWithName) {
|
||||
final Collection<Long> targetTypeIds = targetTypeIdsWithName.keySet();
|
||||
final Collection<Long> existingTargetTypeIds = filterExistingTargetTypeIds(targetTypeIds);
|
||||
if (targetTypeIds.size() != existingTargetTypeIds.size()) {
|
||||
targetTypeIds.retainAll(existingTargetTypeIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out non-existant target type by ids.
|
||||
*
|
||||
* @param targetTypeIds
|
||||
* provided target type ids
|
||||
* @return filtered list of existing target type ids
|
||||
*/
|
||||
protected abstract Collection<Long> filterExistingTargetTypeIds(final Collection<Long> targetTypeIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.filterlayout;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
|
||||
/**
|
||||
* Button click behaviour of target type filter buttons layout.
|
||||
*/
|
||||
public class TargetTypeFilterButtonClick extends AbstractFilterSingleButtonClick<ProxyTargetType> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final transient BiConsumer<ProxyTargetType, ClickBehaviourType> filterChangedCallback;
|
||||
|
||||
TargetTypeFilterButtonClick(final BiConsumer<ProxyTargetType, ClickBehaviourType> filterChangedCallback) {
|
||||
this.filterChangedCallback = filterChangedCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filterUnClicked(ProxyTargetType clickedFilter) {
|
||||
filterChangedCallback.accept(clickedFilter, ClickBehaviourType.UNCLICKED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void filterClicked(ProxyTargetType clickedFilter) {
|
||||
filterChangedCallback.accept(clickedFilter, ClickBehaviourType.CLICKED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilterPreviouslyClicked(final ProxyTargetType clickedFilter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.targettype;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import org.eclipse.hawkbit.ui.common.EntityValidator;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Validator used in TargetType window controllers to validate {@link ProxyTargetType}.
|
||||
*/
|
||||
public class ProxyTargetTypeValidator extends EntityValidator {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
*/
|
||||
public ProxyTargetTypeValidator(final CommonUiDependencies uiDependencies) {
|
||||
super(uiDependencies);
|
||||
}
|
||||
|
||||
public boolean isEntityValid(final ProxyTargetType entity, final BooleanSupplier duplicateCheck) {
|
||||
if (!StringUtils.hasText(entity.getName())) {
|
||||
displayValidationError("message.error.missing.typename");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (duplicateCheck.getAsBoolean()) {
|
||||
final String trimmedName = StringUtils.trimWhitespace(entity.getName());
|
||||
displayValidationError("message.type.duplicate.check", trimmedName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,11 +8,17 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.management;
|
||||
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.server.Page.BrowserWindowResizeEvent;
|
||||
import com.vaadin.server.Page.BrowserWindowResizeListener;
|
||||
import com.vaadin.spring.annotation.SpringView;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Layout;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetInvalidationManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
@@ -52,14 +58,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.vaadin.spring.events.EventBus.UIEventBus;
|
||||
|
||||
import com.vaadin.server.Page;
|
||||
import com.vaadin.server.Page.BrowserWindowResizeEvent;
|
||||
import com.vaadin.server.Page.BrowserWindowResizeListener;
|
||||
import com.vaadin.spring.annotation.SpringView;
|
||||
import com.vaadin.spring.annotation.UIScope;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Layout;
|
||||
|
||||
/**
|
||||
* Target status and deployment management view
|
||||
*/
|
||||
@@ -107,8 +105,8 @@ public class DeploymentView extends AbstractEventListenersAwareView implements B
|
||||
|
||||
if (permChecker.hasTargetReadPermission()) {
|
||||
this.targetTagFilterLayout = new TargetTagFilterLayout(uiDependencies, managementUIState,
|
||||
targetFilterQueryManagement, targetTagManagement, targetManagement,
|
||||
managementUIState.getTargetTagFilterLayoutUiState());
|
||||
targetFilterQueryManagement, targetTypeManagement, targetTagManagement, targetManagement,
|
||||
managementUIState.getTargetTagFilterLayoutUiState(), distributionSetTypeManagement);
|
||||
|
||||
this.targetGridLayout = new TargetGridLayout(uiDependencies, targetManagement, targetTypeManagement, deploymentManagement,
|
||||
uiProperties, targetTagManagement, distributionSetManagement, uiExecutor, configManagement,
|
||||
|
||||
@@ -46,13 +46,13 @@ public class TargetTagWindowBuilder extends AbstractEntityWindowBuilder<ProxyTag
|
||||
@Override
|
||||
public Window getWindowForAdd() {
|
||||
return getWindowForNewEntity(new AddTargetTagWindowController(uiDependencies, targetTagManagement,
|
||||
new TagWindowLayout<ProxyTag>(uiDependencies)));
|
||||
new TagWindowLayout<>(uiDependencies)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getWindowForUpdate(final ProxyTag proxyTag) {
|
||||
return getWindowForEntity(proxyTag, new UpdateTargetTagWindowController(uiDependencies, targetTagManagement,
|
||||
new TagWindowLayout<ProxyTag>(uiDependencies)));
|
||||
new TagWindowLayout<>(uiDependencies)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,21 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.management.targettag.filter;
|
||||
|
||||
import com.vaadin.ui.Accordion;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTag;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventLayout;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventTopics;
|
||||
@@ -29,16 +34,12 @@ import org.eclipse.hawkbit.ui.common.layout.listener.GridActionsVisibilityListen
|
||||
import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGenericSupport;
|
||||
import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridRefreshAwareSupport;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.TargetTagWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.targettype.TargetTypeWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
import org.vaadin.spring.events.EventBus.UIEventBus;
|
||||
|
||||
import com.vaadin.ui.Accordion;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Target filter tabsheet with 'simple' and 'complex' filter options.
|
||||
*/
|
||||
@@ -51,33 +52,41 @@ public class MultipleTargetFilter extends Accordion {
|
||||
private final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState;
|
||||
|
||||
private final VerticalLayout simpleFilterTab;
|
||||
private final VerticalLayout targetTypeFilterTab;
|
||||
|
||||
private final TargetTagFilterButtons filterByButtons;
|
||||
private final TargetTypeFilterButtons targetTypeFilterButtons;
|
||||
private final FilterByStatusLayout filterByStatusFooter;
|
||||
private final TargetFilterQueryButtons customFilterTab;
|
||||
|
||||
private final transient GridActionsVisibilityListener gridActionsVisibilityListener;
|
||||
private final transient GridActionsVisibilityListener targetTagGridActionsVisibilityListener;
|
||||
private final transient GridActionsVisibilityListener targetTypeGridActionsVisibilityListener;
|
||||
private final transient EntityModifiedListener<ProxyTag> entityTagModifiedListener;
|
||||
private final transient EntityModifiedListener<ProxyTargetFilterQuery> entityFilterQueryModifiedListener;
|
||||
|
||||
private final transient EntityModifiedListener<ProxyTargetType> entityTargetTypeModifiedListener;
|
||||
|
||||
MultipleTargetFilter(final CommonUiDependencies uiDependencies,
|
||||
final TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState,
|
||||
final TargetTagWindowBuilder targetTagWindowBuilder) {
|
||||
final TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState,
|
||||
final TargetTagWindowBuilder targetTagWindowBuilder, final TargetTypeWindowBuilder targetTypeWindowBuilder, final TargetTypeManagement targetTypeManagement) {
|
||||
this.i18n = uiDependencies.getI18n();
|
||||
this.eventBus = uiDependencies.getEventBus();
|
||||
this.targetTagFilterLayoutUiState = targetTagFilterLayoutUiState;
|
||||
|
||||
this.filterByButtons = new TargetTagFilterButtons(uiDependencies, targetTagManagement, targetManagement,
|
||||
targetTagFilterLayoutUiState, targetTagWindowBuilder);
|
||||
this.targetTypeFilterButtons = new TargetTypeFilterButtons(uiDependencies, targetTypeManagement, targetTagFilterLayoutUiState, targetTypeWindowBuilder);
|
||||
this.filterByStatusFooter = new FilterByStatusLayout(i18n, eventBus, targetTagFilterLayoutUiState);
|
||||
this.simpleFilterTab = buildSimpleFilterTab();
|
||||
this.targetTypeFilterTab = buildTargetTypeFilterTab();
|
||||
this.customFilterTab = new TargetFilterQueryButtons(i18n, eventBus, targetFilterQueryManagement,
|
||||
targetTagFilterLayoutUiState);
|
||||
|
||||
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.TARGET_TAG_FILTER,
|
||||
EventView.DEPLOYMENT);
|
||||
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(eventBus, layoutViewAware,
|
||||
this.targetTagGridActionsVisibilityListener = new GridActionsVisibilityListener(eventBus, layoutViewAware,
|
||||
filterByButtons::hideActionColumns, filterByButtons::showEditColumn, filterByButtons::showDeleteColumn);
|
||||
this.entityTagModifiedListener = new EntityModifiedListener.Builder<>(eventBus, ProxyTag.class)
|
||||
.parentEntityType(ProxyTarget.class).viewAware(layoutViewAware)
|
||||
@@ -86,6 +95,12 @@ public class MultipleTargetFilter extends Accordion {
|
||||
ProxyTargetFilterQuery.class).viewAware(layoutViewAware)
|
||||
.entityModifiedAwareSupports(getFilterQueryModifiedAwareSupports()).build();
|
||||
|
||||
this.targetTypeGridActionsVisibilityListener = new GridActionsVisibilityListener(eventBus, layoutViewAware,
|
||||
targetTypeFilterButtons::hideActionColumns, targetTypeFilterButtons::showEditColumn, targetTypeFilterButtons::showDeleteColumn);
|
||||
this.entityTargetTypeModifiedListener = new EntityModifiedListener.Builder<>(eventBus, ProxyTargetType.class)
|
||||
.parentEntityType(ProxyTarget.class).viewAware(layoutViewAware)
|
||||
.entityModifiedAwareSupports(getTargetTypeModifiedAwareSupports()).build();
|
||||
|
||||
init();
|
||||
addTabs();
|
||||
addSelectedTabChangeListener(event -> selectedTabChanged());
|
||||
@@ -119,11 +134,40 @@ public class MultipleTargetFilter extends Accordion {
|
||||
return simpleTab;
|
||||
}
|
||||
|
||||
private VerticalLayout buildTargetTypeFilterTab() {
|
||||
final VerticalLayout targetTypeTab = new VerticalLayout();
|
||||
targetTypeTab.setSpacing(false);
|
||||
targetTypeTab.setMargin(false);
|
||||
targetTypeTab.setSizeFull();
|
||||
targetTypeTab.setCaption(i18n.getMessage("caption.filter.type"));
|
||||
targetTypeTab.addStyleName(SPUIStyleDefinitions.TARGET_TYPE_FILTER_HEADER);
|
||||
|
||||
final VerticalLayout targetTypeGridLayout = new VerticalLayout();
|
||||
targetTypeGridLayout.setSpacing(false);
|
||||
targetTypeGridLayout.setMargin(false);
|
||||
targetTypeGridLayout.setSizeFull();
|
||||
targetTypeGridLayout.setId(UIComponentIdProvider.TARGET_TYPE_DROP_AREA_ID);
|
||||
targetTypeGridLayout.addComponent(targetTypeFilterButtons.getNoTargetTypeButton());
|
||||
targetTypeGridLayout.addComponent(targetTypeFilterButtons);
|
||||
targetTypeGridLayout.setComponentAlignment(targetTypeFilterButtons, Alignment.MIDDLE_CENTER);
|
||||
targetTypeGridLayout.setExpandRatio(targetTypeFilterButtons, 1.0F);
|
||||
|
||||
targetTypeTab.addComponent(targetTypeGridLayout);
|
||||
targetTypeTab.setExpandRatio(targetTypeGridLayout, 1.0F);
|
||||
|
||||
return targetTypeTab;
|
||||
}
|
||||
|
||||
private List<EntityModifiedAwareSupport> getTagModifiedAwareSupports() {
|
||||
return Arrays.asList(EntityModifiedGridRefreshAwareSupport.of(filterByButtons::refreshAll),
|
||||
EntityModifiedGenericSupport.of(null, null, filterByButtons::resetFilterOnTagsDeleted));
|
||||
}
|
||||
|
||||
private List<EntityModifiedAwareSupport> getTargetTypeModifiedAwareSupports() {
|
||||
return Arrays.asList(EntityModifiedGridRefreshAwareSupport.of(targetTypeFilterButtons::refreshAll),
|
||||
EntityModifiedGenericSupport.of(null, null, null));
|
||||
}
|
||||
|
||||
private List<EntityModifiedAwareSupport> getFilterQueryModifiedAwareSupports() {
|
||||
return Arrays.asList(EntityModifiedGridRefreshAwareSupport.of(customFilterTab::refreshAll),
|
||||
EntityModifiedGenericSupport.of(null, customFilterTab::reselectFilterOnTfqUpdated,
|
||||
@@ -138,6 +182,7 @@ public class MultipleTargetFilter extends Accordion {
|
||||
private void addTabs() {
|
||||
addTab(simpleFilterTab).setId(UIComponentIdProvider.SIMPLE_FILTER_ACCORDION_TAB);
|
||||
addTab(customFilterTab).setId(UIComponentIdProvider.CUSTOM_FILTER_ACCORDION_TAB);
|
||||
addTab(targetTypeFilterTab).setId(UIComponentIdProvider.TARGET_TYPE_FILTER_ACCORDION_TAB);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,20 +191,30 @@ public class MultipleTargetFilter extends Accordion {
|
||||
public void selectedTabChanged() {
|
||||
final String selectedTabId = getTab(getSelectedTab()).getId();
|
||||
|
||||
|
||||
if (UIComponentIdProvider.SIMPLE_FILTER_ACCORDION_TAB.equals(selectedTabId)) {
|
||||
customFilterTab.clearAppliedTargetFilterQuery();
|
||||
|
||||
targetTagFilterLayoutUiState.setCustomFilterTabSelected(false);
|
||||
targetTagFilterLayoutUiState.setTargetTypeFilterTabSelected(false);
|
||||
|
||||
eventBus.publish(EventTopics.TARGET_FILTER_TAB_CHANGED, this, TargetFilterTabChangedEventPayload.SIMPLE);
|
||||
} else {
|
||||
}
|
||||
if (UIComponentIdProvider.TARGET_TYPE_FILTER_ACCORDION_TAB.equals(selectedTabId)){
|
||||
targetTagFilterLayoutUiState.setTargetTypeFilterTabSelected(true);
|
||||
targetTagFilterLayoutUiState.setCustomFilterTabSelected(false);
|
||||
eventBus.publish(EventTopics.TARGET_FILTER_TAB_CHANGED, this, TargetFilterTabChangedEventPayload.TARGET_TYPE);
|
||||
}
|
||||
if (UIComponentIdProvider.CUSTOM_FILTER_ACCORDION_TAB.equals(selectedTabId)){
|
||||
filterByButtons.clearTargetTagFilters();
|
||||
filterByStatusFooter.clearStatusAndOverdueFilters();
|
||||
|
||||
targetTagFilterLayoutUiState.setCustomFilterTabSelected(true);
|
||||
targetTagFilterLayoutUiState.setTargetTypeFilterTabSelected(false);
|
||||
|
||||
eventBus.publish(EventTopics.TARGET_FILTER_TAB_CHANGED, this, TargetFilterTabChangedEventPayload.CUSTOM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,12 +225,19 @@ public class MultipleTargetFilter extends Accordion {
|
||||
customFilterTab.restoreState();
|
||||
|
||||
setSelectedTab(customFilterTab);
|
||||
} else {
|
||||
}
|
||||
if (targetTagFilterLayoutUiState.isCustomFilterTabSelected()) {
|
||||
filterByButtons.restoreState();
|
||||
filterByStatusFooter.restoreState();
|
||||
|
||||
setSelectedTab(simpleFilterTab);
|
||||
}
|
||||
if (targetTagFilterLayoutUiState.isTargetTypeFilterTabSelected()) {
|
||||
filterByButtons.restoreState();
|
||||
filterByStatusFooter.restoreState();
|
||||
|
||||
setSelectedTab(targetTypeFilterTab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,17 +252,21 @@ public class MultipleTargetFilter extends Accordion {
|
||||
* Subscribe event listeners
|
||||
*/
|
||||
public void subscribeListeners() {
|
||||
gridActionsVisibilityListener.subscribe();
|
||||
targetTagGridActionsVisibilityListener.subscribe();
|
||||
entityTagModifiedListener.subscribe();
|
||||
entityFilterQueryModifiedListener.subscribe();
|
||||
targetTypeGridActionsVisibilityListener.subscribe();
|
||||
entityTargetTypeModifiedListener.subscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe event listeners
|
||||
*/
|
||||
public void unsubscribeListeners() {
|
||||
gridActionsVisibilityListener.unsubscribe();
|
||||
targetTagGridActionsVisibilityListener.unsubscribe();
|
||||
entityTagModifiedListener.unsubscribe();
|
||||
entityFilterQueryModifiedListener.unsubscribe();
|
||||
targetTypeGridActionsVisibilityListener.unsubscribe();
|
||||
entityTargetTypeModifiedListener.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.eclipse.hawkbit.ui.common.event.EventLayout;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventView;
|
||||
import org.eclipse.hawkbit.ui.common.grid.header.AbstractFilterHeader;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.TargetTagWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.targettype.TargetTypeWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
|
||||
|
||||
@@ -28,23 +29,26 @@ public class TargetTagFilterHeader extends AbstractFilterHeader {
|
||||
|
||||
private final transient TargetTagWindowBuilder targetTagWindowBuilder;
|
||||
|
||||
private final transient TargetTypeWindowBuilder targetTypeWindowBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for TargetTagFilterHeader
|
||||
*
|
||||
* @param uiDependencies
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param targetTagFilterLayoutUiState
|
||||
* TargetTagFilterLayoutUiState
|
||||
* @param targetTagWindowBuilder
|
||||
* TargetTagWindowBuilder
|
||||
* @param targetTypeWindowBuilder
|
||||
*/
|
||||
public TargetTagFilterHeader(final CommonUiDependencies uiDependencies,
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState,
|
||||
final TargetTagWindowBuilder targetTagWindowBuilder) {
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState,
|
||||
final TargetTagWindowBuilder targetTagWindowBuilder, TargetTypeWindowBuilder targetTypeWindowBuilder) {
|
||||
super(uiDependencies.getI18n(), uiDependencies.getPermChecker(), uiDependencies.getEventBus());
|
||||
|
||||
this.targetTagFilterLayoutUiState = targetTagFilterLayoutUiState;
|
||||
this.targetTagWindowBuilder = targetTagWindowBuilder;
|
||||
this.targetTypeWindowBuilder = targetTypeWindowBuilder;
|
||||
|
||||
buildHeader();
|
||||
}
|
||||
@@ -70,11 +74,17 @@ public class TargetTagFilterHeader extends AbstractFilterHeader {
|
||||
|
||||
@Override
|
||||
protected Window getWindowForAdd() {
|
||||
if (targetTagFilterLayoutUiState.isTargetTypeFilterTabSelected()) {
|
||||
return targetTypeWindowBuilder.getWindowForAdd();
|
||||
}
|
||||
return targetTagWindowBuilder.getWindowForAdd();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAddEntityWindowCaptionMsgKey() {
|
||||
if (targetTagFilterLayoutUiState.isTargetTypeFilterTabSelected()) {
|
||||
return UIMessageIdProvider.CAPTION_TYPE;
|
||||
}
|
||||
return UIMessageIdProvider.CAPTION_TAG;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.management.targettag.filter;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventTopics;
|
||||
import org.eclipse.hawkbit.ui.common.event.TargetFilterTabChangedEventPayload;
|
||||
@@ -20,6 +22,7 @@ import org.eclipse.hawkbit.ui.management.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.TargetTagWindowBuilder;
|
||||
|
||||
import com.vaadin.ui.ComponentContainer;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.targettype.TargetTypeWindowBuilder;
|
||||
|
||||
/**
|
||||
* Target Tag filter layout.
|
||||
@@ -49,16 +52,20 @@ public class TargetTagFilterLayout extends AbstractFilterLayout {
|
||||
* TargetTagFilterLayoutUiState
|
||||
*/
|
||||
public TargetTagFilterLayout(final CommonUiDependencies uiDependencies, final ManagementUIState managementUIState,
|
||||
final TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState) {
|
||||
final TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
final TargetTypeManagement targetTypeManagement,
|
||||
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
|
||||
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState, final DistributionSetTypeManagement distributionSetTypeManagement) {
|
||||
final TargetTagWindowBuilder targetTagWindowBuilder = new TargetTagWindowBuilder(uiDependencies,
|
||||
targetTagManagement);
|
||||
|
||||
final TargetTypeWindowBuilder targetTypeWindowBuilder = new TargetTypeWindowBuilder(uiDependencies,
|
||||
targetTypeManagement, distributionSetTypeManagement);
|
||||
|
||||
this.targetTagFilterHeader = new TargetTagFilterHeader(uiDependencies, targetTagFilterLayoutUiState,
|
||||
targetTagWindowBuilder);
|
||||
targetTagWindowBuilder, targetTypeWindowBuilder);
|
||||
this.multipleTargetFilter = new MultipleTargetFilter(uiDependencies, targetFilterQueryManagement,
|
||||
targetTagManagement, targetManagement, targetTagFilterLayoutUiState, targetTagWindowBuilder);
|
||||
targetTagManagement, targetManagement, targetTagFilterLayoutUiState, targetTagWindowBuilder, targetTypeWindowBuilder, targetTypeManagement);
|
||||
|
||||
this.filterTabChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(),
|
||||
EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged);
|
||||
|
||||
@@ -24,6 +24,8 @@ public class TargetTagFilterLayoutUiState extends TagFilterLayoutUiState {
|
||||
private final Collection<TargetUpdateStatus> clickedTargetUpdateStatusFilters = new ArrayList<>();
|
||||
private boolean isOverdueFilterClicked;
|
||||
private boolean isCustomFilterTabSelected;
|
||||
private boolean isTargetTypeFilterTabSelected;
|
||||
|
||||
|
||||
/**
|
||||
* @return Id of clicked target filter query
|
||||
@@ -94,4 +96,13 @@ public class TargetTagFilterLayoutUiState extends TagFilterLayoutUiState {
|
||||
public void setCustomFilterTabSelected(final boolean isCustomFilterTabSelected) {
|
||||
this.isCustomFilterTabSelected = isCustomFilterTabSelected;
|
||||
}
|
||||
|
||||
public boolean isTargetTypeFilterTabSelected() {
|
||||
return isTargetTypeFilterTabSelected;
|
||||
}
|
||||
|
||||
public void setTargetTypeFilterTabSelected(boolean targetTypeFilterTabSelected) {
|
||||
isTargetTypeFilterTabSelected = targetTypeFilterTabSelected;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.filter;
|
||||
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.Window;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.hawkbit.repository.Identifiable;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.TargetTypeInUseException;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.mappers.TargetTypeToProxyTargetTypeMapper;
|
||||
import org.eclipse.hawkbit.ui.common.data.providers.TargetTypeDataProvider;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventTopics;
|
||||
import org.eclipse.hawkbit.ui.common.event.EventView;
|
||||
import org.eclipse.hawkbit.ui.common.filterlayout.AbstractTargetTypeFilterButtons;
|
||||
import org.eclipse.hawkbit.ui.common.state.TagFilterLayoutUiState;
|
||||
import org.eclipse.hawkbit.ui.management.targettag.targettype.TargetTypeWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Target Type filter buttons table.
|
||||
*/
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class TargetTypeFilterButtons extends AbstractTargetTypeFilterButtons {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final transient TargetTypeManagement targetTypeManagement;
|
||||
private final transient TargetTypeWindowBuilder targetTypeWindowBuilder;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TargetTypeFilterButtons.class);
|
||||
|
||||
TargetTypeFilterButtons(final CommonUiDependencies uiDependencies,
|
||||
final TargetTypeManagement targetTypeManagement, final TagFilterLayoutUiState tagFilterLayoutUiState,
|
||||
final TargetTypeWindowBuilder targetTypeWindowBuilder) {
|
||||
super(uiDependencies, tagFilterLayoutUiState);
|
||||
|
||||
this.targetTypeManagement = targetTypeManagement;
|
||||
this.targetTypeWindowBuilder = targetTypeWindowBuilder;
|
||||
|
||||
init();
|
||||
setDataProvider(
|
||||
new TargetTypeDataProvider<>(targetTypeManagement, new TargetTypeToProxyTargetTypeMapper<>()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGridId() {
|
||||
return UIComponentIdProvider.TARGET_TYPE_TABLE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessageKeyEntityTypeSing() {
|
||||
return "caption.entity.target.type";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMessageKeyEntityTypePlur() {
|
||||
return "caption.entity.target.types";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean deleteFilterButtons(Collection<ProxyTargetType> filterButtonsToDelete) {
|
||||
final ProxyTargetType targetTypeToDelete = filterButtonsToDelete.iterator().next();
|
||||
return deleteTargetType(targetTypeToDelete);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFilterButtonIdPrefix() {
|
||||
return UIComponentIdProvider.TARGET_TYPE_ID_PREFIXS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void editButtonClickListener(ProxyTargetType clickedFilter) {
|
||||
final Window updateWindow = targetTypeWindowBuilder.getWindowForUpdate(clickedFilter);
|
||||
|
||||
updateWindow.setCaption(i18n.getMessage("caption.update", i18n.getMessage("caption.type")));
|
||||
UI.getCurrent().addWindow(updateWindow);
|
||||
updateWindow.setVisible(Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType() {
|
||||
return ProxyTarget.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EventView getView() {
|
||||
return EventView.DEPLOYMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean deleteTargetType(ProxyTargetType targetTypeToDelete) {
|
||||
try{
|
||||
targetTypeManagement.delete(targetTypeToDelete.getId());
|
||||
eventBus.publish(EventTopics.ENTITY_MODIFIED, this,
|
||||
new EntityModifiedEventPayload(EntityModifiedEventPayload.EntityModifiedEventType.ENTITY_REMOVED, getFilterMasterEntityType(),
|
||||
ProxyTargetType.class, targetTypeToDelete.getId()));
|
||||
return true;
|
||||
} catch (TargetTypeInUseException exception){
|
||||
LOG.trace("Target type already in use exception: {}", exception.getMessage());
|
||||
uiNotification.displayValidationError(i18n.getMessage(exception.getMessage()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Long> filterExistingTargetTypeIds(Collection<Long> targetTypeIds) {
|
||||
return targetTypeManagement.get(targetTypeIds).stream().map(Identifiable::getId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDeletionAllowed() {
|
||||
return permissionChecker.hasDeleteTargetPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEditAllowed() {
|
||||
return permissionChecker.hasUpdateRepositoryPermission();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
import org.eclipse.hawkbit.ui.common.AbstractAddNamedEntityWindowController;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.EntityWindowLayout;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType;
|
||||
import org.eclipse.hawkbit.ui.common.targettype.ProxyTargetTypeValidator;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Add target type window controller
|
||||
*/
|
||||
public class AddTargetTypeWindowController
|
||||
extends AbstractAddNamedEntityWindowController<ProxyTargetType, ProxyTargetType, TargetType> {
|
||||
|
||||
private final TargetTypeWindowLayout layout;
|
||||
private final ProxyTargetTypeValidator validator;
|
||||
private final TargetTypeManagement targetTypeManagement;
|
||||
|
||||
/**
|
||||
* Constructor for AddTargetTypeWindowController
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param targetTypeManagement
|
||||
* targetTypeManagement
|
||||
* @param layout
|
||||
* TargetTypeWindowLayout
|
||||
*/
|
||||
public AddTargetTypeWindowController(final CommonUiDependencies uiDependencies,
|
||||
final TargetTypeManagement targetTypeManagement, final TargetTypeWindowLayout layout) {
|
||||
super(uiDependencies);
|
||||
|
||||
this.targetTypeManagement = targetTypeManagement;
|
||||
this.layout = layout;
|
||||
this.validator = new ProxyTargetTypeValidator(uiDependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityWindowLayout<ProxyTargetType> getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProxyTargetType buildEntityFromProxy(final ProxyTargetType proxyEntity) {
|
||||
return new ProxyTargetType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TargetType persistEntityInRepository(final ProxyTargetType entity) {
|
||||
return targetTypeManagement.create(getEntityFactory().targetType().create()
|
||||
.name(entity.getName()).description(entity.getDescription()).colour(entity.getColour())
|
||||
.compatible(entity.getSelectedDsTypes().stream().map(ProxyType::getId)
|
||||
.collect(Collectors.toSet())));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ProxyIdentifiableEntity> getEntityClass() {
|
||||
return ProxyTargetType.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ProxyIdentifiableEntity> getParentEntityClass() {
|
||||
return ProxyTarget.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEntityValid(final ProxyTargetType entity) {
|
||||
final String trimmedName = StringUtils.trimWhitespace(entity.getName());
|
||||
return validator.isEntityValid(entity, () -> targetTypeManagement.getByName(trimmedName).isPresent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType;
|
||||
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
|
||||
import org.eclipse.hawkbit.ui.common.grid.selection.RangeSelectionModel;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
|
||||
/**
|
||||
* Distribution Set Selected Type grid which is shown on the Target Type
|
||||
* Create/Update popup layout.
|
||||
*/
|
||||
public class DsTypeSelectedGrid extends Grid<ProxyType> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final VaadinMessageSource i18n;
|
||||
|
||||
/**
|
||||
* Constructor for DsTypeSelectedGrid
|
||||
*
|
||||
* @param i18n
|
||||
* VaadinMessageSource
|
||||
*/
|
||||
public DsTypeSelectedGrid(final VaadinMessageSource i18n) {
|
||||
this.i18n = i18n;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setSizeFull();
|
||||
setHeightUndefined();
|
||||
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_NO_STRIPES);
|
||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_SMALL);
|
||||
// used to deactivate cell text selection by user
|
||||
addStyleName(AbstractGrid.MULTI_SELECT_STYLE);
|
||||
|
||||
setId(SPUIDefinitions.TWIN_TABLE_SELECTED_ID);
|
||||
setSelectionModel(new RangeSelectionModel<>(i18n));
|
||||
|
||||
addColumns();
|
||||
}
|
||||
|
||||
private void addColumns() {
|
||||
GridComponentBuilder.addColumn(this, ProxyType::getName).setId(UIComponentIdProvider.DIST_TYPE_TABLE_SELECTED_ID)
|
||||
.setCaption(i18n.getMessage("header.dt.twintable.selected"))
|
||||
.setDescriptionGenerator(ProxyType::getDescription);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.vaadin.ui.Grid;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType;
|
||||
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
|
||||
import org.eclipse.hawkbit.ui.common.grid.selection.RangeSelectionModel;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
|
||||
/**
|
||||
* Distribution Set Source Type grid which is shown on the Target Type
|
||||
* Create/Update popup layout.
|
||||
*/
|
||||
public class DsTypeSourceGrid extends Grid<ProxyType> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final VaadinMessageSource i18n;
|
||||
|
||||
/**
|
||||
* Constructor for DsTypeSourceGrid
|
||||
*
|
||||
* @param i18n
|
||||
* VaadinMessageSource
|
||||
*/
|
||||
public DsTypeSourceGrid(final VaadinMessageSource i18n) {
|
||||
this.i18n = i18n;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setSizeFull();
|
||||
setHeightUndefined();
|
||||
addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_NO_STRIPES);
|
||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||
addStyleName(ValoTheme.TABLE_SMALL);
|
||||
// used to deactivate cell text selection by user
|
||||
addStyleName(AbstractGrid.MULTI_SELECT_STYLE);
|
||||
|
||||
setId(SPUIDefinitions.TWIN_TABLE_SOURCE_ID);
|
||||
setSelectionModel(new RangeSelectionModel<>(i18n));
|
||||
|
||||
addColumns();
|
||||
}
|
||||
|
||||
private void addColumns() {
|
||||
GridComponentBuilder.addColumn(this, ProxyType::getName).setId(UIComponentIdProvider.DIST_TYPE_TABLE_SOURCE_ID)
|
||||
.setCaption(i18n.getMessage("header.dt.twintable.available"))
|
||||
.setDescriptionGenerator(ProxyType::getDescription);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.vaadin.icons.VaadinIcons;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.Component;
|
||||
import com.vaadin.ui.CustomField;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.ui.common.data.mappers.TypeToProxyTypeMapper;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Layout for the distribution sets select grids for managing Target
|
||||
* Types on the Distributions View.
|
||||
*/
|
||||
public class TargetTypeDsTypeSelectLayout extends CustomField<Set<ProxyType>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final int MAX_DS_TYPE_QUERY = 500;
|
||||
|
||||
private final VaadinMessageSource i18n;
|
||||
|
||||
private final transient TypeToProxyTypeMapper<DistributionSetType> dsTypeToProxyTypeMapper;
|
||||
|
||||
private DsTypeSelectedGrid selectedGrid;
|
||||
private DsTypeSourceGrid sourceGrid;
|
||||
|
||||
private final List<ProxyType> allDsTypes;
|
||||
private Set<ProxyType> selectedDsTypes;
|
||||
|
||||
private final HorizontalLayout layout;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param i18n
|
||||
* VaadinMessageSource
|
||||
* @param distributionSetTypeManagement
|
||||
* distributionSetTypeManagement
|
||||
*/
|
||||
public TargetTypeDsTypeSelectLayout(final VaadinMessageSource i18n,
|
||||
final DistributionSetTypeManagement distributionSetTypeManagement) {
|
||||
this.i18n = i18n;
|
||||
this.dsTypeToProxyTypeMapper = new TypeToProxyTypeMapper<>();
|
||||
|
||||
this.allDsTypes = distributionSetTypeManagement.findAll(PageRequest.of(0, MAX_DS_TYPE_QUERY))
|
||||
.map(dsTypeToProxyTypeMapper::map).getContent();
|
||||
this.selectedDsTypes = new HashSet<>();
|
||||
|
||||
|
||||
this.layout = new HorizontalLayout();
|
||||
this.layout.setSpacing(false);
|
||||
this.layout.setMargin(false);
|
||||
this.layout.setSizeFull();
|
||||
this.layout.setWidth("400px");
|
||||
|
||||
buildLayout();
|
||||
}
|
||||
|
||||
private void buildLayout() {
|
||||
final VerticalLayout selectButtonLayout = new VerticalLayout();
|
||||
selectButtonLayout.setSpacing(false);
|
||||
selectButtonLayout.setMargin(false);
|
||||
|
||||
final Button selectButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SELECT_DIST_TYPE, "", "",
|
||||
"arrow-button", true, VaadinIcons.FORWARD, SPUIButtonStyleNoBorder.class);
|
||||
selectButton.addClickListener(event -> addDsTypeToSelectedGrid());
|
||||
|
||||
final Button unSelectButton = SPUIComponentProvider.getButton(UIComponentIdProvider.UNSELECT_DIST_TYPE, "", "", "arrow-button",
|
||||
true, VaadinIcons.BACKWARDS, SPUIButtonStyleNoBorder.class);
|
||||
unSelectButton.addClickListener(event -> removeDsTypeFromSelectedGrid());
|
||||
|
||||
selectButtonLayout.addComponent(selectButton);
|
||||
selectButtonLayout.addComponent(unSelectButton);
|
||||
selectButtonLayout.setComponentAlignment(selectButton, Alignment.MIDDLE_CENTER);
|
||||
selectButtonLayout.setComponentAlignment(unSelectButton, Alignment.MIDDLE_CENTER);
|
||||
|
||||
sourceGrid = buildSourceGrid();
|
||||
selectedGrid = buildSelectedGrid();
|
||||
|
||||
layout.addComponent(sourceGrid);
|
||||
layout.addComponent(selectButtonLayout);
|
||||
layout.addComponent(selectedGrid);
|
||||
layout.setComponentAlignment(sourceGrid, Alignment.MIDDLE_LEFT);
|
||||
layout.setComponentAlignment(selectButtonLayout, Alignment.MIDDLE_CENTER);
|
||||
layout.setComponentAlignment(selectedGrid, Alignment.MIDDLE_RIGHT);
|
||||
layout.setExpandRatio(sourceGrid, 0.45F);
|
||||
layout.setExpandRatio(selectButtonLayout, 0.07F);
|
||||
layout.setExpandRatio(selectedGrid, 0.48F);
|
||||
}
|
||||
|
||||
private void addDsTypeToSelectedGrid() {
|
||||
final Set<ProxyType> selectedSourceDsTypes = sourceGrid.getSelectedItems();
|
||||
if (CollectionUtils.isEmpty(selectedSourceDsTypes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setValue(Sets.union(selectedDsTypes, selectedSourceDsTypes).immutableCopy());
|
||||
}
|
||||
|
||||
private void removeDsTypeFromSelectedGrid() {
|
||||
final Set<ProxyType> selectedSelectedDsTypes = selectedGrid.getSelectedItems();
|
||||
if (CollectionUtils.isEmpty(selectedSelectedDsTypes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setValue(Sets.difference(selectedDsTypes, selectedSelectedDsTypes).immutableCopy());
|
||||
}
|
||||
|
||||
private DsTypeSourceGrid buildSourceGrid() {
|
||||
final DsTypeSourceGrid grid = new DsTypeSourceGrid(i18n);
|
||||
grid.setItems(allDsTypes);
|
||||
|
||||
if (!CollectionUtils.isEmpty(allDsTypes)) {
|
||||
grid.select(allDsTypes.get(0));
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
private DsTypeSelectedGrid buildSelectedGrid() {
|
||||
final DsTypeSelectedGrid dsTypeSelectedGrid = new DsTypeSelectedGrid(i18n);
|
||||
dsTypeSelectedGrid.setItems(selectedDsTypes);
|
||||
return dsTypeSelectedGrid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ProxyType> getValue() {
|
||||
return selectedDsTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Component initContent() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doSetValue(final Set<ProxyType> value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectedDsTypes = value;
|
||||
|
||||
selectedGrid.setItems(selectedDsTypes);
|
||||
sourceGrid.setItems(getSourceDsTypes());
|
||||
}
|
||||
|
||||
private List<ProxyType> getSourceDsTypes() {
|
||||
final Set<Long> selectedDsTypeIds = selectedDsTypes.stream().map(ProxyIdentifiableEntity::getId)
|
||||
.collect(Collectors.toSet());
|
||||
return allDsTypes.stream().filter(dsType -> !selectedDsTypeIds.contains(dsType.getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.vaadin.ui.Window;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.ui.common.AbstractEntityWindowBuilder;
|
||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
|
||||
/**
|
||||
* Builder for target type window
|
||||
*/
|
||||
public class TargetTypeWindowBuilder extends AbstractEntityWindowBuilder<ProxyTargetType> {
|
||||
|
||||
private final TargetTypeManagement targetTypeManagement;
|
||||
private final DistributionSetTypeManagement dsTypeManagement;
|
||||
|
||||
/**
|
||||
* Constructor for TargetTypeWindowBuilder
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param dsTypeManagement
|
||||
* DistributionSetTypeManagement
|
||||
* @param targetTypeManagement
|
||||
* TargetTypeManagement
|
||||
*/
|
||||
public TargetTypeWindowBuilder(final CommonUiDependencies uiDependencies, final TargetTypeManagement targetTypeManagement,
|
||||
final DistributionSetTypeManagement dsTypeManagement) {
|
||||
super(uiDependencies);
|
||||
|
||||
this.targetTypeManagement = targetTypeManagement;
|
||||
this.dsTypeManagement = dsTypeManagement;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWindowId() {
|
||||
return UIComponentIdProvider.TAG_POPUP_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getWindowForAdd() {
|
||||
CommonDialogWindow window = getWindowForNewEntity(new AddTargetTypeWindowController(uiDependencies, targetTypeManagement,
|
||||
new TargetTypeWindowLayout(uiDependencies, dsTypeManagement)));
|
||||
window.hideMandatoryExplanation();
|
||||
return window;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getWindowForUpdate(final ProxyTargetType proxyType) {
|
||||
CommonDialogWindow window = getWindowForEntity(proxyType, new UpdateTargetTypeWindowController(uiDependencies, targetTypeManagement,
|
||||
new TargetTypeWindowLayout(uiDependencies, dsTypeManagement)));
|
||||
window.hideMandatoryExplanation();
|
||||
return window;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.vaadin.ui.ComponentContainer;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.management.tag.TagWindowLayout;
|
||||
|
||||
/**
|
||||
* Target type window layout
|
||||
*/
|
||||
public class TargetTypeWindowLayout extends TagWindowLayout<ProxyTargetType> {
|
||||
private final TargetTypeWindowLayoutComponentBuilder targetTypeWindowLayoutComponentBuilder;
|
||||
|
||||
private final TargetTypeDsTypeSelectLayout targetTypeDsTypeSelectLayout;
|
||||
|
||||
/**
|
||||
* Constructor for TargetTypeWindowLayout
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param distributionSetTypeManagement
|
||||
* DistributionSetTypeManagement
|
||||
*/
|
||||
public TargetTypeWindowLayout(final CommonUiDependencies uiDependencies,
|
||||
final DistributionSetTypeManagement distributionSetTypeManagement) {
|
||||
super(uiDependencies);
|
||||
|
||||
this.targetTypeWindowLayoutComponentBuilder = new TargetTypeWindowLayoutComponentBuilder(i18n, distributionSetTypeManagement);
|
||||
|
||||
this.targetTypeDsTypeSelectLayout = targetTypeWindowLayoutComponentBuilder.createTargetTypeDsSelectLayout(binder);
|
||||
|
||||
this.colorPickerComponent.getColorPickerBtn().setCaption(i18n.getMessage("label.choose.type.color"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentContainer getRootComponent() {
|
||||
final ComponentContainer rootLayout = super.getRootComponent();
|
||||
|
||||
rootLayout.addComponent(targetTypeDsTypeSelectLayout);
|
||||
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import com.vaadin.data.Binder;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
|
||||
/**
|
||||
* Builder for target type window layout component
|
||||
*/
|
||||
public class TargetTypeWindowLayoutComponentBuilder {
|
||||
|
||||
private final VaadinMessageSource i18n;
|
||||
private final DistributionSetTypeManagement distributionSetTypeManagement;
|
||||
|
||||
/**
|
||||
* Constructor for TargetTypeWindowLayoutComponentBuilder
|
||||
*
|
||||
* @param i18n
|
||||
* VaadinMessageSource
|
||||
* @param distributionSetTypeManagement
|
||||
* distributionSetTypeManagement
|
||||
*/
|
||||
public TargetTypeWindowLayoutComponentBuilder(final VaadinMessageSource i18n,
|
||||
final DistributionSetTypeManagement distributionSetTypeManagement) {
|
||||
this.i18n = i18n;
|
||||
this.distributionSetTypeManagement = distributionSetTypeManagement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create target type layout
|
||||
*
|
||||
* @param binder
|
||||
* Vaadin binder
|
||||
*
|
||||
* @return layout of target type distribution set selection
|
||||
*/
|
||||
public TargetTypeDsTypeSelectLayout createTargetTypeDsSelectLayout(final Binder<ProxyTargetType> binder) {
|
||||
|
||||
final TargetTypeDsTypeSelectLayout targetTypeDsTypeSelectLayout = new TargetTypeDsTypeSelectLayout(i18n, distributionSetTypeManagement);
|
||||
targetTypeDsTypeSelectLayout.setRequiredIndicatorVisible(false);
|
||||
|
||||
binder.forField(targetTypeDsTypeSelectLayout)
|
||||
.bind(ProxyTargetType::getSelectedDsTypes, ProxyTargetType::setSelectedDsTypes);
|
||||
|
||||
return targetTypeDsTypeSelectLayout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Bosch.IO 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.management.targettag.targettype;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
import org.eclipse.hawkbit.ui.common.AbstractEntityWindowLayout;
|
||||
import org.eclipse.hawkbit.ui.common.AbstractUpdateNamedEntityWindowController;
|
||||
import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
|
||||
import org.eclipse.hawkbit.ui.common.data.mappers.TypeToProxyTypeMapper;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetType;
|
||||
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyType;
|
||||
import org.eclipse.hawkbit.ui.common.targettype.ProxyTargetTypeValidator;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Controller for update target type window
|
||||
*/
|
||||
public class UpdateTargetTypeWindowController
|
||||
extends AbstractUpdateNamedEntityWindowController<ProxyTargetType, ProxyTargetType, TargetType> {
|
||||
|
||||
private final TargetTypeManagement targetTypeManagement;
|
||||
private final TypeToProxyTypeMapper<DistributionSetType> dsTypeToProxyTypeMapper;
|
||||
private final TargetTypeWindowLayout layout;
|
||||
private final ProxyTargetTypeValidator validator;
|
||||
|
||||
private String nameBeforeEdit;
|
||||
|
||||
/**
|
||||
* Constructor for UpdateTargetTypeWindowController
|
||||
*
|
||||
* @param uiDependencies
|
||||
* {@link CommonUiDependencies}
|
||||
* @param targetTypeManagement
|
||||
* TargetTypeManagement
|
||||
* @param layout
|
||||
* TargetTypeWindowLayout
|
||||
*/
|
||||
public UpdateTargetTypeWindowController(final CommonUiDependencies uiDependencies,
|
||||
final TargetTypeManagement targetTypeManagement,
|
||||
final TargetTypeWindowLayout layout) {
|
||||
super(uiDependencies);
|
||||
|
||||
this.targetTypeManagement = targetTypeManagement;
|
||||
this.dsTypeToProxyTypeMapper = new TypeToProxyTypeMapper<>();
|
||||
this.layout = layout;
|
||||
this.validator = new ProxyTargetTypeValidator(uiDependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractEntityWindowLayout<ProxyTargetType> getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProxyTargetType buildEntityFromProxy(final ProxyTargetType proxyEntity) {
|
||||
final ProxyTargetType dsType = new ProxyTargetType();
|
||||
dsType.setId(proxyEntity.getId());
|
||||
dsType.setName(proxyEntity.getName());
|
||||
dsType.setDescription(proxyEntity.getDescription());
|
||||
dsType.setColour(proxyEntity.getColour());
|
||||
dsType.setSelectedDsTypes(getDsTypesByDsTypeId(proxyEntity.getId()));
|
||||
nameBeforeEdit = proxyEntity.getName();
|
||||
|
||||
return dsType;
|
||||
}
|
||||
|
||||
private Set<ProxyType> getDsTypesByDsTypeId(final Long id) {
|
||||
Optional<TargetType> targetType = targetTypeManagement.get(id);
|
||||
return targetType.map(type -> type.getCompatibleDistributionSetTypes().stream()
|
||||
.map(dsTypeToProxyTypeMapper::map).collect(Collectors.toSet())).orElse(Collections.emptySet());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TargetType persistEntityInRepository(final ProxyTargetType entity) {
|
||||
|
||||
Set<Long> dsTypesIds = getDsTypesByDsTypeId(entity.getId()).stream().map(ProxyType::getId).collect(Collectors.toSet());
|
||||
|
||||
Set<Long> selectedDsIds = entity.getSelectedDsTypes().stream().map(ProxyType::getId).collect(Collectors.toSet());
|
||||
|
||||
Set<Long> dsTypesForRemoval = getDsTypesByDsTypeId(entity.getId()).stream().map(ProxyType::getId)
|
||||
.filter(dsType -> !selectedDsIds.contains(dsType)).collect(Collectors.toSet());
|
||||
Set<Long> dsTypesForAdd = selectedDsIds.stream()
|
||||
.filter(dsType -> !dsTypesIds.contains(dsType)).collect(Collectors.toSet());
|
||||
|
||||
dsTypesForRemoval.forEach(dsType -> targetTypeManagement.unassignDistributionSetType(entity.getId(), dsType));
|
||||
|
||||
if (!dsTypesForAdd.isEmpty()) {
|
||||
targetTypeManagement.assignCompatibleDistributionSetTypes(entity.getId(), dsTypesForAdd);
|
||||
}
|
||||
|
||||
return targetTypeManagement.update(getEntityFactory().targetType().update(entity.getId())
|
||||
.name(entity.getName()).description(entity.getDescription()).colour(entity.getColour()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ProxyIdentifiableEntity> getEntityClass() {
|
||||
return ProxyTargetType.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ProxyIdentifiableEntity> getParentEntityClass() {
|
||||
return ProxyTarget.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEntityValid(final ProxyTargetType entity) {
|
||||
final String trimmedName = StringUtils.trimWhitespace(entity.getName());
|
||||
return validator.isEntityValid(entity,
|
||||
() -> hasNamedChanged(trimmedName) && targetTypeManagement.getByName(trimmedName).isPresent());
|
||||
}
|
||||
|
||||
private boolean hasNamedChanged(final String trimmedName) {
|
||||
return !nameBeforeEdit.equals(trimmedName);
|
||||
}
|
||||
}
|
||||
@@ -262,6 +262,11 @@ public final class SPUIDefinitions {
|
||||
*/
|
||||
public static final String NO_TAG_BUTTON_ID = "no_tag_button";
|
||||
|
||||
/**
|
||||
* Id of "NO TARGET TYPE" button.
|
||||
*/
|
||||
public static final String NO_TARGET_TYPE_BUTTON_ID = "no_target_type_button";
|
||||
|
||||
/**
|
||||
* DELETE column/button.
|
||||
*/
|
||||
|
||||
@@ -116,6 +116,11 @@ public final class SPUIStyleDefinitions {
|
||||
*/
|
||||
public static final String SIMPLE_FILTER_HEADER = "simple-tag-filter-header";
|
||||
|
||||
/**
|
||||
* Target type filter header layout.
|
||||
*/
|
||||
public static final String TARGET_TYPE_FILTER_HEADER = "target-type-filter-header";
|
||||
|
||||
/**
|
||||
* Simple tag filter header layout.
|
||||
*/
|
||||
|
||||
@@ -580,6 +580,16 @@ public final class UIComponentIdProvider {
|
||||
*/
|
||||
public static final String TARGET_TAG_DROP_AREA_ID = "target.tag.drop.area";
|
||||
|
||||
/**
|
||||
* ID-Target tag table.
|
||||
*/
|
||||
public static final String TARGET_TYPE_TABLE_ID = "target.type.tableId";
|
||||
|
||||
/**
|
||||
* ID-Target type table drop area.
|
||||
*/
|
||||
public static final String TARGET_TYPE_DROP_AREA_ID = "target.type.drop.area";
|
||||
|
||||
/**
|
||||
* ID-Distibution tag table.
|
||||
*/
|
||||
@@ -929,6 +939,11 @@ public final class UIComponentIdProvider {
|
||||
*/
|
||||
public static final String SIMPLE_FILTER_ACCORDION_TAB = "simple.filter.accordion.tab";
|
||||
|
||||
/**
|
||||
* ID - target type filter- Accordion-Tab
|
||||
*/
|
||||
public static final String TARGET_TYPE_FILTER_ACCORDION_TAB = "target.type.filter.accordion.tab";
|
||||
|
||||
/**
|
||||
* ID - custom filter- Accordion-Tab
|
||||
*/
|
||||
@@ -1337,6 +1352,22 @@ public final class UIComponentIdProvider {
|
||||
* Table multiselect for selecting DistType
|
||||
*/
|
||||
public static final String SELECT_DIST_TYPE = "select-dist-type";
|
||||
|
||||
/**
|
||||
* Table multiselect for unselecting DistType
|
||||
*/
|
||||
public static final String UNSELECT_DIST_TYPE = "unselect-dist-type";
|
||||
|
||||
/**
|
||||
* ID for DistType source value table
|
||||
*/
|
||||
public static final String DIST_TYPE_TABLE_SOURCE_ID = "dsTypeSourceId";
|
||||
|
||||
/**
|
||||
* ID for DistType selected value table
|
||||
*/
|
||||
public static final String DIST_TYPE_TABLE_SELECTED_ID = "dsTypeSelectedId";
|
||||
|
||||
/**
|
||||
* ID for download anonymous checkbox
|
||||
*/
|
||||
@@ -1528,6 +1559,10 @@ public final class UIComponentIdProvider {
|
||||
* Target tag button id prefix.
|
||||
*/
|
||||
public static final String TARGET_TAG_ID_PREFIXS = "target.tag";
|
||||
/**
|
||||
* Target type button id prefix.
|
||||
*/
|
||||
public static final String TARGET_TYPE_ID_PREFIXS = "target.type";
|
||||
/**
|
||||
* Distribution tag button id prefix.
|
||||
*/
|
||||
|
||||
@@ -89,10 +89,14 @@ public final class UIMessageIdProvider {
|
||||
|
||||
public static final String CAPTION_TAG = "caption.tag";
|
||||
|
||||
public static final String CAPTION_TYPE = "caption.type";
|
||||
|
||||
public static final String LABEL_DROP_AREA_UPLOAD = "label.drop.area.upload";
|
||||
|
||||
public static final String LABEL_NO_TAG = "label.no.tag";
|
||||
|
||||
public static final String LABEL_NO_TARGET_TYPE = "label.no.target.type";
|
||||
|
||||
public static final String LABEL_CREATE_FILTER = "label.create.filter";
|
||||
|
||||
public static final String LABEL_EDIT_FILTER = "label.edit.filter";
|
||||
|
||||
@@ -70,6 +70,8 @@ header.first.delete.swmodule.type.table = Software Module Type
|
||||
header.second.delete.swmodule.type.table = Discard
|
||||
header.dist.twintable.selected=Selected
|
||||
header.dist.twintable.available=Available
|
||||
header.dt.twintable.available=Distribution set types
|
||||
header.dt.twintable.selected=Compatible distribution set types
|
||||
header.target.installed = Installed
|
||||
header.target.assigned = Assigned
|
||||
header.type=Type
|
||||
@@ -112,6 +114,7 @@ caption.entity.missing.error = Entity is missing
|
||||
caption.new.softwaremodule.application = Configure New Application
|
||||
caption.new.softwaremodule.os = Configure New OS
|
||||
caption.filter.simple = Simple Filter
|
||||
caption.filter.type = Type Filter
|
||||
caption.filter.custom = Custom Filter
|
||||
caption.metadata = Metadata
|
||||
caption.rollout.name = Rollout name
|
||||
@@ -177,6 +180,7 @@ label.menu = Menu
|
||||
label.active = Active
|
||||
label.action.id = Action Id
|
||||
label.no.tag = NO TAG
|
||||
label.no.target.type = NO TARGET TYPE
|
||||
label.action.forced = Forced
|
||||
label.action.type = Type
|
||||
label.action.soft = Soft
|
||||
@@ -408,6 +412,7 @@ message.cannot.delete = Cannot be deleted
|
||||
message.check.softwaremodule = Please provide both name and version!
|
||||
message.duplicate.softwaremodule = {0} : {1} already exists!
|
||||
message.tag.delete = Please deselect the tag {0} before deleting
|
||||
message.targettype.delete = Please deselect the target type {0} before deleting
|
||||
message.dist.type.check.delete = Please deselect the distribution type {0} before deleting
|
||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||
message.swmodule.type.check.delete = Please deselect the Software Module type {0} before deleting
|
||||
@@ -480,6 +485,7 @@ message.error.missing.filtername = Please select target filter name
|
||||
message.error.missing.controllerId = Missing Controller Id
|
||||
message.error.missing.nameorversion = Missing Name or Version
|
||||
message.error.missing.nameorversionortype = Missing Name or Version or Type
|
||||
message.error.missing.typename = Please select target type name
|
||||
message.error.distributionset.invalid = Action not allowed for invalid distribution set {0}
|
||||
message.type.delete = Please unclick the type {0}, then try to delete
|
||||
message.error.dist.set.type.update= Distribution set type is already assigned to set(s) and cannot be changed
|
||||
@@ -806,6 +812,8 @@ color.not.exists=There is no mapping for the provided colour {0}
|
||||
|
||||
caption.entity.target.tag = Target Tag
|
||||
caption.entity.target.tags = Target Tags
|
||||
caption.entity.target.type = Target Type
|
||||
caption.entity.target.types = Target Types
|
||||
caption.entity.distribution.tag = Distribution Tag
|
||||
caption.entity.distribution.tags = Distribution Tags
|
||||
caption.entity.distribution.type = Distribution set Type
|
||||
|
||||
Reference in New Issue
Block a user