diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java index eb9207dd1..1e1969adc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutExecutor.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.repository.jpa; -import static org.springframework.data.domain.Sort.Direction; - import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -21,8 +19,8 @@ import javax.persistence.EntityManager; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.RolloutApprovalStrategy; -import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutExecutor; +import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutHelper; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.TargetManagement; @@ -60,6 +58,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; +import org.springframework.data.domain.Sort.Direction; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionException; import org.springframework.util.StringUtils; @@ -297,8 +296,7 @@ public class JpaRolloutExecutor implements RolloutExecutor { if (hasScheduledActions) { try { final Iterable iterable = scheduledActions::iterator; - final List actionIds = StreamSupport.stream(iterable.spliterator(), false) - .map(Action::getId) + final List actionIds = StreamSupport.stream(iterable.spliterator(), false).map(Action::getId) .collect(Collectors.toList()); actionRepository.deleteByIdIn(actionIds); afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher() @@ -369,8 +367,8 @@ public class JpaRolloutExecutor implements RolloutExecutor { private void updateTotalTargetCount(final JpaRolloutGroup rolloutGroup, final long countTargetsOfRolloutGroup) { final JpaRollout jpaRollout = (JpaRollout) rolloutGroup.getRollout(); - final long updatedTargetCount = - jpaRollout.getTotalTargets() - (rolloutGroup.getTotalTargets() - countTargetsOfRolloutGroup); + final long updatedTargetCount = jpaRollout.getTotalTargets() + - (rolloutGroup.getTotalTargets() - countTargetsOfRolloutGroup); jpaRollout.setTotalTargets(updatedTargetCount); rolloutGroup.setTotalTargets((int) countTargetsOfRolloutGroup); rolloutRepository.save(jpaRollout); @@ -394,9 +392,9 @@ public class JpaRolloutExecutor implements RolloutExecutor { private boolean isRolloutGroupComplete(final JpaRollout rollout, final JpaRolloutGroup rolloutGroup) { final Long actionsLeftForRollout = ActionType.DOWNLOAD_ONLY == rollout.getActionType() ? actionRepository.countByRolloutAndRolloutGroupAndStatusNotIn(rollout, rolloutGroup, - DOWNLOAD_ONLY_ACTION_TERMINATION_STATUSES) + DOWNLOAD_ONLY_ACTION_TERMINATION_STATUSES) : actionRepository.countByRolloutAndRolloutGroupAndStatusNotIn(rollout, rolloutGroup, - DEFAULT_ACTION_TERMINATION_STATUSES); + DEFAULT_ACTION_TERMINATION_STATUSES); return actionsLeftForRollout == 0; } @@ -440,8 +438,8 @@ public class JpaRolloutExecutor implements RolloutExecutor { } private void executeRolloutGroupSuccessAction(final Rollout rollout, final RolloutGroup rolloutGroup) { - context.getBean(rolloutGroup.getSuccessAction().getBeanName(), RolloutGroupActionEvaluator.class) - .eval(rollout, rolloutGroup, rolloutGroup.getSuccessActionExp()); + context.getBean(rolloutGroup.getSuccessAction().getBeanName(), RolloutGroupActionEvaluator.class).eval(rollout, + rolloutGroup, rolloutGroup.getSuccessActionExp()); } private void startFirstRolloutGroup(final Rollout rollout) { @@ -496,7 +494,8 @@ public class JpaRolloutExecutor implements RolloutExecutor { final long targetsInGroupFilter = DeploymentHelper.runInNewTransaction(txManager, "countAllTargetsByTargetFilterQueryAndNotInRolloutGroups", count -> targetManagement.countByRsqlAndNotInRolloutGroups(readyGroups, groupTargetFilter)); - final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter); + final long expectedInGroup = Math + .round((double) (group.getTargetPercentage() / 100) * (double) targetsInGroupFilter); final long currentlyInGroup = DeploymentHelper.runInNewTransaction(txManager, "countRolloutTargetGroupByRolloutGroup", count -> rolloutTargetGroupRepository.countByRolloutGroup(group)); @@ -573,7 +572,8 @@ public class JpaRolloutExecutor implements RolloutExecutor { try { long actionsCreated; do { - actionsCreated = createActionsForTargetsInNewTransaction(rollout.getId(), group.getId(), TRANSACTION_TARGETS); + actionsCreated = createActionsForTargetsInNewTransaction(rollout.getId(), group.getId(), + TRANSACTION_TARGETS); totalActionsCreated += actionsCreated; } while (actionsCreated > 0); @@ -584,8 +584,7 @@ public class JpaRolloutExecutor implements RolloutExecutor { return totalActionsCreated; } - private Long createActionsForTargetsInNewTransaction(final long rolloutId, final long groupId, - final int limit) { + private Long createActionsForTargetsInNewTransaction(final long rolloutId, final long groupId, final int limit) { return DeploymentHelper.runInNewTransaction(txManager, "createActionsForTargets", status -> { final PageRequest pageRequest = PageRequest.of(0, limit); final Rollout rollout = rolloutRepository.findById(rolloutId) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java index 13350a45e..5fea47789 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/MgmtUiConfiguration.java @@ -11,6 +11,12 @@ package org.eclipse.hawkbit.ui; import java.util.List; import org.eclipse.hawkbit.im.authentication.PermissionService; +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplierImpl; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplier; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplierImpl; import org.eclipse.hawkbit.ui.error.HawkbitUIErrorHandler; import org.eclipse.hawkbit.ui.error.extractors.ConstraintViolationErrorExtractor; import org.eclipse.hawkbit.ui.error.extractors.UiErrorDetailsExtractor; @@ -28,6 +34,7 @@ import org.vaadin.spring.servlet.Vaadin4SpringServlet; import com.vaadin.server.ErrorHandler; import com.vaadin.server.SystemMessagesProvider; import com.vaadin.server.VaadinServlet; +import com.vaadin.spring.annotation.UIScope; /** * Enables UI components for the Management UI. @@ -95,11 +102,21 @@ public class MgmtUiConfiguration { return new HawkbitUIErrorHandler(i18n, uiErrorDetailsExtractor); } + /** + * UI Upload Error details extractor bean. + * + * @return UI Upload Error details extractor + */ @Bean UiErrorDetailsExtractor uploadErrorExtractor() { return new UploadErrorExtractor(); } + /** + * UI ConstraintViolation Error details extractor bean. + * + * @return UI ConstraintViolation Error details extractor + */ @Bean UiErrorDetailsExtractor constraintViolationErrorExtractor(final VaadinMessageSource i18n) { return new ConstraintViolationErrorExtractor(i18n); @@ -114,4 +131,40 @@ public class MgmtUiConfiguration { public VaadinServlet vaadinServlet() { return new Vaadin4SpringServlet(); } + + /** + * UI target entity mapper bean. + * + * @return UI target entity mapper + */ + @Bean + public TargetToProxyTargetMapper targetToProxyTargetMapper(final VaadinMessageSource i18n) { + return new TargetToProxyTargetMapper(i18n); + } + + /** + * UI Management target data supplier bean. + * + * @return UI target data supplier for Management view + */ + @Bean + @ConditionalOnMissingBean + @UIScope + public TargetManagementStateDataSupplier targetManagementStateDataSupplier(final TargetManagement targetManagement, + final TargetToProxyTargetMapper targetToProxyTargetMapper) { + return new TargetManagementStateDataSupplierImpl(targetManagement, targetToProxyTargetMapper); + } + + /** + * UI Filter target data supplier bean. + * + * @return UI target data supplier for Filter view + */ + @Bean + @ConditionalOnMissingBean + @UIScope + public TargetFilterStateDataSupplier targetFilterStateDataSupplier(final TargetManagement targetManagement, + final TargetToProxyTargetMapper targetToProxyTargetMapper) { + return new TargetFilterStateDataSupplierImpl(targetManagement, targetToProxyTargetMapper); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java index 611f28afd..974e958d9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleGrid.java @@ -84,9 +84,9 @@ public class SoftwareModuleGrid extends AbstractGrid(this, eventBus, EventLayout.SM_LIST, view, - this::mapIdToProxyEntity, this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); + setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.SM_LIST, view, this::mapIdToProxyEntity, + this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); if (smGridLayoutUiState.isMaximized()) { getSelectionSupport().disableSelection(); } else { @@ -110,7 +110,7 @@ public class SoftwareModuleGrid extends AbstractGrid( new SoftwareModuleDataProvider(softwareModuleManagement, new AssignedSoftwareModuleToProxyMapper(softwareModuleToProxyMapper)), - getSelectionSupport()::deselectAll)); + SwFilterParams::new, getSelectionSupport()::deselectAll)); initFilterMappings(); getFilterSupport().setFilter(new SwFilterParams()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java index de247b6e4..6ad975db9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java @@ -26,7 +26,6 @@ import com.vaadin.server.Sizeable.Unit; import com.vaadin.shared.ui.ContentMode; import com.vaadin.ui.Component; import com.vaadin.ui.Label; -import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; @@ -138,9 +137,6 @@ public class ConfirmationDialog implements Serializable { return new SaveDialogCloseListener() { @Override public void saveOrUpdate() { - if (window.getParent() != null) { - UI.getCurrent().removeWindow(window); - } callback.accept(true); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsDistributionsFilterParams.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsDistributionsFilterParams.java index 80cd5c3a7..053d407f2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsDistributionsFilterParams.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsDistributionsFilterParams.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.common.data.filters; +import java.util.Objects; + import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetDistributionsStateDataProvider; /** @@ -38,6 +40,17 @@ public class DsDistributionsFilterParams extends DsFilterParams { this.dsTypeId = dsTypeId; } + /** + * Copy Constructor. + * + * @param filter + * A filter to be copied + */ + public DsDistributionsFilterParams(final DsDistributionsFilterParams filter) { + super(filter); + this.dsTypeId = filter.getDsTypeId(); + } + /** * @return DsTypeId */ @@ -54,4 +67,22 @@ public class DsDistributionsFilterParams extends DsFilterParams { public void setDsTypeId(final Long dsTypeId) { this.dsTypeId = dsTypeId; } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DsDistributionsFilterParams other = (DsDistributionsFilterParams) obj; + return Objects.equals(this.getSearchText(), other.getSearchText()) + && Objects.equals(this.getDsTypeId(), other.getDsTypeId()); + } + + @Override + public int hashCode() { + return Objects.hash(getSearchText(), getDsTypeId()); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsFilterParams.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsFilterParams.java index 08482365d..22b7b623c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsFilterParams.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsFilterParams.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.data.filters; import java.io.Serializable; +import java.util.Objects; import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetManagementStateDataProvider; import org.springframework.util.StringUtils; @@ -38,6 +39,16 @@ public class DsFilterParams implements Serializable { this.searchText = searchText; } + /** + * Copy Constructor. + * + * @param filter + * A filter to be copied + */ + public DsFilterParams(final DsFilterParams filter) { + this.searchText = filter.getSearchText(); + } + /** * @return SearchText */ @@ -55,4 +66,20 @@ public class DsFilterParams implements Serializable { this.searchText = !StringUtils.isEmpty(searchText) ? String.format("%%%s%%", searchText) : null; } + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DsFilterParams other = (DsFilterParams) obj; + return Objects.equals(this.getSearchText(), other.getSearchText()); + } + + @Override + public int hashCode() { + return Objects.hash(getSearchText()); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsManagementFilterParams.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsManagementFilterParams.java index 56a317948..f48056b4e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsManagementFilterParams.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/DsManagementFilterParams.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui.common.data.filters; import java.util.ArrayList; import java.util.Collection; -import java.util.List; +import java.util.Objects; import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetManagementStateDataProvider; @@ -44,13 +44,28 @@ public class DsManagementFilterParams extends DsFilterParams { * String as pinned target controller Id */ public DsManagementFilterParams(final String searchText, final boolean noTagClicked, - final List distributionSetTags, final String pinnedTargetControllerId) { + final Collection distributionSetTags, final String pinnedTargetControllerId) { super(searchText); this.noTagClicked = noTagClicked; this.distributionSetTags = distributionSetTags; this.pinnedTargetControllerId = pinnedTargetControllerId; } + /** + * Copy Constructor. + * + * @param filter + * A filter to be copied + */ + public DsManagementFilterParams(final DsManagementFilterParams filter) { + super(filter); + this.noTagClicked = filter.isNoTagClicked(); + this.distributionSetTags = filter.getDistributionSetTags() != null + ? new ArrayList<>(filter.getDistributionSetTags()) + : null; + this.pinnedTargetControllerId = filter.getPinnedTargetControllerId(); + } + /** * @return DistributionSetTags */ @@ -101,4 +116,24 @@ public class DsManagementFilterParams extends DsFilterParams { public void setNoTagClicked(final boolean noTagClicked) { this.noTagClicked = noTagClicked; } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DsManagementFilterParams other = (DsManagementFilterParams) obj; + return Objects.equals(this.getSearchText(), other.getSearchText()) + && Objects.equals(this.isNoTagClicked(), other.isNoTagClicked()) + && Objects.equals(this.getDistributionSetTags(), other.getDistributionSetTags()) + && Objects.equals(this.getPinnedTargetControllerId(), other.getPinnedTargetControllerId()); + } + + @Override + public int hashCode() { + return Objects.hash(getSearchText(), isNoTagClicked(), getDistributionSetTags(), getPinnedTargetControllerId()); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/SwFilterParams.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/SwFilterParams.java index b4e1f0aa3..f056a8037 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/SwFilterParams.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/SwFilterParams.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.data.filters; import java.io.Serializable; +import java.util.Objects; import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleDataProvider; import org.springframework.util.StringUtils; @@ -34,11 +35,11 @@ public class SwFilterParams implements Serializable { * Constructor. * * @param searchText - * String as search text + * String as search text * @param softwareModuleTypeId - * Long as software module Id + * Long as software module Id * @param lastSelectedDistributionId - * Long as Last selected Distribution Id + * Long as Last selected Distribution Id */ public SwFilterParams(final String searchText, final Long softwareModuleTypeId, final Long lastSelectedDistributionId) { @@ -47,6 +48,18 @@ public class SwFilterParams implements Serializable { this.lastSelectedDistributionId = lastSelectedDistributionId; } + /** + * Copy Constructor. + * + * @param filter + * A filter to be copied + */ + public SwFilterParams(final SwFilterParams filter) { + this.searchText = filter.getSearchText(); + this.softwareModuleTypeId = filter.getSoftwareModuleTypeId(); + this.lastSelectedDistributionId = filter.getLastSelectedDistributionId(); + } + /** * Get SearchText * @@ -60,7 +73,7 @@ public class SwFilterParams implements Serializable { * Setter for searchText * * @param searchText - * String + * String */ public void setSearchText(final String searchText) { this.searchText = !StringUtils.isEmpty(searchText) ? String.format("%%%s%%", searchText) : null; @@ -79,7 +92,7 @@ public class SwFilterParams implements Serializable { * Setter for softwareModuleTypeId * * @param softwareModuleTypeId - * Long + * Long */ public void setSoftwareModuleTypeId(final Long softwareModuleTypeId) { this.softwareModuleTypeId = softwareModuleTypeId; @@ -98,9 +111,28 @@ public class SwFilterParams implements Serializable { * Setter for lastSelectedDistributionId * * @param lastSelectedDistributionId - * Long + * Long */ public void setLastSelectedDistributionId(final Long lastSelectedDistributionId) { this.lastSelectedDistributionId = lastSelectedDistributionId; } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SwFilterParams other = (SwFilterParams) obj; + return Objects.equals(this.getSearchText(), other.getSearchText()) + && Objects.equals(this.getSoftwareModuleTypeId(), other.getSoftwareModuleTypeId()) + && Objects.equals(this.getLastSelectedDistributionId(), other.getLastSelectedDistributionId()); + } + + @Override + public int hashCode() { + return Objects.hash(getSearchText(), getSoftwareModuleTypeId(), getLastSelectedDistributionId()); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/TargetManagementFilterParams.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/TargetManagementFilterParams.java index 8595075a0..80af90dc9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/TargetManagementFilterParams.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/filters/TargetManagementFilterParams.java @@ -9,8 +9,10 @@ package org.eclipse.hawkbit.ui.common.data.filters; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Objects; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.ui.common.data.providers.TargetManagementStateDataProvider; @@ -43,21 +45,21 @@ public class TargetManagementFilterParams implements Serializable { * Constructor. * * @param pinnedDistId - * Id for Pinned distribution + * Id for Pinned distribution * @param searchText - * String as search text + * String as search text * @param targetUpdateStatusList - * Collection of TargetUpdateStatus + * Collection of TargetUpdateStatus * @param overdueState - * boolean + * boolean * @param distributionId - * Long + * Long * @param noTagClicked - * boolean + * boolean * @param targetTags - * Collection of string as target tags + * Collection of string as target tags * @param targetFilterQueryId - * Id for target filter query + * Id for target filter query */ public TargetManagementFilterParams(final Long pinnedDistId, final String searchText, final Collection targetUpdateStatusList, final boolean overdueState, @@ -73,12 +75,30 @@ public class TargetManagementFilterParams implements Serializable { this.targetFilterQueryId = targetFilterQueryId; } + /** + * Copy Constructor. + * + * @param filter + * A filter to be copied + */ + public TargetManagementFilterParams(final TargetManagementFilterParams filter) { + this.pinnedDistId = filter.getPinnedDistId(); + this.searchText = filter.getSearchText(); + this.targetUpdateStatusList = filter.getTargetUpdateStatusList() != null + ? new ArrayList<>(filter.getTargetUpdateStatusList()) + : null; + this.overdueState = filter.isOverdueState(); + this.distributionId = filter.getDistributionId(); + this.noTagClicked = filter.isNoTagClicked(); + this.targetTags = filter.getTargetTags() != null ? new ArrayList<>(filter.getTargetTags()) : null; + this.targetFilterQueryId = filter.getTargetFilterQueryId(); + } + /** * Gets the flag that indicates if the filter is selected * - * @return boolean - * true if the filter is selected, otherwise - * false + * @return boolean true if the filter is selected, otherwise + * false */ public boolean isAnyFilterSelected() { return isAnyTagSelected() || isAnyStatusFilterSelected() || isSearchActive() || isAnyComplexFilterSelected(); @@ -113,7 +133,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the pinnedDistId * * @param pinnedDistId - * Id for pinned distribution + * Id for pinned distribution */ public void setPinnedDistId(final Long pinnedDistId) { this.pinnedDistId = pinnedDistId; @@ -132,7 +152,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the searchText * * @param searchText - * Text for search + * Text for search */ public void setSearchText(final String searchText) { this.searchText = !StringUtils.isEmpty(searchText) ? String.format("%%%s%%", searchText) : null; @@ -151,7 +171,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the targetUpdateStatusList * * @param targetUpdateStatusList - * Collection of targetUpdateStatus + * Collection of targetUpdateStatus */ public void setTargetUpdateStatusList(final Collection targetUpdateStatusList) { this.targetUpdateStatusList = targetUpdateStatusList; @@ -170,7 +190,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the distributionId * * @param distributionId - * Distribution Id + * Distribution Id */ public void setDistributionId(final Long distributionId) { this.distributionId = distributionId; @@ -189,7 +209,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the targetTags * * @param targetTags - * Collection of targetTags + * Collection of targetTags */ public void setTargetTags(final Collection targetTags) { this.targetTags = targetTags; @@ -198,8 +218,7 @@ public class TargetManagementFilterParams implements Serializable { /** * Gets the targetFilterQueryId * - * @return targetFilterQueryId - * Id for target filter query + * @return targetFilterQueryId Id for target filter query */ public Long getTargetFilterQueryId() { return targetFilterQueryId; @@ -209,7 +228,7 @@ public class TargetManagementFilterParams implements Serializable { * Sets the targetFilterQueryId * * @param targetFilterQueryId - * Id for target filter query + * Id for target filter query */ public void setTargetFilterQueryId(final Long targetFilterQueryId) { this.targetFilterQueryId = targetFilterQueryId; @@ -218,9 +237,8 @@ public class TargetManagementFilterParams implements Serializable { /** * Gets the state of overdue * - * @return overdueState - * true if the state is set, otherwise - * false + * @return overdueState true if the state is set, otherwise + * false */ public boolean isOverdueState() { return overdueState; @@ -240,9 +258,8 @@ public class TargetManagementFilterParams implements Serializable { /** * Gets the status of tag clicked * - * @return noTagClicked - * true if the tag is clicked, otherwise - * false + * @return noTagClicked true if the tag is clicked, otherwise + * false */ public boolean isNoTagClicked() { return noTagClicked; @@ -258,4 +275,31 @@ public class TargetManagementFilterParams implements Serializable { public void setNoTagClicked(final boolean noTagClicked) { this.noTagClicked = noTagClicked; } + + // equals requires all fields in condition + @SuppressWarnings("squid:S1067") + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TargetManagementFilterParams other = (TargetManagementFilterParams) obj; + return Objects.equals(this.getPinnedDistId(), other.getPinnedDistId()) + && Objects.equals(this.getSearchText(), other.getSearchText()) + && Objects.equals(this.getTargetUpdateStatusList(), other.getTargetUpdateStatusList()) + && Objects.equals(this.isOverdueState(), other.isOverdueState()) + && Objects.equals(this.getDistributionId(), other.getDistributionId()) + && Objects.equals(this.isNoTagClicked(), other.isNoTagClicked()) + && Objects.equals(this.getTargetTags(), other.getTargetTags()) + && Objects.equals(this.getTargetFilterQueryId(), other.getTargetFilterQueryId()); + } + + @Override + public int hashCode() { + return Objects.hash(getPinnedDistId(), getSearchText(), getTargetUpdateStatusList(), isOverdueState(), + getDistributionId(), isNoTagClicked(), getTargetTags(), getTargetFilterQueryId()); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/AbstractGenericDataProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/AbstractGenericDataProvider.java index 57065d943..1445be75a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/AbstractGenericDataProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/AbstractGenericDataProvider.java @@ -27,11 +27,11 @@ import com.vaadin.data.provider.Query; * {@link ProxyIdentifiableEntity} entities. * * @param - * Generic type of ProxyIdentifiableEntity + * UI Proxy entity type * @param - * Generic type + * Backend entity type * @param - * Generic type + * Filter type */ public abstract class AbstractGenericDataProvider extends AbstractBackEndDataProvider { @@ -45,9 +45,9 @@ public abstract class AbstractGenericDataProvider - * Generic type of ProxyIdentifiableEntity + * UI Proxy entity type * @param - * Generic type of Identifiable + * Backend entity Identifiable type * @param - * Generic type + * Filter type */ public abstract class AbstractProxyDataProvider, F> extends AbstractGenericDataProvider { @@ -38,9 +38,9 @@ public abstract class AbstractProxyDataProvider mapper) { + protected AbstractProxyDataProvider(final IdentifiableEntityToProxyIdentifiableEntityMapper mapper) { this(mapper, Sort.by(Direction.ASC, "id")); } @@ -48,11 +48,11 @@ public abstract class AbstractProxyDataProvider mapper, + protected AbstractProxyDataProvider(final IdentifiableEntityToProxyIdentifiableEntityMapper mapper, final Sort defaultSortOrder) { super(defaultSortOrder); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/ActionStatusDataProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/ActionStatusDataProvider.java index 162a177ed..6a305e482 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/ActionStatusDataProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/providers/ActionStatusDataProvider.java @@ -34,9 +34,9 @@ public class ActionStatusDataProvider extends AbstractProxyDataProvider mapper) { @@ -49,7 +49,7 @@ public class TargetTagDataProvider extends AbstractProxyDataProvider + * UI Proxy entity type + * @param + * Filter type + */ +public interface DataSupplier { + + /** + * Provides back end data. + * + * @return back end data provider + */ + DataProvider dataProvider(); + + /** + * Provides client/server data communicator component. + * + * @return data communicator + */ + DataCommunicator dataCommunicator(); + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplier.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplier.java new file mode 100644 index 000000000..9918923cf --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplier.java @@ -0,0 +1,19 @@ +/** + * 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.suppliers; + +import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget; + +/** + * Interface for target backend data retrieval provider for Filter View. + * + */ +public interface TargetFilterStateDataSupplier extends DataSupplier { + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplierImpl.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplierImpl.java new file mode 100644 index 000000000..ab5c08616 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetFilterStateDataSupplierImpl.java @@ -0,0 +1,52 @@ +/** + * 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.suppliers; + +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; +import org.eclipse.hawkbit.ui.common.data.providers.TargetFilterStateDataProvider; +import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget; + +import com.vaadin.data.provider.DataCommunicator; +import com.vaadin.data.provider.DataProvider; + +/** + * Target backend data retrieval provider for Filter View default + * implementation. + * + */ +public class TargetFilterStateDataSupplierImpl implements TargetFilterStateDataSupplier { + private final TargetFilterStateDataProvider dataProvider; + private final DataCommunicator dataCommunicator; + + /** + * Constructor. + * + * @param targetManagement + * Target Management + * @param targetToProxyTargetMapper + * Backend to UI Proxy target entity mapper + */ + public TargetFilterStateDataSupplierImpl(final TargetManagement targetManagement, + final TargetToProxyTargetMapper targetToProxyTargetMapper) { + this.dataProvider = new TargetFilterStateDataProvider(targetManagement, targetToProxyTargetMapper); + this.dataCommunicator = new DataCommunicator<>(); + } + + @Override + public DataProvider dataProvider() { + return dataProvider; + } + + @Override + public DataCommunicator dataCommunicator() { + return dataCommunicator; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplier.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplier.java new file mode 100644 index 000000000..44eec0707 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplier.java @@ -0,0 +1,20 @@ +/** + * 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.suppliers; + +import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams; +import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget; + +/** + * Interface for target backend data retrieval provider for Management View. + * + */ +public interface TargetManagementStateDataSupplier extends DataSupplier { + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplierImpl.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplierImpl.java new file mode 100644 index 000000000..3744b6636 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/data/suppliers/TargetManagementStateDataSupplierImpl.java @@ -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.common.data.suppliers; + +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams; +import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; +import org.eclipse.hawkbit.ui.common.data.providers.TargetManagementStateDataProvider; +import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget; + +import com.vaadin.data.provider.DataCommunicator; +import com.vaadin.data.provider.DataProvider; + +/** + * Target backend data retrieval provider for Management View default + * implementation. + * + */ +public class TargetManagementStateDataSupplierImpl implements TargetManagementStateDataSupplier { + private final TargetManagementStateDataProvider dataProvider; + private final DataCommunicator dataCommunicator; + + /** + * Constructor. + * + * @param targetManagement + * Target Management + * @param targetToProxyTargetMapper + * Backend to UI Proxy target entity mapper + */ + public TargetManagementStateDataSupplierImpl(final TargetManagement targetManagement, + final TargetToProxyTargetMapper targetToProxyTargetMapper) { + this.dataProvider = new TargetManagementStateDataProvider(targetManagement, targetToProxyTargetMapper); + this.dataCommunicator = new DataCommunicator<>(); + } + + @Override + public DataProvider dataProvider() { + return dataProvider; + } + + @Override + public DataCommunicator dataCommunicator() { + return dataCommunicator; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/MetaDataWindowGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/MetaDataWindowGrid.java index 2c586db3d..4d3d62201 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/MetaDataWindowGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/MetaDataWindowGrid.java @@ -52,20 +52,21 @@ public class MetaDataWindowGrid extends AbstractGrid implem * callback method to delete metadata entities * */ - public MetaDataWindowGrid(final CommonUiDependencies uiDependencies, final AbstractMetaDataDataProvider dataProvider,final BooleanSupplier hasMetadataChangePermission, + public MetaDataWindowGrid(final CommonUiDependencies uiDependencies, + final AbstractMetaDataDataProvider dataProvider, final BooleanSupplier hasMetadataChangePermission, final Predicate> itemsDeletionCallback) { super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); this.hasMetadataChangePermission = hasMetadataChangePermission; - this.metaDataDeleteSupport = new DeleteSupport<>(this, i18n, uiDependencies.getUiNotification(), "caption.metadata", - "caption.metadata.plur", ProxyMetaData::getKey, itemsDeletionCallback, + this.metaDataDeleteSupport = new DeleteSupport<>(this, i18n, uiDependencies.getUiNotification(), + "caption.metadata", "caption.metadata.plur", ProxyMetaData::getKey, itemsDeletionCallback, UIComponentIdProvider.METADATA_DELETE_CONFIRMATION_DIALOG); setFilterSupport(new FilterSupport<>(dataProvider)); // we don't need to send selection events, because details layout // is part of MetaData Window - setSelectionSupport(new SelectionSupport(this)); + setSelectionSupport(new SelectionSupport<>(this)); getSelectionSupport().enableSingleSelection(); init(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/distributionset/AbstractDsGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/distributionset/AbstractDsGrid.java index 37da9a5fc..d951a0428 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/distributionset/AbstractDsGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/distributionset/AbstractDsGrid.java @@ -61,8 +61,8 @@ public abstract class AbstractDsGrid extends AbstractGrid(this, eventBus, EventLayout.DS_LIST, view, - this::mapIdToProxyEntity, this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); + setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.DS_LIST, view, this::mapIdToProxyEntity, + this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); if (distributionSetGridLayoutUiState.isMaximized()) { getSelectionSupport().disableSelection(); } else { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGrid.java index 0de753264..4c755472e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGrid.java @@ -19,7 +19,9 @@ import org.eclipse.hawkbit.ui.common.grid.support.SelectionSupport; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; +import com.vaadin.data.provider.DataCommunicator; import com.vaadin.data.provider.DataProviderListener; +import com.vaadin.data.provider.Query; import com.vaadin.ui.Grid; import com.vaadin.ui.components.grid.GridSelectionModel; @@ -70,6 +72,25 @@ public abstract class AbstractGrid extends */ protected AbstractGrid(final VaadinMessageSource i18n, final UIEventBus eventBus, final SpPermissionChecker permissionChecker) { + this(i18n, eventBus, permissionChecker, new DataCommunicator<>()); + } + + /** + * Constructor. + * + * @param i18n + * i18n + * @param eventBus + * eventBus + * @param permissionChecker + * permissionChecker + * @param dataCommunicator + * dataCommunicator + */ + protected AbstractGrid(final VaadinMessageSource i18n, final UIEventBus eventBus, + final SpPermissionChecker permissionChecker, final DataCommunicator dataCommunicator) { + super(dataCommunicator); + this.i18n = i18n; this.eventBus = eventBus; this.permissionChecker = permissionChecker; @@ -136,7 +157,7 @@ public abstract class AbstractGrid extends * Get total number of items. */ public int getDataSize() { - return getDataCommunicator().getDataProviderSize(); + return getDataProvider().size(new Query<>()); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/DeleteSupport.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/DeleteSupport.java index 3fc2da023..1b20adaad 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/DeleteSupport.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/DeleteSupport.java @@ -158,6 +158,7 @@ public class DeleteSupport { grid.deselectAll(); boolean isDeletionSuccessfull = false; + RuntimeException deletionException = null; try { isDeletionSuccessfull = itemsDeletionCallback.test(itemsToBeDeleted); } catch (final RuntimeException ex) { @@ -165,12 +166,16 @@ public class DeleteSupport { .map(String::valueOf).collect(Collectors.joining(",")); LOG.warn("Deletion of {} with ids '{}' failed: {}", localizedEntityTypeSing, itemsToBeDeletedIds, ex.getMessage()); + deletionException = ex; } if (isDeletionSuccessfull) { notification.displaySuccess(successNotificationText); } else { notification.displayWarning(failureNotificationText); + if (deletionException != null) { + throw deletionException; + } } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/FilterSupport.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/FilterSupport.java index faee89fb6..9a8f63735 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/FilterSupport.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/FilterSupport.java @@ -11,23 +11,27 @@ package org.eclipse.hawkbit.ui.common.grid.support; import java.util.EnumMap; import java.util.function.BiConsumer; +import java.util.function.UnaryOperator; import org.eclipse.hawkbit.ui.common.event.FilterType; import com.vaadin.data.provider.ConfigurableFilterDataProvider; import com.vaadin.data.provider.DataProvider; +import com.vaadin.data.provider.DataProviderWrapper; +import com.vaadin.data.provider.Query; /** * Support for Filter in Grid * * @param - * Generic type + * Data provider Proxy entity type * @param - * Generic type + * Custom filter type */ public class FilterSupport { - private final ConfigurableFilterDataProvider filterDataProvider; + private final CustomFilterDataProviderWrapper filterDataProvider; private final EnumMap> filterTypeToSetterMapping; + private final UnaryOperator filterCloner; private final Runnable afterRefreshFilterCallback; private F entityFilter; @@ -36,23 +40,51 @@ public class FilterSupport { * Constructor for FilterSupport * * @param dataProvider - * Data provider for filter + * Data provider that should be enhanced with a custom filter */ public FilterSupport(final DataProvider dataProvider) { - this(dataProvider, null); + this(dataProvider, null, null); } /** * Constructor for FilterSupport * * @param dataProvider - * Data provider for filter + * Data provider that should be enhanced with a custom filter + * @param filterCloner + * Creates a clone for a filter + */ + public FilterSupport(final DataProvider dataProvider, final UnaryOperator filterCloner) { + this(dataProvider, filterCloner, null); + } + + /** + * Constructor for FilterSupport + * + * @param dataProvider + * Data provider that should be enhanced with a custom filter * @param afterRefreshFilterCallback - * Runnable + * Callback to be called after filter/data refresh */ public FilterSupport(final DataProvider dataProvider, final Runnable afterRefreshFilterCallback) { - this.filterDataProvider = dataProvider.withConfigurableFilter(); + this(dataProvider, null, afterRefreshFilterCallback); + } + + /** + * Constructor for FilterSupport + * + * @param dataProvider + * Data provider that should be enhanced with a custom filter + * @param filterCloner + * Creates a clone for a filter + * @param afterRefreshFilterCallback + * Callback to be called after filter/data refresh + */ + public FilterSupport(final DataProvider dataProvider, final UnaryOperator filterCloner, + final Runnable afterRefreshFilterCallback) { + this.filterDataProvider = new CustomFilterDataProviderWrapper<>(dataProvider); this.filterTypeToSetterMapping = new EnumMap<>(FilterType.class); + this.filterCloner = filterCloner; this.afterRefreshFilterCallback = afterRefreshFilterCallback; } @@ -121,7 +153,9 @@ public class FilterSupport { * Refresh filter data */ public void refreshFilter() { - filterDataProvider.setFilter(entityFilter); + // data provider receives a fresh copy of current entity filter + // to make it effectively immutable + filterDataProvider.setFilter(filterCloner != null ? filterCloner.apply(entityFilter) : entityFilter); if (afterRefreshFilterCallback != null) { afterRefreshFilterCallback.run(); @@ -131,7 +165,7 @@ public class FilterSupport { /** * @return Filter data provider */ - public ConfigurableFilterDataProvider getFilterDataProvider() { + public CustomFilterDataProviderWrapper getFilterDataProvider() { return filterDataProvider; } @@ -215,4 +249,50 @@ public class FilterSupport { } } } + + /** + * Data provider with custom filter that can be set programmatically. + * + * @param + * Data provider Proxy entity type + * @param + * Custom filter type + */ + public static class CustomFilterDataProviderWrapper extends DataProviderWrapper + implements ConfigurableFilterDataProvider { + private static final long serialVersionUID = 1L; + + private transient F customFilter; + + /** + * Constructor. + * + * @param dataProvider + * the wrapped data provider + */ + public CustomFilterDataProviderWrapper(final DataProvider dataProvider) { + super(dataProvider); + } + + @Override + protected F getFilter(final Query query) { + // Filter of Void query is always null, so can be ignored + return getFilter(); + } + + /** + * Gets the custom filter. + * + * @return custom filter + */ + public F getFilter() { + return customFilter; + } + + @Override + public void setFilter(final F filter) { + this.customFilter = filter; + refreshAll(); + } + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/SelectionSupport.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/SelectionSupport.java index 7adc08ccc..a86f6ab3c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/SelectionSupport.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/support/SelectionSupport.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.grid.support; import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -23,6 +24,7 @@ import org.eclipse.hawkbit.ui.common.event.EventTopics; import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.SelectionChangedEventPayload; import org.eclipse.hawkbit.ui.common.event.SelectionChangedEventPayload.SelectionChangedEventType; +import org.springframework.util.CollectionUtils; import org.vaadin.spring.events.EventBus.UIEventBus; import com.vaadin.shared.Registration; @@ -248,15 +250,12 @@ public class SelectionSupport { return false; } - final int size = grid.getDataCommunicator().getDataProviderSize(); - if (size > 0) { - final T firstItem = grid.getDataCommunicator().fetchItemsWithRange(0, 1).get(0); + final List firstItem = grid.getDataCommunicator().fetchItemsWithRange(0, 1); - if (firstItem != null) { - grid.select(firstItem); + if (!CollectionUtils.isEmpty(firstItem)) { + grid.select(firstItem.get(0)); - return true; - } + return true; } grid.deselectAll(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetGrid.java index 8b83ad470..dfbdecf9f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetGrid.java @@ -81,8 +81,10 @@ public class DistributionSetGrid extends AbstractDsGrid(new DistributionSetDistributionsStateDataProvider(dsManagement, - dsTypeManagement, dsToProxyDistributionMapper), getSelectionSupport()::deselectAll)); + setFilterSupport(new FilterSupport<>( + new DistributionSetDistributionsStateDataProvider(dsManagement, dsTypeManagement, + dsToProxyDistributionMapper), + DsDistributionsFilterParams::new, getSelectionSupport()::deselectAll)); initFilterMappings(); getFilterSupport().setFilter(new DsDistributionsFilterParams()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/error/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/error/HawkbitUIErrorHandler.java index 78495fbe0..fe98c366d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/error/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/error/HawkbitUIErrorHandler.java @@ -58,6 +58,10 @@ public class HawkbitUIErrorHandler implements ErrorHandler { @Override public void error(final ErrorEvent event) { + if (LOG.isDebugEnabled()) { + LOG.debug("Ui error received. Trying to extract details...", event.getThrowable()); + } + final Page currentPage = getPageFrom(event); final List errorDetails = extractErrorDetails(event); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java index 32cae63c6..123f737a9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonUiDependencies; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventViewAware; @@ -63,17 +64,19 @@ public class FilterManagementView extends VerticalLayout implements View { final FilterManagementUIState filterManagementUIState, final RsqlValidationOracle rsqlValidationOracle, final TargetFilterQueryManagement targetFilterQueryManagement, final SpPermissionChecker permissionChecker, final UINotification notification, final UiProperties uiProperties, final EntityFactory entityFactory, - final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement) { + final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement, + final TargetFilterStateDataSupplier targetFilterStateDataSupplier) { this.filterManagementUIState = filterManagementUIState; - final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, notification, - permissionChecker); + final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, + notification, permissionChecker); this.targetFilterGridLayout = new TargetFilterGridLayout(uiDependencies, targetFilterQueryManagement, targetManagement, distributionSetManagement, filterManagementUIState); - this.targetFilterDetailsLayout = new TargetFilterDetailsLayout(uiDependencies, uiProperties, rsqlValidationOracle, - targetManagement, targetFilterQueryManagement, filterManagementUIState.getDetailsLayoutUiState()); + this.targetFilterDetailsLayout = new TargetFilterDetailsLayout(uiDependencies, uiProperties, + rsqlValidationOracle, targetFilterQueryManagement, targetFilterStateDataSupplier, + filterManagementUIState.getDetailsLayoutUiState()); final Map layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); layoutVisibilityHandlers.put(EventLayout.TARGET_FILTER_QUERY_LIST, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterDetailsLayout.java index 1051ced93..5a66742cf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterDetailsLayout.java @@ -9,12 +9,12 @@ package org.eclipse.hawkbit.ui.filtermanagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; -import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonUiDependencies; 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.suppliers.TargetFilterStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventView; @@ -38,7 +38,7 @@ public class TargetFilterDetailsLayout extends AbstractGridComponentLayout { private final transient FilterChangedListener targetFilterListener; /** - * TargetFilterDetailsLayout constructor + * TargetFilterDetailsLayout constructor. * * @param uiDependencies * {@link CommonUiDependencies} @@ -46,20 +46,22 @@ public class TargetFilterDetailsLayout extends AbstractGridComponentLayout { * properties * @param rsqlValidationOracle * to get RSQL validation and suggestions - * @param targetManagement - * management to get targets matching the filters * @param targetFilterManagement * management to CRUD target filters + * @param targetFilterStateDataSupplier + * target grid data supplier * @param uiState * to persist the user interaction */ public TargetFilterDetailsLayout(final CommonUiDependencies uiDependencies, final UiProperties uiProperties, - final RsqlValidationOracle rsqlValidationOracle, final TargetManagement targetManagement, - final TargetFilterQueryManagement targetFilterManagement, final TargetFilterDetailsLayoutUiState uiState) { + final RsqlValidationOracle rsqlValidationOracle, final TargetFilterQueryManagement targetFilterManagement, + final TargetFilterStateDataSupplier targetFilterStateDataSupplier, + final TargetFilterDetailsLayoutUiState uiState) { this.targetFilterDetailsGridHeader = new TargetFilterDetailsGridHeader(uiDependencies, targetFilterManagement, uiProperties, rsqlValidationOracle, uiState); - this.targetFilterTargetGrid = new TargetFilterTargetGrid(uiDependencies, targetManagement, uiState); + this.targetFilterTargetGrid = new TargetFilterTargetGrid(uiDependencies, targetFilterStateDataSupplier, + uiState); this.targetFilterCountMessageLabel = new TargetFilterCountMessageLabel(uiDependencies.getI18n()); initGridDataUpdatedListener(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTargetGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTargetGrid.java index 2dde8d8b8..e54609fd2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTargetGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTargetGrid.java @@ -8,13 +8,11 @@ */ package org.eclipse.hawkbit.ui.filtermanagement; -import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.TargetStatusIconSupplier; -import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; -import org.eclipse.hawkbit.ui.common.data.providers.TargetFilterStateDataProvider; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.FilterType; import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; import org.eclipse.hawkbit.ui.common.grid.support.FilterSupport; @@ -36,14 +34,25 @@ public class TargetFilterTargetGrid extends AbstractGrid { private final TargetFilterDetailsLayoutUiState uiState; - TargetFilterTargetGrid(final CommonUiDependencies uiDependencies, final TargetManagement targetManagement, + /** + * TargetFilterTargetGrid constructor. + * + * @param uiDependencies + * {@link CommonUiDependencies} + * @param targetFilterStateDataSupplier + * data supplier + * @param uiState + * layout state + */ + public TargetFilterTargetGrid(final CommonUiDependencies uiDependencies, + final TargetFilterStateDataSupplier targetFilterStateDataSupplier, final TargetFilterDetailsLayoutUiState uiState) { - super(uiDependencies.getI18n(), uiDependencies.getEventBus()); + super(uiDependencies.getI18n(), uiDependencies.getEventBus(), null, + targetFilterStateDataSupplier.dataCommunicator()); this.uiState = uiState; - setFilterSupport(new FilterSupport<>( - new TargetFilterStateDataProvider(targetManagement, new TargetToProxyTargetMapper(i18n)))); + setFilterSupport(new FilterSupport<>(targetFilterStateDataSupplier.dataProvider())); initFilterMappings(); targetStatusIconSupplier = new TargetStatusIconSupplier<>(i18n, ProxyTarget::getUpdateStatus, TARGET_STATUS_ID); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java index 394c31f88..73b8ccdd6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java @@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.CommonUiDependencies; +import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventViewAware; @@ -95,21 +96,23 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo final TargetTagManagement targetTagManagement, final DistributionSetTagManagement distributionSetTagManagement, final TargetFilterQueryManagement targetFilterQueryManagement, final SystemManagement systemManagement, - final TenantConfigurationManagement configManagement, final SystemSecurityContext systemSecurityContext, - @Qualifier("uiExecutor") final Executor uiExecutor) { + final TenantConfigurationManagement configManagement, + final TargetManagementStateDataSupplier targetManagementStateDataSupplier, + final SystemSecurityContext systemSecurityContext, @Qualifier("uiExecutor") final Executor uiExecutor) { this.permChecker = permChecker; this.managementUIState = managementUIState; - final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, uiNotification, - permChecker); + final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, + uiNotification, permChecker); if (permChecker.hasTargetReadPermission()) { this.targetTagFilterLayout = new TargetTagFilterLayout(uiDependencies, managementUIState, targetFilterQueryManagement, targetTagManagement, targetManagement, managementUIState.getTargetTagFilterLayoutUiState()); - this.targetGridLayout = new TargetGridLayout(uiDependencies, targetManagement, deploymentManagement, uiProperties, - targetTagManagement, distributionSetManagement, uiExecutor, configManagement, systemSecurityContext, + this.targetGridLayout = new TargetGridLayout(uiDependencies, targetManagement, deploymentManagement, + uiProperties, targetTagManagement, distributionSetManagement, uiExecutor, configManagement, + targetManagementStateDataSupplier, systemSecurityContext, managementUIState.getTargetTagFilterLayoutUiState(), managementUIState.getTargetGridLayoutUiState(), managementUIState.getTargetBulkUploadUiState(), managementUIState.getDistributionGridLayoutUiState()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java index 7a56cb0e7..35d03462e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java @@ -15,8 +15,8 @@ import java.util.Optional; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.CommonUiDependencies; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.ActionStatusIconSupplier; import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.ActionTypeIconSupplier; @@ -84,7 +84,7 @@ public class ActionHistoryGrid extends AbstractGrid { private final transient MasterEntitySupport masterEntitySupport; - ActionHistoryGrid(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement, + public ActionHistoryGrid(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement, final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState) { super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); @@ -93,7 +93,7 @@ public class ActionHistoryGrid extends AbstractGrid { this.actionToProxyActionMapper = new ActionToProxyActionMapper(); // currently we do not restore action history selection - setSelectionSupport(new SelectionSupport(this, eventBus, EventLayout.ACTION_HISTORY_LIST, + setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.ACTION_HISTORY_LIST, EventView.DEPLOYMENT, this::mapIdToProxyEntity, null, null)); if (actionHistoryGridLayoutUiState.isMaximized()) { getSelectionSupport().enableSingleSelection(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusGrid.java index 624eef028..2bdfccdc3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusGrid.java @@ -48,11 +48,12 @@ public class ActionStatusGrid extends AbstractGrid { * @param deploymentManagement * deploymentManagement */ - protected ActionStatusGrid(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement) { + public ActionStatusGrid(final CommonUiDependencies uiDependencies, + final DeploymentManagement deploymentManagement) { super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); - setSelectionSupport(new SelectionSupport(this, eventBus, - EventLayout.ACTION_HISTORY_STATUS_LIST, EventView.DEPLOYMENT, null, null, null)); + setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.ACTION_HISTORY_STATUS_LIST, + EventView.DEPLOYMENT, null, null, null)); getSelectionSupport().enableSingleSelection(); setFilterSupport(new FilterSupport<>( diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusMsgGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusMsgGrid.java index 043814a83..c61959568 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusMsgGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusMsgGrid.java @@ -44,10 +44,11 @@ public class ActionStatusMsgGrid extends AbstractGrid { private final Registration itemClickListenerRegistration; - protected ActionStatusMsgGrid(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement) { + public ActionStatusMsgGrid(final CommonUiDependencies uiDependencies, + final DeploymentManagement deploymentManagement) { super(uiDependencies.getI18n(), uiDependencies.getEventBus(), uiDependencies.getPermChecker()); - setSelectionSupport(new SelectionSupport(this)); + setSelectionSupport(new SelectionSupport<>(this)); getSelectionSupport().enableSingleSelection(); addStyleName(SPUIStyleDefinitions.ACTION_HISTORY_MESSAGE_GRID); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionGrid.java index 906d0dabf..ae734bc0c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionGrid.java @@ -126,7 +126,7 @@ public class DistributionGrid extends AbstractDsGrid { setFilterSupport(new FilterSupport<>( new DistributionSetManagementStateDataProvider(distributionSetManagement, dsToProxyDistributionMapper), - getSelectionSupport()::deselectAll)); + DsManagementFilterParams::new, getSelectionSupport()::deselectAll)); initFilterMappings(); getFilterSupport().setFilter(new DsManagementFilterParams()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetCountMessageLabel.java similarity index 96% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetCountMessageLabel.java index c167242b6..02eb0b423 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetCountMessageLabel.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management; +package org.eclipse.hawkbit.ui.management.targettable; import java.util.Collection; @@ -28,7 +28,7 @@ import com.vaadin.ui.Label; * Count message label which display current filter details and details on * pinning. */ -public class CountMessageLabel extends AbstractFooterSupport { +public class TargetCountMessageLabel extends AbstractFooterSupport { private final VaadinMessageSource i18n; private final TargetManagement targetManagement; @@ -43,7 +43,7 @@ public class CountMessageLabel extends AbstractFooterSupport { * @param i18n * I18N */ - public CountMessageLabel(final TargetManagement targetManagement, final VaadinMessageSource i18n) { + public TargetCountMessageLabel(final TargetManagement targetManagement, final VaadinMessageSource i18n) { this.targetManagement = targetManagement; this.i18n = i18n; this.targetCountLabel = new Label(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGrid.java index 37a0db35e..fab8d540a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGrid.java @@ -29,9 +29,9 @@ import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.TargetPollingStat import org.eclipse.hawkbit.ui.common.builder.StatusIconBuilder.TargetStatusIconSupplier; import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams; import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; -import org.eclipse.hawkbit.ui.common.data.providers.TargetManagementStateDataProvider; 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.suppliers.TargetManagementStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; import org.eclipse.hawkbit.ui.common.event.EventLayout; @@ -104,6 +104,8 @@ public class TargetGrid extends AbstractGrid(this, eventBus, EventLayout.TARGET_LIST, - EventView.DEPLOYMENT, this::mapIdToProxyEntity, this::getSelectedEntityIdFromUiState, - this::setSelectedEntityIdToUiState)); + setSelectionSupport(new SelectionSupport<>(this, eventBus, EventLayout.TARGET_LIST, EventView.DEPLOYMENT, + this::mapIdToProxyEntity, this::getSelectedEntityIdFromUiState, this::setSelectedEntityIdToUiState)); if (targetGridLayoutUiState.isMaximized()) { getSelectionSupport().disableSelection(); } else { @@ -164,9 +167,8 @@ public class TargetGrid extends AbstractGrid(new TargetManagementStateDataProvider(targetManagement, targetToProxyTargetMapper), - getSelectionSupport()::deselectAll)); + setFilterSupport(new FilterSupport<>(targetManagementStateDataSupplier.dataProvider(), + TargetManagementFilterParams::new, getSelectionSupport()::deselectAll)); initFilterMappings(); getFilterSupport().setFilter(new TargetManagementFilterParams()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridHeader.java index c547e316a..83560e64c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridHeader.java @@ -79,7 +79,7 @@ public class TargetGridHeader extends AbstractEntityGridHeader { /** * Add distribution set filter drop area */ - public void addDsDroArea() { + public void addDsDropArea() { final Component distributionSetFilterDropArea = distributionSetFilterDropAreaSupport.getHeaderComponent(); addComponent(distributionSetFilterDropArea); setComponentAlignment(distributionSetFilterDropArea, Alignment.TOP_CENTER); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridLayout.java index 34e4e9cf0..51299a405 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetGridLayout.java @@ -24,6 +24,7 @@ import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet; 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.suppliers.TargetManagementStateDataSupplier; import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventTopics; @@ -44,7 +45,6 @@ import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridR import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedPinAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedSelectionAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedTagTokenAwareSupport; -import org.eclipse.hawkbit.ui.management.CountMessageLabel; import org.eclipse.hawkbit.ui.management.bulkupload.BulkUploadWindowBuilder; import org.eclipse.hawkbit.ui.management.bulkupload.TargetBulkUploadUiState; import org.eclipse.hawkbit.ui.management.dstable.DistributionGridLayoutUiState; @@ -60,7 +60,7 @@ public class TargetGridLayout extends AbstractGridComponentLayout { private final TargetGrid targetGrid; private final TargetDetailsHeader targetDetailsHeader; private final TargetDetails targetDetails; - private final transient CountMessageLabel countMessageLabel; + private final transient TargetCountMessageLabel countMessageLabel; private final transient GenericEventListener filterTabChangedListener; private final transient FilterChangedListener targetFilterListener; @@ -90,6 +90,8 @@ public class TargetGridLayout extends AbstractGridComponentLayout { * Executor * @param configManagement * TenantConfigurationManagement + * @param targetManagementStateDataSupplier + * target grid data supplier * @param systemSecurityContext * SystemSecurityContext * @param targetTagFilterLayoutUiState @@ -105,6 +107,7 @@ public class TargetGridLayout extends AbstractGridComponentLayout { final DeploymentManagement deploymentManagement, final UiProperties uiProperties, final TargetTagManagement targetTagManagement, final DistributionSetManagement distributionSetManagement, final Executor uiExecutor, final TenantConfigurationManagement configManagement, + final TargetManagementStateDataSupplier targetManagementStateDataSupplier, final SystemSecurityContext systemSecurityContext, final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState, final TargetGridLayoutUiState targetGridLayoutUiState, @@ -114,23 +117,24 @@ public class TargetGridLayout extends AbstractGridComponentLayout { EventView.DEPLOYMENT); final TargetMetaDataWindowBuilder targetMetaDataWindowBuilder = new TargetMetaDataWindowBuilder(uiDependencies, targetManagement); - final BulkUploadWindowBuilder bulkUploadWindowBuilder = new BulkUploadWindowBuilder(uiDependencies, uiProperties, - uiExecutor, targetManagement, deploymentManagement, targetTagManagement, distributionSetManagement, - targetBulkUploadUiState); + final BulkUploadWindowBuilder bulkUploadWindowBuilder = new BulkUploadWindowBuilder(uiDependencies, + uiProperties, uiExecutor, targetManagement, deploymentManagement, targetTagManagement, + distributionSetManagement, targetBulkUploadUiState); this.targetGridHeader = new TargetGridHeader(uiDependencies, targetWindowBuilder, bulkUploadWindowBuilder, targetTagFilterLayoutUiState, targetGridLayoutUiState, targetBulkUploadUiState); this.targetGridHeader.buildHeader(); - this.targetGridHeader.addDsDroArea(); + this.targetGridHeader.addDsDropArea(); this.targetGrid = new TargetGrid(uiDependencies, targetManagement, deploymentManagement, configManagement, - systemSecurityContext, uiProperties, targetGridLayoutUiState, distributionGridLayoutUiState, - targetTagFilterLayoutUiState); + targetManagementStateDataSupplier, systemSecurityContext, uiProperties, targetGridLayoutUiState, + distributionGridLayoutUiState, targetTagFilterLayoutUiState); - this.targetDetailsHeader = new TargetDetailsHeader(uiDependencies, targetWindowBuilder, targetMetaDataWindowBuilder); - this.targetDetails = new TargetDetails(uiDependencies, targetTagManagement, targetManagement, deploymentManagement, + this.targetDetailsHeader = new TargetDetailsHeader(uiDependencies, targetWindowBuilder, targetMetaDataWindowBuilder); + this.targetDetails = new TargetDetails(uiDependencies, targetTagManagement, targetManagement, + deploymentManagement, targetMetaDataWindowBuilder); - this.countMessageLabel = new CountMessageLabel(targetManagement, uiDependencies.getI18n()); + this.countMessageLabel = new TargetCountMessageLabel(targetManagement, uiDependencies.getI18n()); initGridDataUpdatedListener(); @@ -138,16 +142,16 @@ public class TargetGridLayout extends AbstractGridComponentLayout { EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged); this.targetFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class, new EventViewAware(EventView.DEPLOYMENT), targetGrid.getFilterSupport()); - this.pinningChangedListener = new PinningChangedListener<>(uiDependencies.getEventBus(), ProxyDistributionSet.class, - targetGrid.getPinSupport()); + this.pinningChangedListener = new PinningChangedListener<>(uiDependencies.getEventBus(), + ProxyDistributionSet.class, targetGrid.getPinSupport()); this.targetChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), new EventLayoutViewAware(EventLayout.TARGET_LIST, EventView.DEPLOYMENT), getMasterTargetAwareComponents()); this.selectTargetListener = new SelectGridEntityListener<>(uiDependencies.getEventBus(), new EventLayoutViewAware(EventLayout.TARGET_LIST, EventView.DEPLOYMENT), targetGrid.getSelectionSupport()); - this.targetModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTarget.class) - .entityModifiedAwareSupports(getTargetModifiedAwareSupports()).build(); + this.targetModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), + ProxyTarget.class).entityModifiedAwareSupports(getTargetModifiedAwareSupports()).build(); this.tagModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class) .entityModifiedAwareSupports(getTagModifiedAwareSupports()).parentEntityType(ProxyTarget.class).build(); this.bulkUploadListener = new BulkUploadChangedListener(uiDependencies.getEventBus(), @@ -252,7 +256,7 @@ public class TargetGridLayout extends AbstractGridComponentLayout { * * @return Count message label */ - public CountMessageLabel getCountMessageLabel() { + public TargetCountMessageLabel getCountMessageLabel() { return countMessageLabel; } }