View-scoped event listeners (#1134)

* added UI EntityNotFound error details extractor

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* changed Target count label to not rely on grid data change events but rather on EntityModified UI events to decide how to react dependand on the event type

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added current view check on entity modified events

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* unsubscribe/resubscribe event listeners on view leave/enter, reselect grid entities on view enter

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* fixed target grid count reset on initial load and after view change

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* re-evaluate filters on Deployment View enter

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added on view enter logic for rest of the views

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* introduced event listener aware layout and view, adapted code accordingly

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* fixed bulk upload

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added missing docs

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* adapted software module deselection upon master entity change

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* fixed npe in case master support is not present (Artifact View)

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* restructured amqp assignDistributionSetMultipleTimes test

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>

* added waiting for the messages to be dispached by test

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>
This commit is contained in:
Bondar Bogdan
2021-07-22 11:00:05 +02:00
committed by GitHub
parent 1a285849e6
commit ace2f00742
75 changed files with 1603 additions and 600 deletions

View File

@@ -8,9 +8,23 @@
*/ */
package org.eclipse.hawkbit.integration; package org.eclipse.hawkbit.integration;
import io.qameta.allure.Description; import static org.assertj.core.api.Assertions.assertThat;
import io.qameta.allure.Feature; import static org.eclipse.hawkbit.dmf.amqp.api.EventTopic.DOWNLOAD;
import io.qameta.allure.Story; import static org.eclipse.hawkbit.dmf.amqp.api.MessageType.EVENT;
import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY;
import java.util.AbstractMap.SimpleEntry;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.json.model.DmfActionRequest; import org.eclipse.hawkbit.dmf.json.model.DmfActionRequest;
@@ -55,22 +69,9 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Message;
import java.util.AbstractMap.SimpleEntry; import io.qameta.allure.Description;
import java.util.Arrays; import io.qameta.allure.Feature;
import java.util.Collections; import io.qameta.allure.Story;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.dmf.amqp.api.EventTopic.DOWNLOAD;
import static org.eclipse.hawkbit.dmf.amqp.api.MessageType.EVENT;
import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY;
@Feature("Component Tests - Device Management Federation API") @Feature("Component Tests - Device Management Federation API")
@Story("Amqp Message Dispatcher Service") @Story("Amqp Message Dispatcher Service")
@@ -147,33 +148,37 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12),
@Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 2) }) @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 3) })
public void assignDistributionSetMultipleTimes() { public void assignDistributionSetMultipleTimes() {
final String controllerId = TARGET_PREFIX + "assignDistributionSetMultipleTimes"; final String controllerId = TARGET_PREFIX + "assignDistributionSetMultipleTimes";
final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId); final DistributionSetAssignmentResult assignmentResult = registerTargetAndAssignDistributionSet(controllerId);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
final DistributionSet distributionSet2 = testdataFactory.createDistributionSet(); final DistributionSet distributionSet2 = testdataFactory.createDistributionSet();
testdataFactory.addSoftwareModuleMetadata(distributionSet2); testdataFactory.addSoftwareModuleMetadata(distributionSet2);
// first assignment will be canceled -> Open cancellations
// first assignment will be canceled -> Open cancellations -> No message through the DMF
assignDistributionSet(distributionSet2.getId(), controllerId); assignDistributionSet(distributionSet2.getId(), controllerId);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CANCEL_DOWNLOAD);
// should not get the message of the second assignment
assertDownloadAndInstallMessage(assignmentResult.getDistributionSet().getModules(), controllerId);
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId); assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
// cancelation message is returned upon polling
createAndSendThingCreated(controllerId, TENANT_EXIST); createAndSendThingCreated(controllerId, TENANT_EXIST);
waitUntilTargetHasStatus(controllerId, TargetUpdateStatus.PENDING); waitUntilEventMessagesAreDispatchedToTarget(EventTopic.CANCEL_DOWNLOAD);
assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId); assertCancelActionMessage(getFirstAssignedActionId(assignmentResult), controllerId);
// confirm the cancel of the first action should lead to expose the latest action // confirm the cancel of the first action should lead to expose the
// latest action
createAndSendActionStatusUpdateMessage(controllerId, getFirstAssignedActionId(assignmentResult), createAndSendActionStatusUpdateMessage(controllerId, getFirstAssignedActionId(assignmentResult),
DmfActionStatus.CANCELED); DmfActionStatus.CANCELED);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
// verify latest action is exposed // verify latest action is exposed
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId); assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
// latest action is returned upon polling
createAndSendThingCreated(controllerId, TENANT_EXIST);
waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL);
assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId);
} }
@Test @Test
@@ -401,8 +406,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Test @Test
@Description("If multi assignment is enabled finishing one rollout does not affect other rollouts of the target.") @Description("If multi assignment is enabled finishing one rollout does not affect other rollouts of the target.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = MultiActionAssignEvent.class, count = 3), @Expect(type = ActionCreatedEvent.class, count = 3), @Expect(type = MultiActionAssignEvent.class, count = 3),
@Expect(type = ActionUpdatedEvent.class, count = 5), @Expect(type = ActionCreatedEvent.class, count = 3), @Expect(type = ActionUpdatedEvent.class, count = 5),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 5), @Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 5), @Expect(type = TargetPollEvent.class, count = 1),

View File

@@ -19,6 +19,7 @@ import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSup
import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplierImpl; import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplierImpl;
import org.eclipse.hawkbit.ui.error.HawkbitUIErrorHandler; import org.eclipse.hawkbit.ui.error.HawkbitUIErrorHandler;
import org.eclipse.hawkbit.ui.error.extractors.ConstraintViolationErrorExtractor; import org.eclipse.hawkbit.ui.error.extractors.ConstraintViolationErrorExtractor;
import org.eclipse.hawkbit.ui.error.extractors.EntityNotFoundErrorExtractor;
import org.eclipse.hawkbit.ui.error.extractors.UiErrorDetailsExtractor; import org.eclipse.hawkbit.ui.error.extractors.UiErrorDetailsExtractor;
import org.eclipse.hawkbit.ui.error.extractors.UploadErrorExtractor; import org.eclipse.hawkbit.ui.error.extractors.UploadErrorExtractor;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
@@ -93,13 +94,18 @@ public class MgmtUiConfiguration {
/** /**
* UI Error handler bean. * UI Error handler bean.
* *
* @param i18n
* VaadinMessageSource
* @param uiErrorDetailsExtractor
* ui error details extractors
*
* @return UI Error handler * @return UI Error handler
*/ */
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
ErrorHandler uiErrorHandler(final VaadinMessageSource i18n, ErrorHandler uiErrorHandler(final VaadinMessageSource i18n,
final List<UiErrorDetailsExtractor> uiErrorDetailsExtractor) { final List<UiErrorDetailsExtractor> uiErrorDetailsExtractors) {
return new HawkbitUIErrorHandler(i18n, uiErrorDetailsExtractor); return new HawkbitUIErrorHandler(i18n, uiErrorDetailsExtractors);
} }
/** /**
@@ -115,6 +121,8 @@ public class MgmtUiConfiguration {
/** /**
* UI ConstraintViolation Error details extractor bean. * UI ConstraintViolation Error details extractor bean.
* *
* @param i18n
* VaadinMessageSource
* @return UI ConstraintViolation Error details extractor * @return UI ConstraintViolation Error details extractor
*/ */
@Bean @Bean
@@ -122,6 +130,18 @@ public class MgmtUiConfiguration {
return new ConstraintViolationErrorExtractor(i18n); return new ConstraintViolationErrorExtractor(i18n);
} }
/**
* UI Entity not found Error details extractor bean.
*
* @param i18n
* VaadinMessageSource
* @return UI EntityNotFound Error details extractor
*/
@Bean
UiErrorDetailsExtractor entityNotFoundErrorExtractor(final VaadinMessageSource i18n) {
return new EntityNotFoundErrorExtractor(i18n);
}
/** /**
* Vaadin4Spring servlet bean. * Vaadin4Spring servlet bean.
* *
@@ -135,6 +155,8 @@ public class MgmtUiConfiguration {
/** /**
* UI target entity mapper bean. * UI target entity mapper bean.
* *
* @param i18n
* VaadinMessageSource
* @return UI target entity mapper * @return UI target entity mapper
*/ */
@Bean @Bean
@@ -145,6 +167,10 @@ public class MgmtUiConfiguration {
/** /**
* UI Management target data supplier bean. * UI Management target data supplier bean.
* *
* @param targetManagement
* TargetManagement
* @param targetToProxyTargetMapper
* UI target entity mapper
* @return UI target data supplier for Management view * @return UI target data supplier for Management view
*/ */
@Bean @Bean
@@ -158,6 +184,10 @@ public class MgmtUiConfiguration {
/** /**
* UI Filter target data supplier bean. * UI Filter target data supplier bean.
* *
* @param targetManagement
* TargetManagement
* @param targetToProxyTargetMapper
* UI target entity mapper
* @return UI target data supplier for Filter view * @return UI target data supplier for Filter view
*/ */
@Bean @Bean

View File

@@ -10,11 +10,10 @@ package org.eclipse.hawkbit.ui.artifacts;
import static org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus.UPLOAD_STARTED; import static org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus.UPLOAD_STARTED;
import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.servlet.MultipartConfigElement; import javax.servlet.MultipartConfigElement;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
@@ -27,6 +26,7 @@ import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsGridLayout;
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleGridLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleGridLayout;
import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout; import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout;
import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress;
import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
@@ -47,7 +47,6 @@ import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewBeforeLeaveEvent; import com.vaadin.navigator.ViewBeforeLeaveEvent;
import com.vaadin.server.Page; import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeEvent;
@@ -56,14 +55,13 @@ import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/** /**
* Display artifacts upload view. * Display artifacts upload view.
*/ */
@UIScope @UIScope
@SpringView(name = UploadArtifactView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = UploadArtifactView.VIEW_NAME, ui = AbstractHawkbitUI.class)
public class UploadArtifactView extends VerticalLayout implements View, BrowserWindowResizeListener { public class UploadArtifactView extends AbstractEventListenersAwareView implements BrowserWindowResizeListener {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "spUpload"; public static final String VIEW_NAME = "spUpload";
@@ -107,6 +105,8 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
artifactUploadState.getArtifactDetailsGridLayoutUiState(), artifactManagement, artifactUploadState.getArtifactDetailsGridLayoutUiState(), artifactManagement,
softwareModuleManagement, multipartConfigElement); softwareModuleManagement, multipartConfigElement);
addEventAwareLayouts(Arrays.asList(smTypeFilterLayout, smGridLayout, artifactDetailsGridLayout));
final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class);
layoutVisibilityHandlers.put(EventLayout.SM_TYPE_FILTER, layoutVisibilityHandlers.put(EventLayout.SM_TYPE_FILTER,
new VisibilityHandler(this::showSmTypeLayout, this::hideSmTypeLayout)); new VisibilityHandler(this::showSmTypeLayout, this::hideSmTypeLayout));
@@ -129,16 +129,16 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
} }
} }
@PostConstruct @Override
void init() { protected void init() {
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
buildLayout(); super.init();
restoreState();
Page.getCurrent().addBrowserWindowResizeListener(this); Page.getCurrent().addBrowserWindowResizeListener(this);
} }
} }
private void buildLayout() { @Override
protected void buildLayout() {
setMargin(false); setMargin(false);
setSpacing(false); setSpacing(false);
setSizeFull(); setSizeFull();
@@ -164,24 +164,33 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
mainLayout.setExpandRatio(artifactDetailsGridLayout, 0.5F); mainLayout.setExpandRatio(artifactDetailsGridLayout, 0.5F);
} }
private void restoreState() { @Override
protected void restoreState() {
if (permChecker.hasReadRepositoryPermission()) {
restoreSmWidgetsState();
restoreArtifactWidgetsState();
}
super.restoreState();
}
private void restoreSmWidgetsState() {
if (artifactUploadState.getSmTypeFilterLayoutUiState().isHidden() if (artifactUploadState.getSmTypeFilterLayoutUiState().isHidden()
|| artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) { || artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) {
hideSmTypeLayout(); hideSmTypeLayout();
} else { } else {
showSmTypeLayout(); showSmTypeLayout();
} }
smTypeFilterLayout.restoreState();
if (artifactUploadState.getSmGridLayoutUiState().isMaximized()) { if (artifactUploadState.getSmGridLayoutUiState().isMaximized()) {
maximizeSmGridLayout(); maximizeSmGridLayout();
} }
smGridLayout.restoreState(); }
private void restoreArtifactWidgetsState() {
if (artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) { if (artifactUploadState.getArtifactDetailsGridLayoutUiState().isMaximized()) {
maximizeArtifactGridLayout(); maximizeArtifactGridLayout();
} }
artifactDetailsGridLayout.restoreState();
} }
private void showSmTypeLayout() { private void showSmTypeLayout() {
@@ -265,16 +274,29 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
} }
} }
@PreDestroy @Override
void destroy() { public String getViewName() {
return UploadArtifactView.VIEW_NAME;
}
@Override
protected void subscribeListeners() {
if (permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.subscribe();
layoutResizeListener.subscribe();
}
super.subscribeListeners();
}
@Override
protected void unsubscribeListeners() {
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.unsubscribe(); layoutVisibilityListener.unsubscribe();
layoutResizeListener.unsubscribe(); layoutResizeListener.unsubscribe();
smTypeFilterLayout.unsubscribeListener();
smGridLayout.unsubscribeListener();
artifactDetailsGridLayout.unsubscribeListener();
} }
super.unsubscribeListeners();
} }
@Override @Override
@@ -286,10 +308,12 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
if (Boolean.TRUE.equals(ok)) { if (Boolean.TRUE.equals(ok)) {
// Clear all queued file uploads // Clear all queued file uploads
artifactUploadState.clearFileStates(); artifactUploadState.clearFileStates();
event.navigate(); super.beforeLeave(event);
} else { } else {
// Send a PostViewChangeEvent to the DashboardMenu as if the navigation actually // Send a PostViewChangeEvent to the DashboardMenu
// happened to prevent the DashboardMenu navigation from getting stuck // as if the navigation actually
// happened to prevent the DashboardMenu navigation
// from getting stuck
final DashboardMenuItem dashboardMenuItem = dashboardMenu.getByViewName(VIEW_NAME); final DashboardMenuItem dashboardMenuItem = dashboardMenu.getByViewName(VIEW_NAME);
dashboardMenu.postViewChange(DashboardEvent.createPostViewChangeEvent(dashboardMenuItem)); dashboardMenu.postViewChange(DashboardEvent.createPostViewChangeEvent(dashboardMenuItem));
} }
@@ -297,7 +321,7 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
UI.getCurrent().addWindow(confirmDeleteDialog.getWindow()); UI.getCurrent().addWindow(confirmDeleteDialog.getWindow());
confirmDeleteDialog.getWindow().bringToFront(); confirmDeleteDialog.getWindow().bringToFront();
} else { } else {
event.navigate(); super.beforeLeave(event);
} }
} }

View File

@@ -58,7 +58,8 @@ public class ArtifactDetailsGridLayout extends AbstractGridComponentLayout {
* @param multipartConfigElement * @param multipartConfigElement
* MultipartConfigElement * MultipartConfigElement
*/ */
public ArtifactDetailsGridLayout(final CommonUiDependencies uiDependencies, final ArtifactUploadState artifactUploadState, public ArtifactDetailsGridLayout(final CommonUiDependencies uiDependencies,
final ArtifactUploadState artifactUploadState,
final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState, final ArtifactDetailsGridLayoutUiState artifactDetailsGridLayoutUiState,
final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement, final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement,
final MultipartConfigElement multipartConfigElement) { final MultipartConfigElement multipartConfigElement) {
@@ -66,8 +67,8 @@ public class ArtifactDetailsGridLayout extends AbstractGridComponentLayout {
this.artifactDetailsGrid = new ArtifactDetailsGrid(uiDependencies, artifactManagement); this.artifactDetailsGrid = new ArtifactDetailsGrid(uiDependencies, artifactManagement);
if (uiDependencies.getPermChecker().hasCreateRepositoryPermission()) { if (uiDependencies.getPermChecker().hasCreateRepositoryPermission()) {
this.uploadDropAreaLayout = new UploadDropAreaLayout(uiDependencies, artifactUploadState, multipartConfigElement, this.uploadDropAreaLayout = new UploadDropAreaLayout(uiDependencies, artifactUploadState,
softwareManagement, artifactManagement); multipartConfigElement, softwareManagement, artifactManagement);
buildLayout(artifactDetailsHeader, artifactDetailsGrid, uploadDropAreaLayout); buildLayout(artifactDetailsHeader, artifactDetailsGrid, uploadDropAreaLayout);
} else { } else {
@@ -115,9 +116,7 @@ public class ArtifactDetailsGridLayout extends AbstractGridComponentLayout {
showDetailsLayout(); showDetailsLayout();
} }
/** @Override
* Is called when view is shown to the user
*/
public void restoreState() { public void restoreState() {
artifactDetailsHeader.restoreState(); artifactDetailsHeader.restoreState();
@@ -126,10 +125,14 @@ public class ArtifactDetailsGridLayout extends AbstractGridComponentLayout {
} }
} }
/** @Override
* Unsubscribe the even listeners for selection change and fileupload public void subscribeListeners() {
*/ selectionChangedListener.subscribe();
public void unsubscribeListener() { fileUploadChangedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
selectionChangedListener.unsubscribe(); selectionChangedListener.unsubscribe();
fileUploadChangedListener.unsubscribe(); fileUploadChangedListener.unsubscribe();
} }

View File

@@ -12,6 +12,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -110,13 +111,28 @@ public class SoftwareModuleGrid extends AbstractGrid<ProxySoftwareModule, SwFilt
setFilterSupport(new FilterSupport<>( setFilterSupport(new FilterSupport<>(
new SoftwareModuleDataProvider(softwareModuleManagement, new SoftwareModuleDataProvider(softwareModuleManagement,
new AssignedSoftwareModuleToProxyMapper(softwareModuleToProxyMapper)), new AssignedSoftwareModuleToProxyMapper(softwareModuleToProxyMapper)),
SwFilterParams::new, getSelectionSupport()::deselectAll)); SwFilterParams::new, this::afterFilterRefresh));
initFilterMappings(); initFilterMappings();
getFilterSupport().setFilter(new SwFilterParams()); getFilterSupport().setFilter(new SwFilterParams());
this.numberOfArtifactUploadsForSm = new HashMap<>(); this.numberOfArtifactUploadsForSm = new HashMap<>();
} }
private void afterFilterRefresh() {
// keep selection on master distribution set change as it does not
// filter out any software module entries, only sorts them
if (masterFilterHasNotChanged()) {
getSelectionSupport().deselectAll();
}
}
private boolean masterFilterHasNotChanged() {
final Long filterDsId = getFilter().map(SwFilterParams::getLastSelectedDistributionId).orElse(null);
final Long masterDsId = getMasterEntitySupport() != null ? getMasterEntitySupport().getMasterId() : null;
return Objects.equals(filterDsId, masterDsId);
}
private void initFilterMappings() { private void initFilterMappings() {
getFilterSupport().addMapping(FilterType.SEARCH, SwFilterParams::setSearchText, getFilterSupport().addMapping(FilterType.SEARCH, SwFilterParams::setSearchText,
smGridLayoutUiState.getSearchFilter()); smGridLayoutUiState.getSearchFilter());

View File

@@ -22,7 +22,6 @@ import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
import org.eclipse.hawkbit.ui.common.event.EventTopics; import org.eclipse.hawkbit.ui.common.event.EventTopics;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport;
@@ -81,15 +80,15 @@ public class SoftwareModuleGridLayout extends AbstractSoftwareModuleGridLayout {
softwareModuleTypeManagement, getSmMetaDataWindowBuilder()); softwareModuleTypeManagement, getSmMetaDataWindowBuilder());
this.softwareModuleDetails.buildDetails(); this.softwareModuleDetails.buildDetails();
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.SM_LIST, getEventView());
addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxySoftwareModule.class, addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxySoftwareModule.class,
new EventViewAware(getEventView()), softwareModuleGrid.getFilterSupport())); layoutViewAware, softwareModuleGrid.getFilterSupport()));
addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.SM_LIST, getEventView()), getMasterSmAwareComponents())); getMasterSmAwareComponents()));
addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.SM_LIST, getEventView()),
softwareModuleGrid.getSelectionSupport())); softwareModuleGrid.getSelectionSupport()));
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxySoftwareModule.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxySoftwareModule.class)
.entityModifiedAwareSupports(getSmModifiedAwareSupports()).build()); .viewAware(layoutViewAware).entityModifiedAwareSupports(getSmModifiedAwareSupports()).build());
addEventListener(new GenericEventListener<>(uiDependencies.getEventBus(), EventTopics.FILE_UPLOAD_CHANGED, addEventListener(new GenericEventListener<>(uiDependencies.getEventBus(), EventTopics.FILE_UPLOAD_CHANGED,
this::onUploadChanged)); this::onUploadChanged));

View File

@@ -114,4 +114,9 @@ public class SMTypeFilterButtons extends AbstractTypeFilterButtons {
protected Window getUpdateWindow(final ProxyType clickedFilter) { protected Window getUpdateWindow(final ProxyType clickedFilter) {
return smTypeWindowBuilder.getWindowForUpdate(clickedFilter); return smTypeWindowBuilder.getWindowForUpdate(clickedFilter);
} }
@Override
protected boolean typeExists(final Long typeId) {
return softwareModuleTypeManagement.exists(typeId);
}
} }

View File

@@ -65,12 +65,13 @@ public class SMTypeFilterLayout extends AbstractFilterLayout {
this.smTypeFilterButtons = new SMTypeFilterButtons(uiDependencies, softwareModuleTypeManagement, this.smTypeFilterButtons = new SMTypeFilterButtons(uiDependencies, softwareModuleTypeManagement,
smTypeWindowBuilder, smTypeFilterLayoutUiState, eventView); smTypeWindowBuilder, smTypeFilterLayoutUiState, eventView);
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.SM_TYPE_FILTER, eventView);
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(), this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(),
new EventLayoutViewAware(EventLayout.SM_TYPE_FILTER, eventView), smTypeFilterButtons::hideActionColumns, layoutViewAware, smTypeFilterButtons::hideActionColumns, smTypeFilterButtons::showEditColumn,
smTypeFilterButtons::showEditColumn, smTypeFilterButtons::showDeleteColumn); smTypeFilterButtons::showDeleteColumn);
this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
ProxyType.class).entityModifiedAwareSupports(getEntityModifiedAwareSupports()) ProxyType.class).parentEntityType(ProxySoftwareModule.class).viewAware(layoutViewAware)
.parentEntityType(ProxySoftwareModule.class).build(); .entityModifiedAwareSupports(getEntityModifiedAwareSupports()).build();
buildLayout(); buildLayout();
} }
@@ -94,17 +95,24 @@ public class SMTypeFilterLayout extends AbstractFilterLayout {
return wrapFilterContent(smTypeFilterButtons); return wrapFilterContent(smTypeFilterButtons);
} }
/** @Override
* Is called when view is shown to the user
*/
public void restoreState() { public void restoreState() {
smTypeFilterButtons.restoreState(); smTypeFilterButtons.restoreState();
} }
/** @Override
* Unsubscribe the events listeners public void onViewEnter() {
*/ smTypeFilterButtons.reevaluateFilter();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
gridActionsVisibilityListener.subscribe();
entityModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
gridActionsVisibilityListener.unsubscribe(); gridActionsVisibilityListener.unsubscribe();
entityModifiedListener.unsubscribe(); entityModifiedListener.unsubscribe();
} }

View File

@@ -0,0 +1,123 @@
/**
* 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;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewBeforeLeaveEvent;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.ui.VerticalLayout;
/**
* Abstract class managing event listeners aware layouts.
*
*/
public abstract class AbstractEventListenersAwareView extends VerticalLayout implements View, ViewNameAware {
private static final long serialVersionUID = 1L;
private final transient List<EventListenersAwareLayout> eventAwareLayouts = new ArrayList<>();
private boolean initial;
/**
* Adds event aware layout.
*
* @param eventAwareLayout
* event aware layout to add
*/
protected void addEventAwareLayout(final EventListenersAwareLayout eventAwareLayout) {
if (eventAwareLayout != null) {
eventAwareLayouts.add(eventAwareLayout);
}
}
/**
* Adds a list of event aware layouts.
*
* @param eventAwareLayouts
* event aware layouts to add
*/
protected void addEventAwareLayouts(final Collection<EventListenersAwareLayout> eventAwareLayouts) {
eventAwareLayouts.forEach(this::addEventAwareLayout);
}
@PostConstruct
protected void init() {
buildLayout();
initial = true;
}
/**
* Builds view layout.
*
*/
protected abstract void buildLayout();
@Override
public void enter(final ViewChangeEvent event) {
subscribeListeners();
if (initial) {
restoreState();
initial = false;
return;
}
updateLayoutsOnViewEnter();
}
/**
* Subscribes all listeners of added event aware layouts to event bus.
*
*/
protected void subscribeListeners() {
eventAwareLayouts.forEach(EventListenersAwareLayout::subscribeListeners);
}
/**
* Restores session state of added event aware layouts.
*
*/
protected void restoreState() {
eventAwareLayouts.forEach(EventListenersAwareLayout::restoreState);
}
/**
* Called on on view enter for added event aware layouts to update their
* state.
*
*/
protected void updateLayoutsOnViewEnter() {
eventAwareLayouts.forEach(EventListenersAwareLayout::onViewEnter);
}
@Override
public void beforeLeave(final ViewBeforeLeaveEvent event) {
unsubscribeListeners();
event.navigate();
}
/**
* Unsubscribes all listeners of added event aware layouts to event bus.
*
*/
protected void unsubscribeListeners() {
eventAwareLayouts.forEach(EventListenersAwareLayout::unsubscribeListeners);
}
@PreDestroy
public void destroy() {
unsubscribeListeners();
}
}

View File

@@ -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;
/**
* Interface for event aware event listeners
*
*/
public interface EventListenersAwareLayout {
/**
* Restore components state
*/
default void restoreState() {
}
/**
* Update components on view enter
*/
default void onViewEnter() {
}
/**
* Subscribe event listeners
*/
default void subscribeListeners() {
}
/**
* Unsubscribe event listeners
*/
default void unsubscribeListeners() {
}
}

View File

@@ -0,0 +1,24 @@
/**
* 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;
/**
* Interface for getting view name
*
*/
@FunctionalInterface
public interface ViewNameAware {
/**
* Provides the name of a view
*
* @return view name
*/
String getViewName();
}

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.ui.common.data.mappers; package org.eclipse.hawkbit.ui.common.data.mappers;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyRolloutGroup; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyRolloutGroup;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
@@ -20,18 +19,6 @@ import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
public class RolloutGroupToProxyRolloutGroupMapper public class RolloutGroupToProxyRolloutGroupMapper
extends AbstractNamedEntityToProxyNamedEntityMapper<ProxyRolloutGroup, RolloutGroup> { extends AbstractNamedEntityToProxyNamedEntityMapper<ProxyRolloutGroup, RolloutGroup> {
/**
* Maps the rollout group to proxy rollout group
*
* @param group
* RolloutGroup
*
* @return the corresponding Rollout group
*/
public static ProxyRolloutGroup mapGroup(final RolloutGroup group) {
return new RolloutGroupToProxyRolloutGroupMapper().map(group);
}
@Override @Override
public ProxyRolloutGroup map(final RolloutGroup rolloutGroup) { public ProxyRolloutGroup map(final RolloutGroup rolloutGroup) {
final ProxyRolloutGroup proxyRolloutGroup = new ProxyRolloutGroup(); final ProxyRolloutGroup proxyRolloutGroup = new ProxyRolloutGroup();

View File

@@ -19,18 +19,6 @@ import org.eclipse.hawkbit.ui.common.data.proxies.ProxyRollout;
*/ */
public class RolloutToProxyRolloutMapper extends AbstractNamedEntityToProxyNamedEntityMapper<ProxyRollout, Rollout> { public class RolloutToProxyRolloutMapper extends AbstractNamedEntityToProxyNamedEntityMapper<ProxyRollout, Rollout> {
/**
* Maps the rollout to Proxy rollout
*
* @param rollout
* Rollout
*
* @return ProxyRollout
*/
public static ProxyRollout mapRollout(final Rollout rollout) {
return new RolloutToProxyRolloutMapper().map(rollout);
}
@Override @Override
public ProxyRollout map(final Rollout rollout) { public ProxyRollout map(final Rollout rollout) {
final ProxyRollout proxyRollout = new ProxyRollout(); final ProxyRollout proxyRollout = new ProxyRollout();

View File

@@ -8,6 +8,8 @@
*/ */
package org.eclipse.hawkbit.ui.common.data.suppliers; package org.eclipse.hawkbit.ui.common.data.suppliers;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.ui.common.data.mappers.TargetToProxyTargetMapper; 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.providers.TargetFilterStateDataProvider;
@@ -21,7 +23,9 @@ import com.vaadin.data.provider.DataProvider;
* implementation. * implementation.
* *
*/ */
public class TargetFilterStateDataSupplierImpl implements TargetFilterStateDataSupplier { public class TargetFilterStateDataSupplierImpl implements TargetFilterStateDataSupplier, Serializable {
private static final long serialVersionUID = 1L;
private final TargetFilterStateDataProvider dataProvider; private final TargetFilterStateDataProvider dataProvider;
private final DataCommunicator<ProxyTarget> dataCommunicator; private final DataCommunicator<ProxyTarget> dataCommunicator;

View File

@@ -8,6 +8,8 @@
*/ */
package org.eclipse.hawkbit.ui.common.data.suppliers; package org.eclipse.hawkbit.ui.common.data.suppliers;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams; 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.mappers.TargetToProxyTargetMapper;
@@ -22,7 +24,9 @@ import com.vaadin.data.provider.DataProvider;
* implementation. * implementation.
* *
*/ */
public class TargetManagementStateDataSupplierImpl implements TargetManagementStateDataSupplier { public class TargetManagementStateDataSupplierImpl implements TargetManagementStateDataSupplier, Serializable {
private static final long serialVersionUID = 1L;
private final TargetManagementStateDataProvider dataProvider; private final TargetManagementStateDataProvider dataProvider;
private final DataCommunicator<ProxyTarget> dataCommunicator; private final DataCommunicator<ProxyTarget> dataCommunicator;

View File

@@ -51,7 +51,7 @@ public abstract class AbstractDistributionSetGridLayout extends AbstractGridComp
* @param eventView * @param eventView
* EventView * EventView
*/ */
public AbstractDistributionSetGridLayout(final CommonUiDependencies uiDependencies, protected AbstractDistributionSetGridLayout(final CommonUiDependencies uiDependencies,
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext,
final TenantConfigurationManagement configManagement, final TenantConfigurationManagement configManagement,
final DistributionSetManagement distributionSetManagement, final DistributionSetManagement distributionSetManagement,
@@ -94,9 +94,11 @@ public abstract class AbstractDistributionSetGridLayout extends AbstractGridComp
/** /**
* Returns the {@link AbstractDsGrid} * Returns the {@link AbstractDsGrid}
* *
* @param <F>
* Generic filter type
* @return the distributionGrid * @return the distributionGrid
*/ */
public abstract <T extends DsFilterParams> AbstractDsGrid<T> getDistributionGrid(); public abstract <F extends DsFilterParams> AbstractDsGrid<F> getDistributionGrid();
/** /**
* Returns the {@link DistributionSetGridHeader} * Returns the {@link DistributionSetGridHeader}
@@ -135,9 +137,7 @@ public abstract class AbstractDistributionSetGridLayout extends AbstractGridComp
showDetailsLayout(); showDetailsLayout();
} }
/** @Override
* Restore the distribution grid state
*/
public void restoreState() { public void restoreState() {
getDistributionSetGridHeader().restoreState(); getDistributionSetGridHeader().restoreState();
getDistributionGrid().restoreState(); getDistributionGrid().restoreState();
@@ -147,10 +147,18 @@ public abstract class AbstractDistributionSetGridLayout extends AbstractGridComp
listeners.add(listener); listeners.add(listener);
} }
/** @Override
* Unsubscribe the event listeners. public void onViewEnter() {
*/ getDistributionGrid().getSelectionSupport().reselectCurrentEntity();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
listeners.forEach(TopicEventListener::subscribe);
}
@Override
public void unsubscribeListeners() {
listeners.forEach(TopicEventListener::unsubscribe); listeners.forEach(TopicEventListener::unsubscribe);
} }
} }

View File

@@ -15,6 +15,7 @@ import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder; import org.eclipse.hawkbit.ui.common.builder.GridComponentBuilder;
import org.eclipse.hawkbit.ui.common.data.filters.DsFilterParams;
import org.eclipse.hawkbit.ui.common.data.mappers.DistributionSetToProxyDistributionMapper; import org.eclipse.hawkbit.ui.common.data.mappers.DistributionSetToProxyDistributionMapper;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
@@ -36,9 +37,9 @@ import com.vaadin.ui.Button;
* Abstract class of distribution set grid * Abstract class of distribution set grid
* *
* @param <F> * @param <F>
* Generic type * Generic filter type
*/ */
public abstract class AbstractDsGrid<F> extends AbstractGrid<ProxyDistributionSet, F> { public abstract class AbstractDsGrid<F extends DsFilterParams> extends AbstractGrid<ProxyDistributionSet, F> {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
protected static final String DS_NAME_ID = "dsName"; protected static final String DS_NAME_ID = "dsName";

View File

@@ -8,9 +8,50 @@
*/ */
package org.eclipse.hawkbit.ui.common.event; package org.eclipse.hawkbit.ui.common.event;
import org.eclipse.hawkbit.ui.artifacts.UploadArtifactView;
import org.eclipse.hawkbit.ui.distributions.DistributionsView;
import org.eclipse.hawkbit.ui.filtermanagement.FilterManagementView;
import org.eclipse.hawkbit.ui.management.DeploymentView;
import org.eclipse.hawkbit.ui.rollout.RolloutView;
/** /**
* Enum constants for event view * Enum constants for event view
*/ */
public enum EventView { public enum EventView {
DEPLOYMENT, ROLLOUT, TARGET_FILTER, DISTRIBUTIONS, UPLOAD; DEPLOYMENT(DeploymentView.VIEW_NAME), ROLLOUT(RolloutView.VIEW_NAME), TARGET_FILTER(
FilterManagementView.VIEW_NAME), DISTRIBUTIONS(
DistributionsView.VIEW_NAME), UPLOAD(UploadArtifactView.VIEW_NAME);
private final String viewName;
/**
* Constructor.
*
* @param viewName
* View name
*/
EventView(final String viewName) {
this.viewName = viewName;
}
/**
* Get view name.
*
* @return view name
*/
public String getViewName() {
return viewName;
}
/**
* Matches event view with provided view name.
*
* @param viewName
* View name to match
*
* @return match
*/
public boolean matchByViewName(final String viewName) {
return this.viewName.equals(viewName);
}
} }

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.ui.common.filterlayout; package org.eclipse.hawkbit.ui.common.filterlayout;
import org.eclipse.hawkbit.ui.common.EventListenersAwareLayout;
import org.eclipse.hawkbit.ui.common.grid.header.AbstractGridHeader; import org.eclipse.hawkbit.ui.common.grid.header.AbstractGridHeader;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
@@ -19,7 +20,7 @@ import com.vaadin.ui.VerticalLayout;
/** /**
* Parent class for filter button layout. * Parent class for filter button layout.
*/ */
public abstract class AbstractFilterLayout extends VerticalLayout { public abstract class AbstractFilterLayout extends VerticalLayout implements EventListenersAwareLayout {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
protected void buildLayout() { protected void buildLayout() {

View File

@@ -56,9 +56,10 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
* @param tagFilterLayoutUiState * @param tagFilterLayoutUiState
* TagFilterLayoutUiState * TagFilterLayoutUiState
*/ */
public AbstractTagFilterButtons(final CommonUiDependencies uiDependencies, protected AbstractTagFilterButtons(final CommonUiDependencies uiDependencies,
final TagFilterLayoutUiState tagFilterLayoutUiState) { final TagFilterLayoutUiState tagFilterLayoutUiState) {
super(uiDependencies.getEventBus(), uiDependencies.getI18n(), uiDependencies.getUiNotification(), uiDependencies.getPermChecker()); super(uiDependencies.getEventBus(), uiDependencies.getI18n(), uiDependencies.getUiNotification(),
uiDependencies.getPermChecker());
this.uiNotification = uiDependencies.getUiNotification(); this.uiNotification = uiDependencies.getUiNotification();
this.tagFilterLayoutUiState = tagFilterLayoutUiState; this.tagFilterLayoutUiState = tagFilterLayoutUiState;
@@ -99,8 +100,18 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
tagFilterLayoutUiState.setClickedTagIdsWithName(activeTagIdsWithName); tagFilterLayoutUiState.setClickedTagIdsWithName(activeTagIdsWithName);
} }
/**
* Provides type of the master entity.
*
* @return type of the master entity
*/
protected abstract Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType(); protected abstract Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType();
/**
* Provides event view filter.
*
* @return event view filter.
*/
protected abstract EventView getView(); protected abstract EventView getView();
private void onNoTagChangedEvent(final ClickBehaviourType clickType) { private void onNoTagChangedEvent(final ClickBehaviourType clickType) {
@@ -146,6 +157,12 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
} }
} }
/**
* Tag deletion operation.
*
* @param tagToDelete
* tag to delete
*/
protected abstract void deleteTag(final ProxyTag tagToDelete); protected abstract void deleteTag(final ProxyTag tagToDelete);
/** /**
@@ -183,6 +200,13 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
updateWindow.setVisible(Boolean.TRUE); updateWindow.setVisible(Boolean.TRUE);
} }
/**
* Provides the window for updating tag
*
* @param clickedFilter
* tag to update
* @return update window
*/
protected abstract Window getUpdateWindow(final ProxyTag clickedFilter); protected abstract Window getUpdateWindow(final ProxyTag clickedFilter);
/** /**
@@ -212,6 +236,7 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
final Map<Long, String> tagsToRestore = tagFilterLayoutUiState.getClickedTagIdsWithName(); final Map<Long, String> tagsToRestore = tagFilterLayoutUiState.getClickedTagIdsWithName();
if (!CollectionUtils.isEmpty(tagsToRestore)) { if (!CollectionUtils.isEmpty(tagsToRestore)) {
removeNonExistingTags(tagsToRestore);
getFilterButtonClickBehaviour().setPreviouslyClickedFilterIdsWithName(tagsToRestore); getFilterButtonClickBehaviour().setPreviouslyClickedFilterIdsWithName(tagsToRestore);
} }
@@ -219,4 +244,35 @@ public abstract class AbstractTagFilterButtons extends AbstractFilterButtons<Pro
getNoTagButton().addStyleName(SPUIStyleDefinitions.SP_NO_TAG_BTN_CLICKED_STYLE); getNoTagButton().addStyleName(SPUIStyleDefinitions.SP_NO_TAG_BTN_CLICKED_STYLE);
} }
} }
private boolean removeNonExistingTags(final Map<Long, String> tagIdsWithName) {
final Collection<Long> tagIds = tagIdsWithName.keySet();
final Collection<Long> existingTagIds = filterExistingTagIds(tagIds);
if (tagIds.size() != existingTagIds.size()) {
return tagIds.retainAll(existingTagIds);
}
return false;
}
/**
* Filters out non-existant tags by ids.
*
* @param tagIds
* provided tag ids
* @return filtered list of existing tag ids
*/
protected abstract Collection<Long> filterExistingTagIds(final Collection<Long> tagIds);
/**
* Re-evaluates a filter (usually after view enter).
*
*/
public void reevaluateFilter() {
final Map<Long, String> clickedTags = getFilterButtonClickBehaviour().getPreviouslyClickedFilterIdsWithName();
if (!CollectionUtils.isEmpty(clickedTags) && removeNonExistingTags(clickedTags)) {
publishFilterChangedEvent(clickedTags);
}
}
} }

View File

@@ -45,9 +45,10 @@ public abstract class AbstractTypeFilterButtons extends AbstractFilterButtons<Pr
* @param typeFilterLayoutUiState * @param typeFilterLayoutUiState
* TypeFilterLayoutUiState * TypeFilterLayoutUiState
*/ */
public AbstractTypeFilterButtons(final CommonUiDependencies uiDependencies, protected AbstractTypeFilterButtons(final CommonUiDependencies uiDependencies,
final TypeFilterLayoutUiState typeFilterLayoutUiState) { final TypeFilterLayoutUiState typeFilterLayoutUiState) {
super(uiDependencies.getEventBus(), uiDependencies.getI18n(), uiDependencies.getUiNotification(), uiDependencies.getPermChecker()); super(uiDependencies.getEventBus(), uiDependencies.getI18n(), uiDependencies.getUiNotification(),
uiDependencies.getPermChecker());
this.uiNotification = uiDependencies.getUiNotification(); this.uiNotification = uiDependencies.getUiNotification();
this.typeFilterLayoutUiState = typeFilterLayoutUiState; this.typeFilterLayoutUiState = typeFilterLayoutUiState;
@@ -74,8 +75,18 @@ public abstract class AbstractTypeFilterButtons extends AbstractFilterButtons<Pr
typeFilterLayoutUiState.setClickedTypeId(typeId); typeFilterLayoutUiState.setClickedTypeId(typeId);
} }
/**
* Provides type of the master entity.
*
* @return type of the master entity
*/
protected abstract Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType(); protected abstract Class<? extends ProxyIdentifiableEntity> getFilterMasterEntityType();
/**
* Provides event view filter.
*
* @return event view filter.
*/
protected abstract EventView getView(); protected abstract EventView getView();
@Override @Override
@@ -106,8 +117,21 @@ public abstract class AbstractTypeFilterButtons extends AbstractFilterButtons<Pr
} }
} }
protected abstract boolean isDefaultType(final ProxyType typeToDelete); /**
* Checks if provided type is the default one.
*
* @param type
* provided type
* @return default type check
*/
protected abstract boolean isDefaultType(final ProxyType type);
/**
* Type deletion operation.
*
* @param typeToDelete
* type to delete
*/
protected abstract void deleteType(final ProxyType typeToDelete); protected abstract void deleteType(final ProxyType typeToDelete);
/** /**
@@ -144,6 +168,13 @@ public abstract class AbstractTypeFilterButtons extends AbstractFilterButtons<Pr
updateWindow.setVisible(Boolean.TRUE); updateWindow.setVisible(Boolean.TRUE);
} }
/**
* Provides the window for updating type
*
* @param clickedFilter
* type to update
* @return update window
*/
protected abstract Window getUpdateWindow(final ProxyType clickedFilter); protected abstract Window getUpdateWindow(final ProxyType clickedFilter);
@Override @Override
@@ -154,4 +185,26 @@ public abstract class AbstractTypeFilterButtons extends AbstractFilterButtons<Pr
getFilterButtonClickBehaviour().setPreviouslyClickedFilterId(lastClickedTypeId); getFilterButtonClickBehaviour().setPreviouslyClickedFilterId(lastClickedTypeId);
} }
} }
/**
* Check if provided type exists by id.
*
* @param typeId
* provided type id
* @return if type exists
*/
protected abstract boolean typeExists(final Long typeId);
/**
* Re-evaluates a filter (usually after view enter).
*
*/
public void reevaluateFilter() {
final Long clickedTypeId = getFilterButtonClickBehaviour().getPreviouslyClickedFilterId();
if (clickedTypeId != null && !typeExists(clickedTypeId)) {
getFilterButtonClickBehaviour().setPreviouslyClickedFilterId(null);
publishFilterChangedEvent(null);
}
}
} }

View File

@@ -188,12 +188,9 @@ public class DistributionSetFilterDropAreaSupport implements HeaderSupport {
if (draggingListener == null) { if (draggingListener == null) {
draggingListener = new EntityDraggingListener(eventBus, draggingListener = new EntityDraggingListener(eventBus,
Collections.singletonList(UIComponentIdProvider.DIST_TABLE_ID), dropAreaLayout); Collections.singletonList(UIComponentIdProvider.DIST_TABLE_ID), dropAreaLayout);
return;
} }
if (!draggingListener.isSubscribed()) { draggingListener.subscribe();
draggingListener.subscribe();
}
} }
@Override @Override

View File

@@ -66,15 +66,15 @@ public class DragAndDropSupport<T extends ProxyIdentifiableEntity> {
* Constructor for DragAndDropSupport * Constructor for DragAndDropSupport
* *
* @param grid * @param grid
* Vaadin Grid * Vaadin Grid
* @param i18n * @param i18n
* VaadinMessageSource * VaadinMessageSource
* @param notification * @param notification
* UINotification * UINotification
* @param sourceTargetAssignmentStrategies * @param sourceTargetAssignmentStrategies
* Key value pair of target and assignments * Key value pair of target and assignments
* @param eventBus * @param eventBus
* UIEventBus * UIEventBus
*/ */
public DragAndDropSupport(final AbstractGrid<T, ?> grid, final VaadinMessageSource i18n, public DragAndDropSupport(final AbstractGrid<T, ?> grid, final VaadinMessageSource i18n,
final UINotification notification, final UINotification notification,
@@ -95,7 +95,8 @@ public class DragAndDropSupport<T extends ProxyIdentifiableEntity> {
/** /**
* workaround for target/ds tags that currently do not support selection * workaround for target/ds tags that currently do not support selection
* *
* @param ignoreSelection Set to true for distribution set and targets * @param ignoreSelection
* Set to true for distribution set and targets
*/ */
public void ignoreSelection(final boolean ignoreSelection) { public void ignoreSelection(final boolean ignoreSelection) {
this.ignoreSelection = ignoreSelection; this.ignoreSelection = ignoreSelection;
@@ -137,9 +138,9 @@ public class DragAndDropSupport<T extends ProxyIdentifiableEntity> {
/** /**
* @param dragOrDropExtension * @param dragOrDropExtension
* AbstractExtension * AbstractExtension
* @param dragOrDropDescription * @param dragOrDropDescription
* Description for drag and drop * Description for drag and drop
* *
* @return true if grid supports drag and drop else false * @return true if grid supports drag and drop else false
*/ */
@@ -213,12 +214,9 @@ public class DragAndDropSupport<T extends ProxyIdentifiableEntity> {
private void addGridDropStylingListener() { private void addGridDropStylingListener() {
if (draggingListener == null) { if (draggingListener == null) {
draggingListener = new EntityDraggingListener(eventBus, sourceTargetAssignmentStrategies.keySet(), grid); draggingListener = new EntityDraggingListener(eventBus, sourceTargetAssignmentStrategies.keySet(), grid);
return;
} }
if (!draggingListener.isSubscribed()) { draggingListener.subscribe();
draggingListener.subscribe();
}
} }
private boolean isDropValid(final String sourceId, final T dropTargetItem, private boolean isDropValid(final String sourceId, final T dropTargetItem,

View File

@@ -169,6 +169,13 @@ public class FilterSupport<T, F> {
return filterDataProvider; return filterDataProvider;
} }
/**
* @return Original data provider
*/
public DataProvider<T, F> getOriginalDataProvider() {
return filterDataProvider.getDataProvider();
}
/** /**
* Verifies if filter type is supported * Verifies if filter type is supported
* *
@@ -294,5 +301,14 @@ public class FilterSupport<T, F> {
this.customFilter = filter; this.customFilter = filter;
refreshAll(); refreshAll();
} }
/**
* Gets original data provider.
*
* @return original data provider
*/
public DataProvider<T, F> getDataProvider() {
return dataProvider;
}
} }
} }

View File

@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
* Filter support in Master entity * Filter support in Master entity
* *
* @param <M> * @param <M>
* Generic type of ProxyIdentifiableEntity * Generic type of master entity
*/ */
public class MasterEntitySupport<M extends ProxyIdentifiableEntity> implements MasterEntityAwareComponent<M> { public class MasterEntitySupport<M extends ProxyIdentifiableEntity> implements MasterEntityAwareComponent<M> {
private final FilterSupport<?, ?> filterSupport; private final FilterSupport<?, ?> filterSupport;
@@ -31,7 +31,7 @@ public class MasterEntitySupport<M extends ProxyIdentifiableEntity> implements M
* Constructor for MasterEntitySupport * Constructor for MasterEntitySupport
* *
* @param filterSupport * @param filterSupport
* Filter support * Filter support
*/ */
public MasterEntitySupport(final FilterSupport<?, ?> filterSupport) { public MasterEntitySupport(final FilterSupport<?, ?> filterSupport) {
this(filterSupport, null); this(filterSupport, null);
@@ -41,9 +41,9 @@ public class MasterEntitySupport<M extends ProxyIdentifiableEntity> implements M
* Constructor for MasterEntitySupport * Constructor for MasterEntitySupport
* *
* @param filterSupport * @param filterSupport
* Filter support * Filter support
* @param masterEntityToFilterMapper * @param masterEntityToFilterMapper
* Master entity to filter mapper * Master entity to filter mapper
*/ */
public MasterEntitySupport(final FilterSupport<?, ?> filterSupport, public MasterEntitySupport(final FilterSupport<?, ?> filterSupport,
final Function<M, ?> masterEntityToFilterMapper) { final Function<M, ?> masterEntityToFilterMapper) {
@@ -57,16 +57,18 @@ public class MasterEntitySupport<M extends ProxyIdentifiableEntity> implements M
return; return;
} }
final Long masterEntityId = masterEntity != null ? masterEntity.getId() : null; filterSupport.updateFilter(FilterType.MASTER, getMasterEntityFilter(masterEntity));
masterId = masterEntityId;
if (masterEntity != null) { masterId = masterEntity != null ? masterEntity.getId() : null;
filterSupport.updateFilter(FilterType.MASTER, }
masterEntityToFilterMapper != null ? masterEntityToFilterMapper.apply(masterEntity)
: masterEntityId); private Object getMasterEntityFilter(final M masterEntity) {
} else { if (masterEntity == null) {
filterSupport.updateFilter(FilterType.MASTER, null); return null;
} }
return masterEntityToFilterMapper != null ? masterEntityToFilterMapper.apply(masterEntity)
: masterEntity.getId();
} }
/** /**

View File

@@ -230,7 +230,7 @@ public class SelectionSupport<T extends ProxyIdentifiableEntity> {
} }
/** /**
* @return Id of elected entity from the grid * @return Id of selected entity from the grid
*/ */
public Optional<Long> getSelectedEntityId() { public Optional<Long> getSelectedEntityId() {
if (isNoSelectionModel() && selectedEntityIdUiStateProvider != null) { if (isNoSelectionModel() && selectedEntityIdUiStateProvider != null) {
@@ -350,6 +350,16 @@ public class SelectionSupport<T extends ProxyIdentifiableEntity> {
} }
} }
/**
* Re-fetches and re-selects currently selected entity
*/
public void reselectCurrentEntity() {
getSelectedEntityId().ifPresent(selectedEntityId -> {
deselectAll();
selectEntityById(selectedEntityId);
});
}
@PreDestroy @PreDestroy
void destroy() { void destroy() {
removeListeners(); removeListeners();

View File

@@ -35,9 +35,9 @@ public abstract class AbstractFooterSupport {
} }
/** /**
* Get the count message label. * Get the footer message label.
* *
* @return count message * @return footer message
*/ */
protected abstract Label getFooterMessageLabel(); protected abstract Label getFooterMessageLabel();
} }

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.ui.common.layout; package org.eclipse.hawkbit.ui.common.layout;
import org.eclipse.hawkbit.ui.common.EventListenersAwareLayout;
import org.eclipse.hawkbit.ui.common.detailslayout.AbstractGridDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractGridDetailsLayout;
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
import org.eclipse.hawkbit.ui.common.grid.header.AbstractDetailsHeader; import org.eclipse.hawkbit.ui.common.grid.header.AbstractDetailsHeader;
@@ -24,7 +25,7 @@ import com.vaadin.ui.VerticalLayout;
* {@link AbstractGridHeader}, grid {@link AbstractGrid}, optional grid details * {@link AbstractGridHeader}, grid {@link AbstractGrid}, optional grid details
* {@link AbstractGridDetailsLayout} and optional footer. * {@link AbstractGridDetailsLayout} and optional footer.
*/ */
public abstract class AbstractGridComponentLayout extends VerticalLayout { public abstract class AbstractGridComponentLayout extends VerticalLayout implements EventListenersAwareLayout {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Component detailsLayout; private Component detailsLayout;

View File

@@ -0,0 +1,38 @@
/**
* 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.layout;
/**
* Interface for count aware component.
*
*/
public interface CountAwareComponent {
/**
* Adapts count on entities added.
*
* @param count
* added entities count
*/
void updateCountOnEntitiesAdded(final int count);
/**
* Adapts count on entities updated.
*
*/
void updateCountOnEntitiesUpdated();
/**
* Adapts count on entities deleted.
*
* @param count
* deleted entities count
*/
void updateCountOnEntitiesDeleted(final int count);
}

View File

@@ -12,7 +12,7 @@ import java.util.function.Consumer;
import org.eclipse.hawkbit.ui.common.event.BulkUploadEventPayload; import org.eclipse.hawkbit.ui.common.event.BulkUploadEventPayload;
import org.eclipse.hawkbit.ui.common.event.EventTopics; import org.eclipse.hawkbit.ui.common.event.EventTopics;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod; import org.vaadin.spring.events.annotation.EventBusListenerMethod;
@@ -32,7 +32,7 @@ public class BulkUploadChangedListener extends TopicEventListener {
* @param bulkUploadCallback * @param bulkUploadCallback
* Bulk upload callback event * Bulk upload callback event
*/ */
public BulkUploadChangedListener(final UIEventBus eventBus, public BulkUploadChangedListener(final EventBus eventBus,
final Consumer<BulkUploadEventPayload> bulkUploadCallback) { final Consumer<BulkUploadEventPayload> bulkUploadCallback) {
super(eventBus, EventTopics.BULK_UPLOAD_CHANGED); super(eventBus, EventTopics.BULK_UPLOAD_CHANGED);

View File

@@ -14,15 +14,18 @@ import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.eclipse.hawkbit.ui.common.ViewNameAware;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload; import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload;
import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType; import org.eclipse.hawkbit.ui.common.event.EntityModifiedEventPayload.EntityModifiedEventType;
import org.eclipse.hawkbit.ui.common.event.EventTopics; import org.eclipse.hawkbit.ui.common.event.EventTopics;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod; import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.navigator.View;
import com.vaadin.ui.UI; import com.vaadin.ui.UI;
/** /**
@@ -31,7 +34,7 @@ import com.vaadin.ui.UI;
* @param <T> * @param <T>
* Generic typ of ProxyIdentifiableEntity * Generic typ of ProxyIdentifiableEntity
*/ */
public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends TopicEventListener { public final class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends ViewAwareListener {
private final Class<T> entityType; private final Class<T> entityType;
private final Class<? extends ProxyIdentifiableEntity> parentEntityType; private final Class<? extends ProxyIdentifiableEntity> parentEntityType;
private final Supplier<Optional<Long>> parentEntityIdProvider; private final Supplier<Optional<Long>> parentEntityIdProvider;
@@ -48,14 +51,16 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
* Identifiable entity * Identifiable entity
* @param parentEntityIdProvider * @param parentEntityIdProvider
* Parent entity id provider * Parent entity id provider
* @param viewAware
* View aware
* @param entityModifiedAwareSupports * @param entityModifiedAwareSupports
* List of entity modified aware support * List of entity modified aware support
*/ */
public EntityModifiedListener(final UIEventBus eventBus, final Class<T> entityType, private EntityModifiedListener(final UIEventBus eventBus, final Class<T> entityType,
final Class<? extends ProxyIdentifiableEntity> parentEntityType, final Class<? extends ProxyIdentifiableEntity> parentEntityType,
final Supplier<Optional<Long>> parentEntityIdProvider, final Supplier<Optional<Long>> parentEntityIdProvider, final EventViewAware viewAware,
final List<EntityModifiedAwareSupport> entityModifiedAwareSupports) { final List<EntityModifiedAwareSupport> entityModifiedAwareSupports) {
super(eventBus, EventTopics.ENTITY_MODIFIED); super(eventBus, EventTopics.ENTITY_MODIFIED, viewAware);
this.entityType = entityType; this.entityType = entityType;
this.parentEntityType = parentEntityType; this.parentEntityType = parentEntityType;
@@ -65,7 +70,7 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
private void onEntityModifiedEvent(final EntityModifiedEventPayload eventPayload) { private void onEntityModifiedEvent(final EntityModifiedEventPayload eventPayload) {
if (!suitableEntityType(eventPayload.getEntityType()) if (!suitableView() || !suitableEntityType(eventPayload.getEntityType())
|| !suitableParentEntity(eventPayload.getParentType(), eventPayload.getParentId())) { || !suitableParentEntity(eventPayload.getParentType(), eventPayload.getParentId())) {
return; return;
} }
@@ -90,6 +95,24 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
} }
} }
private boolean suitableView() {
// if view is not explicitly defined allow events from all views
if (getView() == null) {
return true;
}
return getView().matchByViewName(getCurrentViewName());
}
private String getCurrentViewName() {
final View currentView = UI.getCurrent().getNavigator().getCurrentView();
if (currentView instanceof ViewNameAware) {
return ((ViewNameAware) currentView).getViewName();
}
return "";
}
private boolean suitableEntityType(final Class<? extends ProxyIdentifiableEntity> type) { private boolean suitableEntityType(final Class<? extends ProxyIdentifiableEntity> type) {
return entityType != null && entityType.equals(type); return entityType != null && entityType.equals(type);
} }
@@ -161,6 +184,7 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
private final Class<T> entityType; private final Class<T> entityType;
private Class<? extends ProxyIdentifiableEntity> parentEntityType; private Class<? extends ProxyIdentifiableEntity> parentEntityType;
private Supplier<Optional<Long>> parentEntityIdProvider; private Supplier<Optional<Long>> parentEntityIdProvider;
private EventViewAware viewAware;
private List<EntityModifiedAwareSupport> entityModifiedAwareSupports; private List<EntityModifiedAwareSupport> entityModifiedAwareSupports;
/** /**
@@ -202,6 +226,18 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
return this; return this;
} }
/**
* Set View aware
*
* @param viewAware
* View aware
* @return builder
*/
public Builder<T> viewAware(final EventViewAware viewAware) {
this.viewAware = viewAware;
return this;
}
/** /**
* Build entity modified support for layout * Build entity modified support for layout
* *
@@ -220,7 +256,7 @@ public class EntityModifiedListener<T extends ProxyIdentifiableEntity> extends T
*/ */
public EntityModifiedListener<T> build() { public EntityModifiedListener<T> build() {
return new EntityModifiedListener<>(eventBus, entityType, parentEntityType, parentEntityIdProvider, return new EntityModifiedListener<>(eventBus, entityType, parentEntityType, parentEntityIdProvider,
entityModifiedAwareSupports); viewAware, entityModifiedAwareSupports);
} }
} }
} }

View File

@@ -27,6 +27,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
public class FilterChangedListener<T extends ProxyIdentifiableEntity> extends ViewAwareListener { public class FilterChangedListener<T extends ProxyIdentifiableEntity> extends ViewAwareListener {
private final Class<T> entityType; private final Class<T> entityType;
private final FilterSupport<T, ?> filterSupport; private final FilterSupport<T, ?> filterSupport;
private final Runnable updateFilterCountInfo;
/** /**
* Constructor for FilterChangedListener * Constructor for FilterChangedListener
@@ -42,10 +43,30 @@ public class FilterChangedListener<T extends ProxyIdentifiableEntity> extends Vi
*/ */
public FilterChangedListener(final UIEventBus eventBus, final Class<T> entityType, final EventViewAware viewAware, public FilterChangedListener(final UIEventBus eventBus, final Class<T> entityType, final EventViewAware viewAware,
final FilterSupport<T, ?> filterSupport) { final FilterSupport<T, ?> filterSupport) {
this(eventBus, entityType, viewAware, filterSupport, null);
}
/**
* Constructor for FilterChangedListener
*
* @param eventBus
* UIEventBus
* @param entityType
* Generic type entity
* @param viewAware
* EventViewAware
* @param filterSupport
* Generic type filter support
* @param updateFilterCountInfo
* Callback to update entities count info on filter change
*/
public FilterChangedListener(final UIEventBus eventBus, final Class<T> entityType, final EventViewAware viewAware,
final FilterSupport<T, ?> filterSupport, final Runnable updateFilterCountInfo) {
super(eventBus, EventTopics.FILTER_CHANGED, viewAware); super(eventBus, EventTopics.FILTER_CHANGED, viewAware);
this.entityType = entityType; this.entityType = entityType;
this.filterSupport = filterSupport; this.filterSupport = filterSupport;
this.updateFilterCountInfo = updateFilterCountInfo;
} }
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
@@ -58,6 +79,9 @@ public class FilterChangedListener<T extends ProxyIdentifiableEntity> extends Vi
if (filterSupport.isFilterTypeSupported(filterType)) { if (filterSupport.isFilterTypeSupported(filterType)) {
filterSupport.updateFilter(filterType, eventPayload.getFilterValue()); filterSupport.updateFilter(filterType, eventPayload.getFilterValue());
if (updateFilterCountInfo != null) {
updateFilterCountInfo.run();
}
} }
} }

View File

@@ -31,7 +31,7 @@ public abstract class LayoutViewAwareListener extends TopicEventListener {
* @param layoutViewAware * @param layoutViewAware
* EventLayoutViewAware * EventLayoutViewAware
*/ */
public LayoutViewAwareListener(final UIEventBus eventBus, final String topic, protected LayoutViewAwareListener(final UIEventBus eventBus, final String topic,
final EventLayoutViewAware layoutViewAware) { final EventLayoutViewAware layoutViewAware) {
super(eventBus, topic); super(eventBus, topic);
@@ -48,7 +48,7 @@ public abstract class LayoutViewAwareListener extends TopicEventListener {
* @param layoutViewAware * @param layoutViewAware
* EventLayoutViewAware * EventLayoutViewAware
*/ */
public LayoutViewAwareListener(final UIEventBus eventBus, final Collection<String> topics, protected LayoutViewAwareListener(final UIEventBus eventBus, final Collection<String> topics,
final EventLayoutViewAware layoutViewAware) { final EventLayoutViewAware layoutViewAware) {
super(eventBus, topics); super(eventBus, topics);

View File

@@ -26,6 +26,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
public class PinningChangedListener<F> extends TopicEventListener { public class PinningChangedListener<F> extends TopicEventListener {
private final Class<? extends ProxyIdentifiableEntity> entityType; private final Class<? extends ProxyIdentifiableEntity> entityType;
private final PinSupport<? extends ProxyIdentifiableEntity, F> pinSupport; private final PinSupport<? extends ProxyIdentifiableEntity, F> pinSupport;
private final Runnable updatePinCountInfo;
/** /**
* Constructor for PinningChangedListener * Constructor for PinningChangedListener
@@ -39,10 +40,28 @@ public class PinningChangedListener<F> extends TopicEventListener {
*/ */
public PinningChangedListener(final UIEventBus eventBus, final Class<? extends ProxyIdentifiableEntity> entityType, public PinningChangedListener(final UIEventBus eventBus, final Class<? extends ProxyIdentifiableEntity> entityType,
final PinSupport<? extends ProxyIdentifiableEntity, F> pinSupport) { final PinSupport<? extends ProxyIdentifiableEntity, F> pinSupport) {
this(eventBus, entityType, pinSupport, null);
}
/**
* Constructor for PinningChangedListener
*
* @param eventBus
* UIEventBus
* @param entityType
* Identifiable Entity type
* @param pinSupport
* Pin support
* @param updatePinCountInfo
* Callback to update pinned entities count info on pin change
*/
public PinningChangedListener(final UIEventBus eventBus, final Class<? extends ProxyIdentifiableEntity> entityType,
final PinSupport<? extends ProxyIdentifiableEntity, F> pinSupport, final Runnable updatePinCountInfo) {
super(eventBus, EventTopics.PINNING_CHANGED); super(eventBus, EventTopics.PINNING_CHANGED);
this.entityType = entityType; this.entityType = entityType;
this.pinSupport = pinSupport; this.pinSupport = pinSupport;
this.updatePinCountInfo = updatePinCountInfo;
} }
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
@@ -56,6 +75,10 @@ public class PinningChangedListener<F> extends TopicEventListener {
} else { } else {
pinSupport.updatePinFilter(null); pinSupport.updatePinFilter(null);
} }
if (updatePinCountInfo != null) {
updatePinCountInfo.run();
}
} }
private boolean suitableEntityType(final Class<? extends ProxyIdentifiableEntity> type) { private boolean suitableEntityType(final Class<? extends ProxyIdentifiableEntity> type) {

View File

@@ -11,31 +11,33 @@ package org.eclipse.hawkbit.ui.common.layout.listener;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus;
/** /**
* Abstract class for event listener * Abstract class for event listener
*/ */
public abstract class TopicEventListener { public abstract class TopicEventListener {
private final UIEventBus eventBus; private final EventBus eventBus;
private final Collection<String> topics; private final Collection<String> topics;
private boolean subscribed; private boolean subscribed;
protected TopicEventListener(final UIEventBus eventBus, final String topic) { protected TopicEventListener(final EventBus eventBus, final String topic) {
this(eventBus, Collections.singleton(topic)); this(eventBus, Collections.singleton(topic));
} }
protected TopicEventListener(final UIEventBus eventBus, final Collection<String> topics) { protected TopicEventListener(final EventBus eventBus, final Collection<String> topics) {
this.eventBus = eventBus; this.eventBus = eventBus;
this.topics = topics; this.topics = topics;
subscribe();
} }
/** /**
* Subscribe the event * Subscribe the event
*/ */
public void subscribe() { public void subscribe() {
if (subscribed) {
return;
}
topics.forEach(topic -> eventBus.subscribe(this, topic)); topics.forEach(topic -> eventBus.subscribe(this, topic));
subscribed = true; subscribed = true;
} }
@@ -44,6 +46,10 @@ public abstract class TopicEventListener {
* Unsubscribe the event * Unsubscribe the event
*/ */
public void unsubscribe() { public void unsubscribe() {
if (!subscribed) {
return;
}
eventBus.unsubscribe(this); eventBus.unsubscribe(this);
subscribed = false; subscribed = false;
} }
@@ -55,7 +61,7 @@ public abstract class TopicEventListener {
return subscribed; return subscribed;
} }
protected UIEventBus getEventBus() { protected EventBus getEventBus() {
return eventBus; return eventBus;
} }
} }

View File

@@ -30,7 +30,7 @@ public abstract class ViewAwareListener extends TopicEventListener {
* @param viewAware * @param viewAware
* EventViewAware * EventViewAware
*/ */
public ViewAwareListener(final UIEventBus eventBus, final String topic, final EventViewAware viewAware) { protected ViewAwareListener(final UIEventBus eventBus, final String topic, final EventViewAware viewAware) {
super(eventBus, topic); super(eventBus, topic);
this.viewAware = viewAware; this.viewAware = viewAware;
@@ -46,7 +46,7 @@ public abstract class ViewAwareListener extends TopicEventListener {
* @param viewAware * @param viewAware
* EventViewAware * EventViewAware
*/ */
public ViewAwareListener(final UIEventBus eventBus, final Collection<String> topics, protected ViewAwareListener(final UIEventBus eventBus, final Collection<String> topics,
final EventViewAware viewAware) { final EventViewAware viewAware) {
super(eventBus, topics); super(eventBus, topics);
@@ -64,6 +64,6 @@ public abstract class ViewAwareListener extends TopicEventListener {
* @return View * @return View
*/ */
public EventView getView() { public EventView getView() {
return viewAware.getView(); return viewAware != null ? viewAware.getView() : null;
} }
} }

View File

@@ -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.common.layout.listener.support;
import java.util.Collection;
import org.eclipse.hawkbit.ui.common.layout.CountAwareComponent;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport;
/**
* Support for entity modified adapting entities count.
*/
public class EntityModifiedCountAwareSupport implements EntityModifiedAwareSupport {
private final CountAwareComponent countAwareComponent;
/**
* Constructor.
*
* @param countAwareComponent
* Component that adapts its count
*/
public EntityModifiedCountAwareSupport(final CountAwareComponent countAwareComponent) {
this.countAwareComponent = countAwareComponent;
}
/**
* Static method for constructing EntityModifiedCountSupport
*
* @param countAwareComponent
* Component that adapts its count
* @return instance of {@link EntityModifiedCountAwareSupport}
*/
public static EntityModifiedCountAwareSupport of(final CountAwareComponent countAwareComponent) {
return new EntityModifiedCountAwareSupport(countAwareComponent);
}
@Override
public void onEntitiesAdded(final Collection<Long> entityIds) {
countAwareComponent.updateCountOnEntitiesAdded(entityIds.size());
}
@Override
public void onEntitiesUpdated(final Collection<Long> entityIds) {
countAwareComponent.updateCountOnEntitiesUpdated();
}
@Override
public void onEntitiesDeleted(final Collection<Long> entityIds) {
countAwareComponent.updateCountOnEntitiesDeleted(entityIds.size());
}
}

View File

@@ -45,7 +45,7 @@ public abstract class AbstractSoftwareModuleGridLayout extends AbstractGridCompo
* @param eventView * @param eventView
* EventView * EventView
*/ */
public AbstractSoftwareModuleGridLayout(final CommonUiDependencies uiDependencies, protected AbstractSoftwareModuleGridLayout(final CommonUiDependencies uiDependencies,
final SoftwareModuleManagement softwareModuleManagement, final SoftwareModuleManagement softwareModuleManagement,
final SoftwareModuleTypeManagement softwareModuleTypeManagement, final EventView eventView) { final SoftwareModuleTypeManagement softwareModuleTypeManagement, final EventView eventView) {
@@ -117,22 +117,28 @@ public abstract class AbstractSoftwareModuleGridLayout extends AbstractGridCompo
showDetailsLayout(); showDetailsLayout();
} }
/** protected void addEventListener(final TopicEventListener listener) {
* Is called when view is shown to the user listeners.add(listener);
*/ }
@Override
public void restoreState() { public void restoreState() {
getSoftwareModuleGridHeader().restoreState(); getSoftwareModuleGridHeader().restoreState();
getSoftwareModuleGrid().restoreState(); getSoftwareModuleGrid().restoreState();
} }
protected void addEventListener(final TopicEventListener listener) { @Override
listeners.add(listener); public void onViewEnter() {
getSoftwareModuleGrid().getSelectionSupport().reselectCurrentEntity();
} }
/** @Override
* Unsubscribe the event listeners. public void subscribeListeners() {
*/ listeners.forEach(TopicEventListener::subscribe);
public void unsubscribeListener() { }
@Override
public void unsubscribeListeners() {
listeners.forEach(TopicEventListener::unsubscribe); listeners.forEach(TopicEventListener::unsubscribe);
} }

View File

@@ -8,12 +8,10 @@
*/ */
package org.eclipse.hawkbit.ui.distributions; package org.eclipse.hawkbit.ui.distributions;
import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
@@ -28,6 +26,7 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
@@ -47,14 +46,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.annotations.JavaScript; import com.vaadin.annotations.JavaScript;
import com.vaadin.navigator.View;
import com.vaadin.server.Page; import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeEvent;
import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.server.Page.BrowserWindowResizeListener;
import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;
/** /**
* Manage distributions and distributions type view. * Manage distributions and distributions type view.
@@ -62,7 +59,7 @@ import com.vaadin.ui.VerticalLayout;
@UIScope @UIScope
@SpringView(name = DistributionsView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = DistributionsView.VIEW_NAME, ui = AbstractHawkbitUI.class)
@JavaScript("vaadin://js/dynamicStylesheet.js") @JavaScript("vaadin://js/dynamicStylesheet.js")
public class DistributionsView extends VerticalLayout implements View, BrowserWindowResizeListener { public class DistributionsView extends AbstractEventListenersAwareView implements BrowserWindowResizeListener {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "distributions"; public static final String VIEW_NAME = "distributions";
@@ -94,8 +91,8 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
this.permChecker = permChecker; this.permChecker = permChecker;
this.manageDistUIState = manageDistUIState; this.manageDistUIState = manageDistUIState;
final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, uiNotification, final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus,
permChecker); uiNotification, permChecker);
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
this.dsTypeFilterLayout = new DSTypeFilterLayout(uiDependencies, softwareModuleTypeManagement, this.dsTypeFilterLayout = new DSTypeFilterLayout(uiDependencies, softwareModuleTypeManagement,
@@ -113,6 +110,9 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
this.distSMTypeFilterLayout = new DistSMTypeFilterLayout(uiDependencies, softwareModuleTypeManagement, this.distSMTypeFilterLayout = new DistSMTypeFilterLayout(uiDependencies, softwareModuleTypeManagement,
manageDistUIState.getSmTypeFilterLayoutUiState()); manageDistUIState.getSmTypeFilterLayoutUiState());
addEventAwareLayouts(Arrays.asList(dsTypeFilterLayout, distributionSetGridLayout, swModuleGridLayout,
distSMTypeFilterLayout));
final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class);
layoutVisibilityHandlers.put(EventLayout.DS_TYPE_FILTER, layoutVisibilityHandlers.put(EventLayout.DS_TYPE_FILTER,
new VisibilityHandler(this::showDsTypeLayout, this::hideDsTypeLayout)); new VisibilityHandler(this::showDsTypeLayout, this::hideDsTypeLayout));
@@ -138,16 +138,16 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
} }
} }
@PostConstruct @Override
void init() { protected void init() {
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
buildLayout(); super.init();
restoreState();
Page.getCurrent().addBrowserWindowResizeListener(this); Page.getCurrent().addBrowserWindowResizeListener(this);
} }
} }
private void buildLayout() { @Override
protected void buildLayout() {
setMargin(false); setMargin(false);
setSpacing(false); setSpacing(false);
setSizeFull(); setSizeFull();
@@ -175,24 +175,33 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
mainLayout.setExpandRatio(distSMTypeFilterLayout, 0F); mainLayout.setExpandRatio(distSMTypeFilterLayout, 0F);
} }
private void restoreState() { @Override
protected void restoreState() {
if (permChecker.hasReadRepositoryPermission()) {
restoreDsWidgetsState();
restoreSmWidgetsState();
}
super.restoreState();
}
private void restoreDsWidgetsState() {
if (manageDistUIState.getDsTypeFilterLayoutUiState().isHidden() if (manageDistUIState.getDsTypeFilterLayoutUiState().isHidden()
|| manageDistUIState.getSwModuleGridLayoutUiState().isMaximized()) { || manageDistUIState.getSwModuleGridLayoutUiState().isMaximized()) {
hideDsTypeLayout(); hideDsTypeLayout();
} else { } else {
showDsTypeLayout(); showDsTypeLayout();
} }
dsTypeFilterLayout.restoreState();
if (manageDistUIState.getDistributionSetGridLayoutUiState().isMaximized()) { if (manageDistUIState.getDistributionSetGridLayoutUiState().isMaximized()) {
maximizeDsGridLayout(); maximizeDsGridLayout();
} }
distributionSetGridLayout.restoreState(); }
private void restoreSmWidgetsState() {
if (manageDistUIState.getSwModuleGridLayoutUiState().isMaximized()) { if (manageDistUIState.getSwModuleGridLayoutUiState().isMaximized()) {
maximizeSmGridLayout(); maximizeSmGridLayout();
} }
swModuleGridLayout.restoreState();
if (manageDistUIState.getSmTypeFilterLayoutUiState().isHidden() if (manageDistUIState.getSmTypeFilterLayoutUiState().isHidden()
|| manageDistUIState.getDistributionSetGridLayoutUiState().isMaximized()) { || manageDistUIState.getDistributionSetGridLayoutUiState().isMaximized()) {
@@ -200,7 +209,6 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
} else { } else {
showSmTypeLayout(); showSmTypeLayout();
} }
distSMTypeFilterLayout.restoreState();
} }
private void showDsTypeLayout() { private void showDsTypeLayout() {
@@ -300,16 +308,28 @@ public class DistributionsView extends VerticalLayout implements View, BrowserWi
} }
} }
@PreDestroy @Override
void destroy() { public String getViewName() {
return DistributionsView.VIEW_NAME;
}
@Override
protected void subscribeListeners() {
if (permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.subscribe();
layoutResizeListener.subscribe();
}
super.subscribeListeners();
}
@Override
protected void unsubscribeListeners() {
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.unsubscribe(); layoutVisibilityListener.unsubscribe();
layoutResizeListener.unsubscribe(); layoutResizeListener.unsubscribe();
dsTypeFilterLayout.unsubscribeListener();
distributionSetGridLayout.unsubscribeListener();
swModuleGridLayout.unsubscribeListener();
distSMTypeFilterLayout.unsubscribeListener();
} }
super.unsubscribeListeners();
} }
} }

View File

@@ -109,4 +109,9 @@ public class DSTypeFilterButtons extends AbstractTypeFilterButtons {
protected Window getUpdateWindow(final ProxyType clickedFilter) { protected Window getUpdateWindow(final ProxyType clickedFilter) {
return dsTypeWindowBuilder.getWindowForUpdate(clickedFilter); return dsTypeWindowBuilder.getWindowForUpdate(clickedFilter);
} }
@Override
protected boolean typeExists(final Long typeId) {
return distributionSetTypeManagement.exists(typeId);
}
} }

View File

@@ -65,20 +65,22 @@ public class DSTypeFilterLayout extends AbstractFilterLayout {
final DistributionSetTypeManagement distributionSetTypeManagement, final DistributionSetTypeManagement distributionSetTypeManagement,
final DistributionSetManagement distributionSetManagement, final SystemManagement systemManagement, final DistributionSetManagement distributionSetManagement, final SystemManagement systemManagement,
final TypeFilterLayoutUiState dSTypeFilterLayoutUiState) { final TypeFilterLayoutUiState dSTypeFilterLayoutUiState) {
final DsTypeWindowBuilder dsTypeWindowBuilder = new DsTypeWindowBuilder(uiDependencies, distributionSetTypeManagement, final DsTypeWindowBuilder dsTypeWindowBuilder = new DsTypeWindowBuilder(uiDependencies,
distributionSetManagement, softwareModuleTypeManagement); distributionSetTypeManagement, distributionSetManagement, softwareModuleTypeManagement);
this.dsTypeFilterHeader = new DSTypeFilterHeader(uiDependencies, dsTypeWindowBuilder, dSTypeFilterLayoutUiState); this.dsTypeFilterHeader = new DSTypeFilterHeader(uiDependencies, dsTypeWindowBuilder,
this.dSTypeFilterButtons = new DSTypeFilterButtons(uiDependencies, distributionSetTypeManagement, systemManagement, dSTypeFilterLayoutUiState);
dsTypeWindowBuilder, dSTypeFilterLayoutUiState); this.dSTypeFilterButtons = new DSTypeFilterButtons(uiDependencies, distributionSetTypeManagement,
systemManagement, dsTypeWindowBuilder, dSTypeFilterLayoutUiState);
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.DS_TYPE_FILTER,
EventView.DISTRIBUTIONS);
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(), this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(),
new EventLayoutViewAware(EventLayout.DS_TYPE_FILTER, EventView.DISTRIBUTIONS), layoutViewAware, dSTypeFilterButtons::hideActionColumns, dSTypeFilterButtons::showEditColumn,
dSTypeFilterButtons::hideActionColumns, dSTypeFilterButtons::showEditColumn,
dSTypeFilterButtons::showDeleteColumn); dSTypeFilterButtons::showDeleteColumn);
this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyType.class) this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
.entityModifiedAwareSupports(getEntityModifiedAwareSupports()) ProxyType.class).parentEntityType(ProxyDistributionSet.class).viewAware(layoutViewAware)
.parentEntityType(ProxyDistributionSet.class).build(); .entityModifiedAwareSupports(getEntityModifiedAwareSupports()).build();
buildLayout(); buildLayout();
} }
@@ -98,17 +100,24 @@ public class DSTypeFilterLayout extends AbstractFilterLayout {
return wrapFilterContent(dSTypeFilterButtons); return wrapFilterContent(dSTypeFilterButtons);
} }
/** @Override
* Restore state of distribution set filter button
*/
public void restoreState() { public void restoreState() {
dSTypeFilterButtons.restoreState(); dSTypeFilterButtons.restoreState();
} }
/** @Override
* Unsubscribe event listener public void onViewEnter() {
*/ dSTypeFilterButtons.reevaluateFilter();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
gridActionsVisibilityListener.subscribe();
entityModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
gridActionsVisibilityListener.unsubscribe(); gridActionsVisibilityListener.unsubscribe();
entityModifiedListener.unsubscribe(); entityModifiedListener.unsubscribe();
} }

View File

@@ -32,7 +32,6 @@ import org.eclipse.hawkbit.ui.common.distributionset.DistributionSetGridHeader;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport;
@@ -110,25 +109,25 @@ public class DistributionSetGridLayout extends AbstractDistributionSetGridLayout
this.distributionSetDetailsHeader = new DistributionSetDetailsHeader(uiDependencies, getDsWindowBuilder(), this.distributionSetDetailsHeader = new DistributionSetDetailsHeader(uiDependencies, getDsWindowBuilder(),
getDsMetaDataWindowBuilder()); getDsMetaDataWindowBuilder());
this.distributionSetDetails = new DistributionSetDetails(uiDependencies, distributionSetManagement, smManagement, this.distributionSetDetails = new DistributionSetDetails(uiDependencies, distributionSetManagement,
distributionSetTypeManagement, distributionSetTagManagement, configManagement, systemSecurityContext, smManagement, distributionSetTypeManagement, distributionSetTagManagement, configManagement,
getDsMetaDataWindowBuilder()); systemSecurityContext, getDsMetaDataWindowBuilder());
this.distributionSetDetails.setUnassignSmAllowed(true); this.distributionSetDetails.setUnassignSmAllowed(true);
this.distributionSetDetails.addTfqDetailsGrid(targetFilterQueryManagement); this.distributionSetDetails.addTfqDetailsGrid(targetFilterQueryManagement);
this.distributionSetDetails.buildDetails(); this.distributionSetDetails.buildDetails();
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.DS_LIST, getEventView());
addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyDistributionSet.class, addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyDistributionSet.class,
new EventViewAware(getEventView()), distributionSetGrid.getFilterSupport())); layoutViewAware, distributionSetGrid.getFilterSupport()));
addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.DS_LIST, getEventView()), getDsEntityAwareComponents())); getDsEntityAwareComponents()));
addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.DS_LIST, getEventView()),
distributionSetGrid.getSelectionSupport())); distributionSetGrid.getSelectionSupport()));
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyDistributionSet.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyDistributionSet.class)
.entityModifiedAwareSupports(getDsModifiedAwareSupports()).build()); .viewAware(layoutViewAware).entityModifiedAwareSupports(getDsModifiedAwareSupports()).build());
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).parentEntityType(ProxyDistributionSet.class) .parentEntityType(ProxyDistributionSet.class).viewAware(layoutViewAware)
.build()); .entityModifiedAwareSupports(getTagModifiedAwareSupports()).build());
buildLayout(distributionSetGridHeader, distributionSetGrid, distributionSetDetailsHeader, buildLayout(distributionSetGridHeader, distributionSetGrid, distributionSetDetailsHeader,
distributionSetDetails); distributionSetDetails);

View File

@@ -25,7 +25,6 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsHeader;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport;
@@ -65,7 +64,8 @@ public class SwModuleGridLayout extends AbstractSoftwareModuleGridLayout {
* @param swModuleGridLayoutUiState * @param swModuleGridLayoutUiState
* GridLayoutUiState * GridLayoutUiState
*/ */
public SwModuleGridLayout(final CommonUiDependencies uiDependencies, final SoftwareModuleManagement softwareModuleManagement, public SwModuleGridLayout(final CommonUiDependencies uiDependencies,
final SoftwareModuleManagement softwareModuleManagement,
final SoftwareModuleTypeManagement softwareModuleTypeManagement, final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final ArtifactManagement artifactManagement, final TypeFilterLayoutUiState smTypeFilterLayoutUiState, final ArtifactManagement artifactManagement, final TypeFilterLayoutUiState smTypeFilterLayoutUiState,
final GridLayoutUiState swModuleGridLayoutUiState) { final GridLayoutUiState swModuleGridLayoutUiState) {
@@ -88,16 +88,18 @@ public class SwModuleGridLayout extends AbstractSoftwareModuleGridLayout {
softwareModuleTypeManagement, getSmMetaDataWindowBuilder()); softwareModuleTypeManagement, getSmMetaDataWindowBuilder());
this.swModuleDetails.buildDetails(); this.swModuleDetails.buildDetails();
final EventLayoutViewAware smLayoutViewAware = new EventLayoutViewAware(EventLayout.SM_LIST, getEventView());
final EventLayoutViewAware dsLayoutViewAware = new EventLayoutViewAware(EventLayout.DS_LIST, getEventView());
addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxySoftwareModule.class, addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxySoftwareModule.class,
new EventViewAware(getEventView()), swModuleGrid.getFilterSupport())); smLayoutViewAware, swModuleGrid.getFilterSupport()));
addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), dsLayoutViewAware,
new EventLayoutViewAware(EventLayout.DS_LIST, getEventView()), getMasterDsAwareComponents())); getMasterDsAwareComponents()));
addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), smLayoutViewAware,
new EventLayoutViewAware(EventLayout.SM_LIST, getEventView()), getMasterSmAwareComponents())); getMasterSmAwareComponents()));
addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), addEventListener(new SelectGridEntityListener<>(uiDependencies.getEventBus(), smLayoutViewAware,
new EventLayoutViewAware(EventLayout.SM_LIST, getEventView()), swModuleGrid.getSelectionSupport())); swModuleGrid.getSelectionSupport()));
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxySoftwareModule.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxySoftwareModule.class)
.entityModifiedAwareSupports(getSmModifiedAwareSupports()).build()); .viewAware(smLayoutViewAware).entityModifiedAwareSupports(getSmModifiedAwareSupports()).build());
buildLayout(swModuleGridHeader, swModuleGrid, softwareModuleDetailsHeader, swModuleDetails); buildLayout(swModuleGridHeader, swModuleGrid, softwareModuleDetailsHeader, swModuleDetails);
} }

View File

@@ -0,0 +1,38 @@
/**
* 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.error.extractors;
import java.util.Optional;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.ui.error.UiErrorDetails;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
/**
* UI error details extractor for {@link EntityNotFoundException}.
*/
public class EntityNotFoundErrorExtractor extends AbstractSingleUiErrorDetailsExtractor {
private final VaadinMessageSource i18n;
/**
* Constructor for EntityNotFoundErrorExtractor.
*
* @param i18n
* Message source used for localization
*/
public EntityNotFoundErrorExtractor(final VaadinMessageSource i18n) {
this.i18n = i18n;
}
@Override
protected Optional<UiErrorDetails> findDetails(final Throwable error) {
return findExceptionOf(error, EntityNotFoundException.class)
.map(ex -> UiErrorDetails.create(i18n.getMessage("caption.entity.missing.error"), ex.getMessage()));
}
}

View File

@@ -8,12 +8,10 @@
*/ */
package org.eclipse.hawkbit.ui.filtermanagement; package org.eclipse.hawkbit.ui.filtermanagement;
import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
@@ -22,6 +20,7 @@ import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier; import org.eclipse.hawkbit.ui.common.data.suppliers.TargetFilterStateDataSupplier;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
@@ -36,18 +35,16 @@ import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.navigator.View;
import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.Alignment; import com.vaadin.ui.Alignment;
import com.vaadin.ui.VerticalLayout;
/** /**
* View for custom target filter management. * View for custom target filter management.
*/ */
@UIScope @UIScope
@SpringView(name = FilterManagementView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = FilterManagementView.VIEW_NAME, ui = AbstractHawkbitUI.class)
public class FilterManagementView extends VerticalLayout implements View { public class FilterManagementView extends AbstractEventListenersAwareView {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "targetFilters"; public static final String VIEW_NAME = "targetFilters";
@@ -78,6 +75,8 @@ public class FilterManagementView extends VerticalLayout implements View {
rsqlValidationOracle, targetFilterQueryManagement, targetFilterStateDataSupplier, rsqlValidationOracle, targetFilterQueryManagement, targetFilterStateDataSupplier,
filterManagementUIState.getDetailsLayoutUiState()); filterManagementUIState.getDetailsLayoutUiState());
addEventAwareLayouts(Arrays.asList(targetFilterGridLayout, targetFilterDetailsLayout));
final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class);
layoutVisibilityHandlers.put(EventLayout.TARGET_FILTER_QUERY_LIST, layoutVisibilityHandlers.put(EventLayout.TARGET_FILTER_QUERY_LIST,
new VisibilityHandler(this::showTfqListLayout, this::showTfqFormLayout)); new VisibilityHandler(this::showTfqListLayout, this::showTfqFormLayout));
@@ -87,13 +86,8 @@ public class FilterManagementView extends VerticalLayout implements View {
new EventViewAware(EventView.TARGET_FILTER), layoutVisibilityHandlers); new EventViewAware(EventView.TARGET_FILTER), layoutVisibilityHandlers);
} }
@PostConstruct @Override
void init() { protected void buildLayout() {
buildLayout();
restoreState();
}
private void buildLayout() {
setMargin(false); setMargin(false);
setSpacing(false); setSpacing(false);
setSizeFull(); setSizeFull();
@@ -120,21 +114,33 @@ public class FilterManagementView extends VerticalLayout implements View {
targetFilterDetailsLayout.setVisible(true); targetFilterDetailsLayout.setVisible(true);
} }
private void restoreState() { @Override
protected void restoreState() {
if (FilterView.FILTERS == filterManagementUIState.getCurrentView()) { if (FilterView.FILTERS == filterManagementUIState.getCurrentView()) {
showTfqListLayout(); showTfqListLayout();
} else if (FilterView.DETAILS == filterManagementUIState.getCurrentView()) { } else if (FilterView.DETAILS == filterManagementUIState.getCurrentView()) {
showTfqFormLayout(); showTfqFormLayout();
} }
targetFilterDetailsLayout.restoreState();
targetFilterGridLayout.restoreState(); super.restoreState();
} }
@PreDestroy @Override
void destroy() { public String getViewName() {
return FilterManagementView.VIEW_NAME;
}
@Override
protected void subscribeListeners() {
layoutVisibilityListener.subscribe();
super.subscribeListeners();
}
@Override
protected void unsubscribeListeners() {
layoutVisibilityListener.unsubscribe(); layoutVisibilityListener.unsubscribe();
targetFilterGridLayout.unsubscribeListener(); super.unsubscribeListeners();
targetFilterDetailsLayout.unsubscribeListener();
} }
} }

View File

@@ -66,13 +66,15 @@ public class TargetFilterDetailsLayout extends AbstractGridComponentLayout {
initGridDataUpdatedListener(); initGridDataUpdatedListener();
final EventViewAware viewAware = new EventViewAware(EventView.TARGET_FILTER);
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.TARGET_FILTER_QUERY_FORM,
EventView.TARGET_FILTER);
this.showFilterQueryFormListener = new ShowEntityFormLayoutListener<>(uiDependencies.getEventBus(), this.showFilterQueryFormListener = new ShowEntityFormLayoutListener<>(uiDependencies.getEventBus(),
ProxyTargetFilterQuery.class, ProxyTargetFilterQuery.class, layoutViewAware, targetFilterDetailsGridHeader::showAddFilterLayout,
new EventLayoutViewAware(EventLayout.TARGET_FILTER_QUERY_FORM, EventView.TARGET_FILTER),
targetFilterDetailsGridHeader::showAddFilterLayout,
targetFilterDetailsGridHeader::showEditFilterLayout); targetFilterDetailsGridHeader::showEditFilterLayout);
this.targetFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class, this.targetFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class,
new EventViewAware(EventView.TARGET_FILTER), targetFilterTargetGrid.getFilterSupport()); viewAware, targetFilterTargetGrid.getFilterSupport());
buildLayout(targetFilterDetailsGridHeader, targetFilterTargetGrid, targetFilterCountMessageLabel); buildLayout(targetFilterDetailsGridHeader, targetFilterTargetGrid, targetFilterCountMessageLabel);
} }
@@ -82,9 +84,7 @@ public class TargetFilterDetailsLayout extends AbstractGridComponentLayout {
.updateTotalFilteredTargetsCount(targetFilterTargetGrid.getDataSize())); .updateTotalFilteredTargetsCount(targetFilterTargetGrid.getDataSize()));
} }
/** @Override
* restore the saved state
*/
public void restoreState() { public void restoreState() {
targetFilterDetailsGridHeader.restoreState(); targetFilterDetailsGridHeader.restoreState();
if (targetFilterDetailsGridHeader.isFilterQueryValid()) { if (targetFilterDetailsGridHeader.isFilterQueryValid()) {
@@ -92,10 +92,14 @@ public class TargetFilterDetailsLayout extends AbstractGridComponentLayout {
} }
} }
/** @Override
* unsubscribe all listener public void subscribeListeners() {
*/ showFilterQueryFormListener.subscribe();
public void unsubscribeListener() { targetFilterListener.subscribe();
}
@Override
public void unsubscribeListeners() {
showFilterQueryFormListener.unsubscribe(); showFilterQueryFormListener.unsubscribe();
targetFilterListener.unsubscribe(); targetFilterListener.unsubscribe();
} }

View File

@@ -64,12 +64,12 @@ public class TargetFilterGridLayout extends AbstractGridComponentLayout {
this.targetFilterGrid = new TargetFilterGrid(uiDependencies, filterManagementUIState.getGridLayoutUiState(), this.targetFilterGrid = new TargetFilterGrid(uiDependencies, filterManagementUIState.getGridLayoutUiState(),
targetFilterQueryManagement, autoAssignmentWindowBuilder); targetFilterQueryManagement, autoAssignmentWindowBuilder);
final EventViewAware viewAware = new EventViewAware(EventView.TARGET_FILTER);
this.targetQueryFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), this.targetQueryFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(),
ProxyTargetFilterQuery.class, new EventViewAware(EventView.TARGET_FILTER), ProxyTargetFilterQuery.class, viewAware, targetFilterGrid.getFilterSupport());
targetFilterGrid.getFilterSupport());
this.filterQueryModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), this.filterQueryModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
ProxyTargetFilterQuery.class).entityModifiedAwareSupports(getFilterQueryModifiedAwareSupports()) ProxyTargetFilterQuery.class).viewAware(viewAware)
.build(); .entityModifiedAwareSupports(getFilterQueryModifiedAwareSupports()).build();
buildLayout(targetFilterGridHeader, targetFilterGrid); buildLayout(targetFilterGridHeader, targetFilterGrid);
} }
@@ -78,18 +78,20 @@ public class TargetFilterGridLayout extends AbstractGridComponentLayout {
return Collections.singletonList(EntityModifiedGridRefreshAwareSupport.of(targetFilterGrid::refreshAll)); return Collections.singletonList(EntityModifiedGridRefreshAwareSupport.of(targetFilterGrid::refreshAll));
} }
/** @Override
* restore the saved state
*/
public void restoreState() { public void restoreState() {
targetFilterGridHeader.restoreState(); targetFilterGridHeader.restoreState();
targetFilterGrid.restoreState(); targetFilterGrid.restoreState();
} }
/** @Override
* unsubscribe all listener public void subscribeListeners() {
*/ targetQueryFilterListener.subscribe();
public void unsubscribeListener() { filterQueryModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
targetQueryFilterListener.unsubscribe(); targetQueryFilterListener.unsubscribe();
filterQueryModifiedListener.unsubscribe(); filterQueryModifiedListener.unsubscribe();
} }

View File

@@ -8,13 +8,11 @@
*/ */
package org.eclipse.hawkbit.ui.management; package org.eclipse.hawkbit.ui.management;
import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
@@ -30,6 +28,7 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplier; import org.eclipse.hawkbit.ui.common.data.suppliers.TargetManagementStateDataSupplier;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
@@ -51,7 +50,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.navigator.View;
import com.vaadin.server.Page; import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeEvent;
import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.server.Page.BrowserWindowResizeListener;
@@ -59,14 +57,13 @@ import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Layout; import com.vaadin.ui.Layout;
import com.vaadin.ui.VerticalLayout;
/** /**
* Target status and deployment management view * Target status and deployment management view
*/ */
@UIScope @UIScope
@SpringView(name = DeploymentView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = DeploymentView.VIEW_NAME, ui = AbstractHawkbitUI.class)
public class DeploymentView extends VerticalLayout implements View, BrowserWindowResizeListener { public class DeploymentView extends AbstractEventListenersAwareView implements BrowserWindowResizeListener {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "deployment"; public static final String VIEW_NAME = "deployment";
@@ -120,6 +117,8 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
this.actionHistoryLayout = new ActionHistoryLayout(uiDependencies, deploymentManagement, this.actionHistoryLayout = new ActionHistoryLayout(uiDependencies, deploymentManagement,
managementUIState.getActionHistoryGridLayoutUiState()); managementUIState.getActionHistoryGridLayoutUiState());
addEventAwareLayouts(Arrays.asList(targetTagFilterLayout, targetGridLayout, actionHistoryLayout));
} else { } else {
this.targetTagFilterLayout = null; this.targetTagFilterLayout = null;
this.targetGridLayout = null; this.targetGridLayout = null;
@@ -136,6 +135,8 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
systemSecurityContext, uiProperties, managementUIState.getDistributionGridLayoutUiState(), systemSecurityContext, uiProperties, managementUIState.getDistributionGridLayoutUiState(),
managementUIState.getDistributionTagLayoutUiState(), managementUIState.getDistributionTagLayoutUiState(),
managementUIState.getTargetGridLayoutUiState()); managementUIState.getTargetGridLayoutUiState());
addEventAwareLayouts(Arrays.asList(distributionTagLayout, distributionGridLayout));
} else { } else {
this.distributionTagLayout = null; this.distributionTagLayout = null;
this.distributionGridLayout = null; this.distributionGridLayout = null;
@@ -165,16 +166,16 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
} }
} }
@PostConstruct @Override
void init() { protected void init() {
if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) { if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) {
buildLayout(); super.init();
restoreState();
Page.getCurrent().addBrowserWindowResizeListener(this); Page.getCurrent().addBrowserWindowResizeListener(this);
} }
} }
private void buildLayout() { @Override
protected void buildLayout() {
setMargin(false); setMargin(false);
setSpacing(false); setSpacing(false);
setSizeFull(); setSizeFull();
@@ -248,7 +249,8 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
mainLayout.setExpandRatio(actionHistoryLayout, 0.6F); mainLayout.setExpandRatio(actionHistoryLayout, 0.6F);
} }
private void restoreState() { @Override
protected void restoreState() {
if (permChecker.hasTargetReadPermission()) { if (permChecker.hasTargetReadPermission()) {
restoreTargetWidgetsState(); restoreTargetWidgetsState();
} }
@@ -256,6 +258,8 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
if (permChecker.hasReadRepositoryPermission()) { if (permChecker.hasReadRepositoryPermission()) {
restoreDsWidgetsState(); restoreDsWidgetsState();
} }
super.restoreState();
} }
private void restoreTargetWidgetsState() { private void restoreTargetWidgetsState() {
@@ -266,17 +270,14 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
} else { } else {
showTargetTagLayout(); showTargetTagLayout();
} }
targetTagFilterLayout.restoreState();
if (managementUIState.getTargetGridLayoutUiState().isMaximized()) { if (managementUIState.getTargetGridLayoutUiState().isMaximized()) {
maximizeTargetGridLayout(); maximizeTargetGridLayout();
} }
targetGridLayout.restoreState();
if (managementUIState.getActionHistoryGridLayoutUiState().isMaximized()) { if (managementUIState.getActionHistoryGridLayoutUiState().isMaximized()) {
maximizeActionHistoryGridLayout(); maximizeActionHistoryGridLayout();
} }
actionHistoryLayout.restoreState();
} }
private void restoreDsWidgetsState() { private void restoreDsWidgetsState() {
@@ -287,12 +288,10 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
} else { } else {
showDsTagLayout(); showDsTagLayout();
} }
distributionTagLayout.restoreState();
if (managementUIState.getDistributionGridLayoutUiState().isMaximized()) { if (managementUIState.getDistributionGridLayoutUiState().isMaximized()) {
maximizeDsGridLayout(); maximizeDsGridLayout();
} }
distributionGridLayout.restoreState();
} }
private void showTargetTagLayout() { private void showTargetTagLayout() {
@@ -459,22 +458,28 @@ public class DeploymentView extends VerticalLayout implements View, BrowserWindo
} }
} }
@PreDestroy @Override
void destroy() { public String getViewName() {
return DeploymentView.VIEW_NAME;
}
@Override
protected void subscribeListeners() {
if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.subscribe();
layoutResizeListener.subscribe();
}
super.subscribeListeners();
}
@Override
protected void unsubscribeListeners() {
if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) { if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) {
layoutVisibilityListener.unsubscribe(); layoutVisibilityListener.unsubscribe();
layoutResizeListener.unsubscribe(); layoutResizeListener.unsubscribe();
} }
if (permChecker.hasTargetReadPermission()) { super.unsubscribeListeners();
targetTagFilterLayout.unsubscribeListener();
targetGridLayout.unsubscribeListener();
actionHistoryLayout.unsubscribeListener();
}
if (permChecker.hasReadRepositoryPermission()) {
distributionTagLayout.unsubscribeListener();
distributionGridLayout.unsubscribeListener();
}
} }
} }

View File

@@ -10,12 +10,16 @@ package org.eclipse.hawkbit.ui.management;
import java.io.Serializable; import java.io.Serializable;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.ui.common.layout.listener.BulkUploadChangedListener;
import org.eclipse.hawkbit.ui.common.state.TagFilterLayoutUiState; import org.eclipse.hawkbit.ui.common.state.TagFilterLayoutUiState;
import org.eclipse.hawkbit.ui.management.actionhistory.ActionHistoryGridLayoutUiState; import org.eclipse.hawkbit.ui.management.actionhistory.ActionHistoryGridLayoutUiState;
import org.eclipse.hawkbit.ui.management.bulkupload.TargetBulkUploadUiState; import org.eclipse.hawkbit.ui.management.bulkupload.TargetBulkUploadUiState;
import org.eclipse.hawkbit.ui.management.dstable.DistributionGridLayoutUiState; import org.eclipse.hawkbit.ui.management.dstable.DistributionGridLayoutUiState;
import org.eclipse.hawkbit.ui.management.targettable.TargetGridLayoutUiState; import org.eclipse.hawkbit.ui.management.targettable.TargetGridLayoutUiState;
import org.eclipse.hawkbit.ui.management.targettag.filter.TargetTagFilterLayoutUiState; import org.eclipse.hawkbit.ui.management.targettag.filter.TargetTagFilterLayoutUiState;
import org.vaadin.spring.events.EventBus.SessionEventBus;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope; import com.vaadin.spring.annotation.VaadinSessionScope;
@@ -28,6 +32,8 @@ import com.vaadin.spring.annotation.VaadinSessionScope;
public class ManagementUIState implements Serializable { public class ManagementUIState implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final transient BulkUploadChangedListener bulkUploadListener;
private final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState; private final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState;
private final TargetGridLayoutUiState targetGridLayoutUiState; private final TargetGridLayoutUiState targetGridLayoutUiState;
private final TargetBulkUploadUiState targetBulkUploadUiState; private final TargetBulkUploadUiState targetBulkUploadUiState;
@@ -35,7 +41,7 @@ public class ManagementUIState implements Serializable {
private final TagFilterLayoutUiState distributionTagLayoutUiState; private final TagFilterLayoutUiState distributionTagLayoutUiState;
private final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState; private final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState;
ManagementUIState() { ManagementUIState(final SessionEventBus sessionEventBus) {
this.targetTagFilterLayoutUiState = new TargetTagFilterLayoutUiState(); this.targetTagFilterLayoutUiState = new TargetTagFilterLayoutUiState();
this.targetGridLayoutUiState = new TargetGridLayoutUiState(); this.targetGridLayoutUiState = new TargetGridLayoutUiState();
this.targetBulkUploadUiState = new TargetBulkUploadUiState(); this.targetBulkUploadUiState = new TargetBulkUploadUiState();
@@ -43,11 +49,15 @@ public class ManagementUIState implements Serializable {
this.distributionTagLayoutUiState = new TagFilterLayoutUiState(); this.distributionTagLayoutUiState = new TagFilterLayoutUiState();
this.actionHistoryGridLayoutUiState = new ActionHistoryGridLayoutUiState(); this.actionHistoryGridLayoutUiState = new ActionHistoryGridLayoutUiState();
this.bulkUploadListener = new BulkUploadChangedListener(sessionEventBus,
targetBulkUploadUiState::onBulkUploadChanged);
init(); init();
} }
private void init() { private void init() {
distributionTagLayoutUiState.setHidden(true); distributionTagLayoutUiState.setHidden(true);
bulkUploadListener.subscribe();
} }
/** /**
@@ -91,4 +101,9 @@ public class ManagementUIState implements Serializable {
public TargetBulkUploadUiState getTargetBulkUploadUiState() { public TargetBulkUploadUiState getTargetBulkUploadUiState() {
return targetBulkUploadUiState; return targetBulkUploadUiState;
} }
@PreDestroy
public void destroy() {
bulkUploadListener.unsubscribe();
}
} }

View File

@@ -49,19 +49,21 @@ public class ActionHistoryGridLayout extends AbstractGridComponentLayout {
* @param actionHistoryGridLayoutUiState * @param actionHistoryGridLayoutUiState
* ActionHistoryGridLayoutUiState * ActionHistoryGridLayoutUiState
*/ */
public ActionHistoryGridLayout(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement, public ActionHistoryGridLayout(final CommonUiDependencies uiDependencies,
final DeploymentManagement deploymentManagement,
final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState) { final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState) {
this.actionHistoryHeader = new ActionHistoryGridHeader(uiDependencies, actionHistoryGridLayoutUiState); this.actionHistoryHeader = new ActionHistoryGridHeader(uiDependencies, actionHistoryGridLayoutUiState);
this.actionHistoryGrid = new ActionHistoryGrid(uiDependencies, deploymentManagement, actionHistoryGridLayoutUiState); this.actionHistoryGrid = new ActionHistoryGrid(uiDependencies, deploymentManagement,
actionHistoryGridLayoutUiState);
final EventLayoutViewAware masterLayoutView = new EventLayoutViewAware(EventLayout.TARGET_LIST, final EventLayoutViewAware masterLayoutView = new EventLayoutViewAware(EventLayout.TARGET_LIST,
EventView.DEPLOYMENT); EventView.DEPLOYMENT);
this.masterEntityChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(),
this.masterEntityChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), masterLayoutView, masterLayoutView, getMasterEntityAwareComponents());
getMasterEntityAwareComponents()); this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyAction.class) ProxyAction.class).parentEntityType(ProxyTarget.class).parentEntityIdProvider(this::getMasterEntityId)
.entityModifiedAwareSupports(getEntityModifiedAwareSupports()).parentEntityType(ProxyTarget.class) .viewAware(masterLayoutView).entityModifiedAwareSupports(getEntityModifiedAwareSupports())
.parentEntityIdProvider(this::getMasterEntityId).build(); .build();
buildLayout(actionHistoryHeader, actionHistoryGrid); buildLayout(actionHistoryHeader, actionHistoryGrid);
} }
@@ -95,17 +97,24 @@ public class ActionHistoryGridLayout extends AbstractGridComponentLayout {
actionHistoryGrid.createMinimizedContent(); actionHistoryGrid.createMinimizedContent();
} }
/** @Override
* restore action histors header
*/
public void restoreState() { public void restoreState() {
actionHistoryHeader.restoreState(); actionHistoryHeader.restoreState();
} }
/** @Override
* Unsubscribe the changed listener public void onViewEnter() {
*/ actionHistoryGrid.getSelectionSupport().reselectCurrentEntity();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
entityModifiedListener.subscribe();
masterEntityChangedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
entityModifiedListener.unsubscribe(); entityModifiedListener.unsubscribe();
masterEntityChangedListener.unsubscribe(); masterEntityChangedListener.unsubscribe();
} }

View File

@@ -10,13 +10,14 @@ package org.eclipse.hawkbit.ui.management.actionhistory;
import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.EventListenersAwareLayout;
import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.HorizontalLayout;
/** /**
* Layout responsible for action-history-grid and the corresponding header. * Layout responsible for action-history-grid and the corresponding header.
*/ */
public class ActionHistoryLayout extends HorizontalLayout { public class ActionHistoryLayout extends HorizontalLayout implements EventListenersAwareLayout {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final ActionHistoryGridLayout actionHistoryGridLayout; private final ActionHistoryGridLayout actionHistoryGridLayout;
@@ -33,7 +34,8 @@ public class ActionHistoryLayout extends HorizontalLayout {
* @param actionHistoryGridLayoutUiState * @param actionHistoryGridLayoutUiState
* ActionHistoryGridLayoutUiState * ActionHistoryGridLayoutUiState
*/ */
public ActionHistoryLayout(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement, public ActionHistoryLayout(final CommonUiDependencies uiDependencies,
final DeploymentManagement deploymentManagement,
final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState) { final ActionHistoryGridLayoutUiState actionHistoryGridLayoutUiState) {
this.actionHistoryGridLayout = new ActionHistoryGridLayout(uiDependencies, deploymentManagement, this.actionHistoryGridLayout = new ActionHistoryGridLayout(uiDependencies, deploymentManagement,
@@ -65,13 +67,6 @@ public class ActionHistoryLayout extends HorizontalLayout {
setExpandRatio(actionStatusMsgLayout, 0.27F); setExpandRatio(actionStatusMsgLayout, 0.27F);
} }
/**
* Restore the action history grid layout
*/
public void restoreState() {
actionHistoryGridLayout.restoreState();
}
/** /**
* Maximize the action history grid layout * Maximize the action history grid layout
*/ */
@@ -98,12 +93,27 @@ public class ActionHistoryLayout extends HorizontalLayout {
actionStatusMsgLayout.setVisible(false); actionStatusMsgLayout.setVisible(false);
} }
/** @Override
* Unsubscribe the changed listener public void restoreState() {
*/ actionHistoryGridLayout.restoreState();
public void unsubscribeListener() { }
actionHistoryGridLayout.unsubscribeListener();
actionStatusLayout.unsubscribeListener(); @Override
actionStatusMsgLayout.unsubscribeListener(); public void onViewEnter() {
actionHistoryGridLayout.onViewEnter();
}
@Override
public void subscribeListeners() {
actionHistoryGridLayout.subscribeListeners();
actionStatusLayout.subscribeListeners();
actionStatusMsgLayout.subscribeListeners();
}
@Override
public void unsubscribeListeners() {
actionHistoryGridLayout.unsubscribeListeners();
actionStatusLayout.unsubscribeListeners();
actionStatusMsgLayout.unsubscribeListeners();
} }
} }

View File

@@ -41,7 +41,8 @@ public class ActionStatusGridLayout extends AbstractGridComponentLayout {
* @param deploymentManagement * @param deploymentManagement
* DeploymentManagement * DeploymentManagement
*/ */
public ActionStatusGridLayout(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement) { public ActionStatusGridLayout(final CommonUiDependencies uiDependencies,
final DeploymentManagement deploymentManagement) {
this.actionStatusGridHeader = new ActionStatusGridHeader(uiDependencies.getI18n()); this.actionStatusGridHeader = new ActionStatusGridHeader(uiDependencies.getI18n());
this.actionStatusGrid = new ActionStatusGrid(uiDependencies, deploymentManagement); this.actionStatusGrid = new ActionStatusGrid(uiDependencies, deploymentManagement);
@@ -96,10 +97,13 @@ public class ActionStatusGridLayout extends AbstractGridComponentLayout {
actionStatusGrid.getSelectionSupport().disableSelection(); actionStatusGrid.getSelectionSupport().disableSelection();
} }
/** @Override
* Unsubscribe the changed listener public void subscribeListeners() {
*/ selectionChangedListener.subscribe();
public void unsubscribeListener() { }
@Override
public void unsubscribeListeners() {
selectionChangedListener.unsubscribe(); selectionChangedListener.unsubscribe();
} }
} }

View File

@@ -40,7 +40,8 @@ public class ActionStatusMsgGridLayout extends AbstractGridComponentLayout {
* @param deploymentManagement * @param deploymentManagement
* DeploymentManagement * DeploymentManagement
*/ */
public ActionStatusMsgGridLayout(final CommonUiDependencies uiDependencies, final DeploymentManagement deploymentManagement) { public ActionStatusMsgGridLayout(final CommonUiDependencies uiDependencies,
final DeploymentManagement deploymentManagement) {
this.actionStatusMsgHeader = new ActionStatusMsgGridHeader(uiDependencies.getI18n()); this.actionStatusMsgHeader = new ActionStatusMsgGridHeader(uiDependencies.getI18n());
this.actionStatusMsgGrid = new ActionStatusMsgGrid(uiDependencies, deploymentManagement); this.actionStatusMsgGrid = new ActionStatusMsgGrid(uiDependencies, deploymentManagement);
@@ -79,10 +80,13 @@ public class ActionStatusMsgGridLayout extends AbstractGridComponentLayout {
actionStatusMsgGrid.getSelectionSupport().disableSelection(); actionStatusMsgGrid.getSelectionSupport().disableSelection();
} }
/** @Override
* Unsubscribe the changed listener public void subscribeListeners() {
*/ selectionChangedListener.subscribe();
public void unsubscribeListener() { }
@Override
public void unsubscribeListeners() {
selectionChangedListener.unsubscribe(); selectionChangedListener.unsubscribe();
} }
} }

View File

@@ -82,6 +82,7 @@ public class BulkUploadWindowBuilder {
targetBulkUpdateWindowLayout = new TargetBulkUpdateWindowLayout(uiDependencies, targetManagement, targetBulkUpdateWindowLayout = new TargetBulkUpdateWindowLayout(uiDependencies, targetManagement,
deploymentManagement, tagManagement, distributionSetManagement, uiproperties, uiExecutor, deploymentManagement, tagManagement, distributionSetManagement, uiproperties, uiExecutor,
targetBulkUploadUiState); targetBulkUploadUiState);
targetBulkUpdateWindowLayout.clearUiState();
} }
final Window bulkUploadWindow = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW) final Window bulkUploadWindow = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW)

View File

@@ -13,6 +13,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSetInfo; import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSetInfo;
import org.eclipse.hawkbit.ui.common.event.BulkUploadEventPayload;
/** /**
* Target bulk upload ui state * Target bulk upload ui state
@@ -94,4 +95,26 @@ public class TargetBulkUploadUiState implements Serializable {
public void setDescription(final String description) { public void setDescription(final String description) {
this.description = description; this.description = description;
} }
/**
* Updates state on bulk upload events
*
* @param eventPayload
* BulkUploadEventPayload
*/
public void onBulkUploadChanged(final BulkUploadEventPayload eventPayload) {
switch (eventPayload.getBulkUploadState()) {
case UPLOAD_STARTED:
setInProgress(true);
break;
case UPLOAD_FAILED:
setInProgress(false);
break;
case BULK_UPLOAD_COMPLETED:
setInProgress(false);
break;
default:
break;
}
}
} }

View File

@@ -33,7 +33,6 @@ import org.eclipse.hawkbit.ui.common.distributionset.DistributionSetGridHeader;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.EntityModifiedListener.EntityModifiedAwareSupport;
@@ -119,17 +118,18 @@ public class DistributionGridLayout extends AbstractDistributionSetGridLayout {
this.distributionDetails.setUnassignSmAllowed(false); this.distributionDetails.setUnassignSmAllowed(false);
this.distributionDetails.buildDetails(); this.distributionDetails.buildDetails();
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.DS_LIST, getEventView());
addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyDistributionSet.class, addEventListener(new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyDistributionSet.class,
new EventViewAware(getEventView()), distributionGrid.getFilterSupport())); layoutViewAware, distributionGrid.getFilterSupport()));
addEventListener(new PinningChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class, addEventListener(new PinningChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class,
distributionGrid.getPinSupport())); distributionGrid.getPinSupport()));
addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), addEventListener(new SelectionChangedListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.DS_LIST, getEventView()), getMasterDsAwareComponents())); getMasterDsAwareComponents()));
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyDistributionSet.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyDistributionSet.class)
.entityModifiedAwareSupports(getDsModifiedAwareSupports()).build()); .viewAware(layoutViewAware).entityModifiedAwareSupports(getDsModifiedAwareSupports()).build());
addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class) addEventListener(new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).parentEntityType(ProxyDistributionSet.class) .parentEntityType(ProxyDistributionSet.class).viewAware(layoutViewAware)
.build()); .entityModifiedAwareSupports(getTagModifiedAwareSupports()).build());
buildLayout(distributionGridHeader, distributionGrid, distributionSetDetailsHeader, distributionDetails); buildLayout(distributionGridHeader, distributionGrid, distributionSetDetailsHeader, distributionDetails);
} }

View File

@@ -8,10 +8,13 @@
*/ */
package org.eclipse.hawkbit.ui.management.dstag.filter; package org.eclipse.hawkbit.ui.management.dstag.filter;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.data.mappers.TagToProxyTagMapper; import org.eclipse.hawkbit.ui.common.data.mappers.TagToProxyTagMapper;
import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetTagDataProvider; import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetTagDataProvider;
@@ -124,4 +127,9 @@ public class DistributionTagButtons extends AbstractTagFilterButtons {
protected Window getUpdateWindow(final ProxyTag clickedFilter) { protected Window getUpdateWindow(final ProxyTag clickedFilter) {
return dsTagWindowBuilder.getWindowForUpdate(clickedFilter); return dsTagWindowBuilder.getWindowForUpdate(clickedFilter);
} }
@Override
protected Collection<Long> filterExistingTagIds(final Collection<Long> tagIds) {
return distributionSetTagManagement.get(tagIds).stream().map(Identifiable::getId).collect(Collectors.toSet());
}
} }

View File

@@ -62,20 +62,22 @@ public class DistributionTagLayout extends AbstractFilterLayout {
final DistributionSetTagManagement distributionSetTagManagement, final DistributionSetTagManagement distributionSetTagManagement,
final DistributionSetManagement distributionSetManagement, final DistributionSetManagement distributionSetManagement,
final TagFilterLayoutUiState distributionTagLayoutUiState) { final TagFilterLayoutUiState distributionTagLayoutUiState) {
final DsTagWindowBuilder dsTagWindowBuilder = new DsTagWindowBuilder(uiDependencies, distributionSetTagManagement); final DsTagWindowBuilder dsTagWindowBuilder = new DsTagWindowBuilder(uiDependencies,
distributionSetTagManagement);
this.distributionTagFilterHeader = new DistributionTagFilterHeader(uiDependencies, dsTagWindowBuilder, this.distributionTagFilterHeader = new DistributionTagFilterHeader(uiDependencies, dsTagWindowBuilder,
distributionTagLayoutUiState); distributionTagLayoutUiState);
this.distributionTagButtons = new DistributionTagButtons(uiDependencies, distributionSetTagManagement, this.distributionTagButtons = new DistributionTagButtons(uiDependencies, distributionSetTagManagement,
distributionSetManagement, dsTagWindowBuilder, distributionTagLayoutUiState); distributionSetManagement, dsTagWindowBuilder, distributionTagLayoutUiState);
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.DS_TAG_FILTER,
EventView.DEPLOYMENT);
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(), this.gridActionsVisibilityListener = new GridActionsVisibilityListener(uiDependencies.getEventBus(),
new EventLayoutViewAware(EventLayout.DS_TAG_FILTER, EventView.DEPLOYMENT), layoutViewAware, distributionTagButtons::hideActionColumns, distributionTagButtons::showEditColumn,
distributionTagButtons::hideActionColumns, distributionTagButtons::showEditColumn,
distributionTagButtons::showDeleteColumn); distributionTagButtons::showDeleteColumn);
this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class) this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class)
.entityModifiedAwareSupports(getEntityModifiedAwareSupports()) .parentEntityType(ProxyDistributionSet.class).viewAware(layoutViewAware)
.parentEntityType(ProxyDistributionSet.class).build(); .entityModifiedAwareSupports(getEntityModifiedAwareSupports()).build();
buildLayout(); buildLayout();
} }
@@ -101,18 +103,25 @@ public class DistributionTagLayout extends AbstractFilterLayout {
return filterButtonsLayout; return filterButtonsLayout;
} }
/** @Override
* Restore the distribution tag state
*/
public void restoreState() { public void restoreState() {
distributionTagFilterHeader.restoreState(); distributionTagFilterHeader.restoreState();
distributionTagButtons.restoreState(); distributionTagButtons.restoreState();
} }
/** @Override
* Unsubscribe the changed listener public void onViewEnter() {
*/ distributionTagButtons.reevaluateFilter();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
gridActionsVisibilityListener.subscribe();
entityModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
gridActionsVisibilityListener.unsubscribe(); gridActionsVisibilityListener.unsubscribe();
entityModifiedListener.unsubscribe(); entityModifiedListener.unsubscribe();
} }

View File

@@ -13,7 +13,10 @@ import java.util.Collection;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams; import org.eclipse.hawkbit.ui.common.data.filters.TargetManagementFilterParams;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTarget;
import org.eclipse.hawkbit.ui.common.grid.support.FilterSupport;
import org.eclipse.hawkbit.ui.common.layout.AbstractFooterSupport; import org.eclipse.hawkbit.ui.common.layout.AbstractFooterSupport;
import org.eclipse.hawkbit.ui.common.layout.CountAwareComponent;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
@@ -21,6 +24,7 @@ import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.vaadin.data.provider.Query;
import com.vaadin.shared.ui.ContentMode; import com.vaadin.shared.ui.ContentMode;
import com.vaadin.ui.Label; import com.vaadin.ui.Label;
@@ -28,24 +32,27 @@ import com.vaadin.ui.Label;
* Count message label which display current filter details and details on * Count message label which display current filter details and details on
* pinning. * pinning.
*/ */
public class TargetCountMessageLabel extends AbstractFooterSupport { public class TargetCountMessageLabel extends AbstractFooterSupport implements CountAwareComponent {
private final VaadinMessageSource i18n; private final VaadinMessageSource i18n;
private final TargetManagement targetManagement; private final TargetManagement targetManagement;
private final FilterSupport<ProxyTarget, TargetManagementFilterParams> gridFilterSupport;
private final Label targetCountLabel; private final Label targetCountLabel;
private int totalCount;
private int filteredCount;
/** /**
* Constructor * Constructor
* *
* @param targetManagement
* TargetManagement
* @param i18n * @param i18n
* I18N * I18N
*/ */
public TargetCountMessageLabel(final TargetManagement targetManagement, final VaadinMessageSource i18n) { public TargetCountMessageLabel(final VaadinMessageSource i18n, final TargetManagement targetManagement,
this.targetManagement = targetManagement; final FilterSupport<ProxyTarget, TargetManagementFilterParams> gridFilterSupport) {
this.i18n = i18n; this.i18n = i18n;
this.targetManagement = targetManagement;
this.gridFilterSupport = gridFilterSupport;
this.targetCountLabel = new Label(); this.targetCountLabel = new Label();
init(); init();
@@ -59,91 +66,132 @@ public class TargetCountMessageLabel extends AbstractFooterSupport {
targetCountLabel.setDescription(null); targetCountLabel.setDescription(null);
} }
/** public void updateTotalCount() {
* Display target count status on label totalCount = fetchTotalCount();
* updateCountLabel();
* @param count
* Total targets
* @param targetFilterParams
* TargetManagementFilterParams
*/
public void displayTargetCountStatus(final long count, final TargetManagementFilterParams targetFilterParams) {
if (targetFilterParams == null) {
return;
}
targetCountLabel.setCaption(getTargetCountStatusMessage(count, targetFilterParams));
updatePinningDetails(targetFilterParams.getPinnedDistId());
} }
private String getTargetCountStatusMessage(final long count, private int fetchTotalCount() {
final TargetManagementFilterParams targetFilterParams) { return gridFilterSupport.getOriginalDataProvider().size(new Query<>());
if (!targetFilterParams.isAnyFilterSelected()) {
return getTotalTargetMessage(count).toString();
}
final StringBuilder message = getTotalTargetMessage();
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
message.append(i18n.getMessage("label.filter.targets"));
message.append(count);
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
final String status = i18n.getMessage("label.filter.status");
final String overdue = i18n.getMessage("label.filter.overdue");
final String tags = i18n.getMessage("label.filter.tags");
final String text = i18n.getMessage("label.filter.text");
final String dists = i18n.getMessage("label.filter.dist");
final String custom = i18n.getMessage("label.filter.custom");
final StringBuilder filterMesgBuf = new StringBuilder(i18n.getMessage("label.filter"));
filterMesgBuf.append(" ");
filterMesgBuf.append(getStatusMsg(targetFilterParams.getTargetUpdateStatusList(), status));
filterMesgBuf.append(getOverdueStateMsg(targetFilterParams.isOverdueState(), overdue));
filterMesgBuf.append(getTagsMsg(targetFilterParams.isNoTagClicked(), targetFilterParams.getTargetTags(), tags));
filterMesgBuf.append(!StringUtils.isEmpty(targetFilterParams.getSearchText()) ? text : " ");
filterMesgBuf.append(targetFilterParams.getDistributionId() != null ? dists : " ");
filterMesgBuf.append(targetFilterParams.getTargetFilterQueryId() != null ? custom : " ");
final String filterMesageChk = filterMesgBuf.toString().trim();
String filterMesage = filterMesageChk;
if (filterMesage.endsWith(",")) {
filterMesage = filterMesageChk.substring(0, filterMesageChk.length() - 1);
}
message.append(filterMesage);
return message.toString();
} }
private StringBuilder getTotalTargetMessage(final long count) { public void updateFilteredCount() {
if (gridFilterSupport.getFilter().isAnyFilterSelected()) {
filteredCount = fetchFilteredCount();
}
updateCountLabel();
}
private int fetchFilteredCount() {
return gridFilterSupport.getFilterDataProvider().size(new Query<>());
}
public void updateTotalAndFilteredCount() {
totalCount = fetchTotalCount();
if (gridFilterSupport.getFilter().isAnyFilterSelected()) {
filteredCount = fetchFilteredCount();
}
updateCountLabel();
}
private void updateCountLabel() {
final StringBuilder countMessageBuilder = getTotalTargetsMessage();
final TargetManagementFilterParams targetFilterParams = gridFilterSupport.getFilter();
if (targetFilterParams.isAnyFilterSelected()) {
appendFilteredTargetsMessage(countMessageBuilder, targetFilterParams);
}
targetCountLabel.setCaption(countMessageBuilder.toString());
}
private StringBuilder getTotalTargetsMessage() {
final StringBuilder message = new StringBuilder(i18n.getMessage("label.target.filter.count")); final StringBuilder message = new StringBuilder(i18n.getMessage("label.target.filter.count"));
message.append(": "); message.append(": ");
message.append(count); message.append(totalCount);
return message; return message;
} }
private StringBuilder getTotalTargetMessage() { private void appendFilteredTargetsMessage(final StringBuilder countMessageBuilder,
return getTotalTargetMessage(targetManagement.count()); final TargetManagementFilterParams targetFilterParams) {
countMessageBuilder.append(HawkbitCommonUtil.SP_STRING_PIPE);
countMessageBuilder.append(i18n.getMessage("label.filter.targets"));
countMessageBuilder.append(filteredCount);
countMessageBuilder.append(HawkbitCommonUtil.SP_STRING_PIPE);
countMessageBuilder.append(getFilterParametersMessage(targetFilterParams));
} }
private static String getStatusMsg(final Collection<TargetUpdateStatus> status, final String param) { private String getFilterParametersMessage(final TargetManagementFilterParams targetFilterParams) {
return status.isEmpty() ? " " : param; final StringBuilder filterMessageBuilder = new StringBuilder(i18n.getMessage("label.filter"));
filterMessageBuilder.append(" ");
appendStatusMsg(filterMessageBuilder, targetFilterParams.getTargetUpdateStatusList());
appendOverdueStateMsg(filterMessageBuilder, targetFilterParams.isOverdueState());
appendTagsMsg(filterMessageBuilder, targetFilterParams.isNoTagClicked(), targetFilterParams.getTargetTags());
appendSearchMsg(filterMessageBuilder, targetFilterParams.getSearchText());
appendDsMsg(filterMessageBuilder, targetFilterParams.getDistributionId());
appendCustomFilterQueryMsg(filterMessageBuilder, targetFilterParams.getTargetFilterQueryId());
String filterMessage = filterMessageBuilder.toString().trim();
if (filterMessage.endsWith(",")) {
filterMessage = filterMessage.substring(0, filterMessage.length() - 1);
}
return filterMessage;
} }
private static String getOverdueStateMsg(final boolean overdueState, final String param) { private void appendStatusMsg(final StringBuilder filterMessageBuilder,
return !overdueState ? " " : param; final Collection<TargetUpdateStatus> status) {
if (!status.isEmpty()) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.status"));
}
} }
private static String getTagsMsg(final Boolean noTargetTagSelected, final Collection<String> tags, private static void appendFilterMsg(final StringBuilder filterMessageBuilder, final String filter) {
final String param) { filterMessageBuilder.append(filter);
return CollectionUtils.isEmpty(tags) && Boolean.FALSE.equals(noTargetTagSelected) ? " " : param; filterMessageBuilder.append(", ");
}
private void appendOverdueStateMsg(final StringBuilder filterMessageBuilder, final boolean overdueState) {
if (overdueState) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.overdue"));
}
}
private void appendTagsMsg(final StringBuilder filterMessageBuilder, final boolean noTargetTagSelected,
final Collection<String> tags) {
if (noTargetTagSelected || !CollectionUtils.isEmpty(tags)) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.tags"));
}
}
private void appendSearchMsg(final StringBuilder filterMessageBuilder, final String search) {
if (!StringUtils.isEmpty(search)) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.text"));
}
}
private void appendDsMsg(final StringBuilder filterMessageBuilder, final Long dsId) {
if (dsId != null) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.dist"));
}
}
private void appendCustomFilterQueryMsg(final StringBuilder filterMessageBuilder, final Long customFilterQueryId) {
if (customFilterQueryId != null) {
appendFilterMsg(filterMessageBuilder, i18n.getMessage("label.filter.custom"));
}
} }
/** /**
* Update pinning details * Update pinning details
* *
* @param pinnedDsId
* Pinned distribution set id
*/ */
public void updatePinningDetails(final Long pinnedDsId) { public void updatePinningDetails() {
final Long pinnedDsId = gridFilterSupport.getFilter().getPinnedDistId();
if (pinnedDsId == null) { if (pinnedDsId == null) {
targetCountLabel.setValue(""); targetCountLabel.setValue("");
return; return;
@@ -167,4 +215,21 @@ public class TargetCountMessageLabel extends AbstractFooterSupport {
protected Label getFooterMessageLabel() { protected Label getFooterMessageLabel() {
return targetCountLabel; return targetCountLabel;
} }
@Override
public void updateCountOnEntitiesAdded(final int count) {
updateTotalAndFilteredCount();
}
@Override
public void updateCountOnEntitiesUpdated() {
updateFilteredCount();
updatePinningDetails();
}
@Override
public void updateCountOnEntitiesDeleted(final int count) {
updateTotalAndFilteredCount();
updatePinningDetails();
}
} }

View File

@@ -186,7 +186,7 @@ public class TargetGridHeader extends AbstractEntityGridHeader {
bulkUploadTargetWindow.setVisible(true); bulkUploadTargetWindow.setVisible(true);
} }
private Boolean isBulkUploadInProgress() { private boolean isBulkUploadInProgress() {
return targetBulkUploadUiState.isInProgress(); return targetBulkUploadUiState.isInProgress();
} }
@@ -207,11 +207,11 @@ public class TargetGridHeader extends AbstractEntityGridHeader {
final String failureReason, final float progress, final int successCount, final int failCount) { final String failureReason, final float progress, final int successCount, final int failCount) {
switch (state) { switch (state) {
case UPLOAD_STARTED: case UPLOAD_STARTED:
adaptbulkUploadHeaderAndUiState(true); bulkUploadHeaderSupport.showProgressIndicator();
layout.onStartOfUpload(); layout.onStartOfUpload();
break; break;
case UPLOAD_FAILED: case UPLOAD_FAILED:
adaptbulkUploadHeaderAndUiState(false); bulkUploadHeaderSupport.hideProgressIndicator();
layout.onUploadFailure(failureReason); layout.onUploadFailure(failureReason);
break; break;
case TARGET_PROVISIONING_STARTED: case TARGET_PROVISIONING_STARTED:
@@ -227,19 +227,19 @@ public class TargetGridHeader extends AbstractEntityGridHeader {
layout.onAssignmentFailure(failureReason); layout.onAssignmentFailure(failureReason);
break; break;
case BULK_UPLOAD_COMPLETED: case BULK_UPLOAD_COMPLETED:
adaptbulkUploadHeaderAndUiState(false); bulkUploadHeaderSupport.hideProgressIndicator();
layout.onUploadCompletion(successCount, failCount); layout.onUploadCompletion(successCount, failCount);
break; break;
} }
} }
private void adaptbulkUploadHeaderAndUiState(final boolean isInProgress) { /**
if (isInProgress) { * Hides progress indicator in case no bulk upload is running.
bulkUploadHeaderSupport.showProgressIndicator(); */
} else { public void checkBulkUpload() {
if (bulkUploadHeaderSupport != null && !isBulkUploadInProgress()) {
bulkUploadHeaderSupport.hideProgressIndicator(); bulkUploadHeaderSupport.hideProgressIndicator();
} }
targetBulkUploadUiState.setInProgress(isInProgress);
} }
/** /**

View File

@@ -29,7 +29,6 @@ import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware; import org.eclipse.hawkbit.ui.common.event.EventLayoutViewAware;
import org.eclipse.hawkbit.ui.common.event.EventTopics; import org.eclipse.hawkbit.ui.common.event.EventTopics;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
import org.eclipse.hawkbit.ui.common.event.EventViewAware;
import org.eclipse.hawkbit.ui.common.event.TargetFilterTabChangedEventPayload; import org.eclipse.hawkbit.ui.common.event.TargetFilterTabChangedEventPayload;
import org.eclipse.hawkbit.ui.common.layout.AbstractGridComponentLayout; import org.eclipse.hawkbit.ui.common.layout.AbstractGridComponentLayout;
import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent; import org.eclipse.hawkbit.ui.common.layout.MasterEntityAwareComponent;
@@ -41,6 +40,7 @@ import org.eclipse.hawkbit.ui.common.layout.listener.GenericEventListener;
import org.eclipse.hawkbit.ui.common.layout.listener.PinningChangedListener; import org.eclipse.hawkbit.ui.common.layout.listener.PinningChangedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.SelectGridEntityListener; import org.eclipse.hawkbit.ui.common.layout.listener.SelectGridEntityListener;
import org.eclipse.hawkbit.ui.common.layout.listener.SelectionChangedListener; import org.eclipse.hawkbit.ui.common.layout.listener.SelectionChangedListener;
import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedCountAwareSupport;
import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridRefreshAwareSupport; import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedGridRefreshAwareSupport;
import org.eclipse.hawkbit.ui.common.layout.listener.support.EntityModifiedPinAwareSupport; 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.EntityModifiedSelectionAwareSupport;
@@ -134,37 +134,33 @@ public class TargetGridLayout extends AbstractGridComponentLayout {
this.targetDetails = new TargetDetails(uiDependencies, targetTagManagement, targetManagement, this.targetDetails = new TargetDetails(uiDependencies, targetTagManagement, targetManagement,
deploymentManagement, targetMetaDataWindowBuilder); deploymentManagement, targetMetaDataWindowBuilder);
this.countMessageLabel = new TargetCountMessageLabel(targetManagement, uiDependencies.getI18n()); this.countMessageLabel = new TargetCountMessageLabel(uiDependencies.getI18n(), targetManagement,
targetGrid.getFilterSupport());
initGridDataUpdatedListener();
final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.TARGET_LIST,
EventView.DEPLOYMENT);
this.filterTabChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(), this.filterTabChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(),
EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged); EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged);
this.targetFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class, this.targetFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyTarget.class,
new EventViewAware(EventView.DEPLOYMENT), targetGrid.getFilterSupport()); layoutViewAware, targetGrid.getFilterSupport(), countMessageLabel::updateFilteredCount);
this.pinningChangedListener = new PinningChangedListener<>(uiDependencies.getEventBus(), this.pinningChangedListener = new PinningChangedListener<>(uiDependencies.getEventBus(),
ProxyDistributionSet.class, targetGrid.getPinSupport()); ProxyDistributionSet.class, targetGrid.getPinSupport(), countMessageLabel::updatePinningDetails);
this.targetChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), this.targetChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.TARGET_LIST, EventView.DEPLOYMENT),
getMasterTargetAwareComponents()); getMasterTargetAwareComponents());
this.selectTargetListener = new SelectGridEntityListener<>(uiDependencies.getEventBus(), this.selectTargetListener = new SelectGridEntityListener<>(uiDependencies.getEventBus(), layoutViewAware,
new EventLayoutViewAware(EventLayout.TARGET_LIST, EventView.DEPLOYMENT),
targetGrid.getSelectionSupport()); targetGrid.getSelectionSupport());
this.targetModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), this.targetModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
ProxyTarget.class).entityModifiedAwareSupports(getTargetModifiedAwareSupports()).build(); ProxyTarget.class).viewAware(layoutViewAware)
.entityModifiedAwareSupports(getTargetModifiedAwareSupports()).build();
this.tagModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class) this.tagModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyTag.class)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).parentEntityType(ProxyTarget.class).build(); .parentEntityType(ProxyTarget.class).viewAware(layoutViewAware)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).build();
this.bulkUploadListener = new BulkUploadChangedListener(uiDependencies.getEventBus(), this.bulkUploadListener = new BulkUploadChangedListener(uiDependencies.getEventBus(),
targetGridHeader::onBulkUploadChanged); targetGridHeader::onBulkUploadChanged);
buildLayout(targetGridHeader, targetGrid, targetDetailsHeader, targetDetails); buildLayout(targetGridHeader, targetGrid, targetDetailsHeader, targetDetails);
} }
private void initGridDataUpdatedListener() {
targetGrid.addDataChangedListener(event -> countMessageLabel.displayTargetCountStatus(targetGrid.getDataSize(),
targetGrid.getFilter().orElse(null)));
}
private List<MasterEntityAwareComponent<ProxyTarget>> getMasterTargetAwareComponents() { private List<MasterEntityAwareComponent<ProxyTarget>> getMasterTargetAwareComponents() {
return Arrays.asList(targetDetailsHeader, targetDetails); return Arrays.asList(targetDetailsHeader, targetDetails);
} }
@@ -174,7 +170,8 @@ public class TargetGridLayout extends AbstractGridComponentLayout {
EntityModifiedSelectionAwareSupport.of(targetGrid.getSelectionSupport(), EntityModifiedSelectionAwareSupport.of(targetGrid.getSelectionSupport(),
targetGrid::mapIdToProxyEntity), targetGrid::mapIdToProxyEntity),
EntityModifiedPinAwareSupport.of(targetGrid.getPinSupport(), true, true), EntityModifiedPinAwareSupport.of(targetGrid.getPinSupport(), true, true),
EntityModifiedGridRefreshAwareSupport.of(targetGrid::refreshAll)); EntityModifiedGridRefreshAwareSupport.of(targetGrid::refreshAll),
EntityModifiedCountAwareSupport.of(countMessageLabel));
} }
private List<EntityModifiedAwareSupport> getTagModifiedAwareSupports() { private List<EntityModifiedAwareSupport> getTagModifiedAwareSupports() {
@@ -211,6 +208,8 @@ public class TargetGridLayout extends AbstractGridComponentLayout {
targetGridHeader.enableSearchIcon(); targetGridHeader.enableSearchIcon();
targetGrid.onSimpleTabSelected(); targetGrid.onSimpleTabSelected();
} }
countMessageLabel.updateFilteredCount();
} }
/** /**
@@ -229,18 +228,36 @@ public class TargetGridLayout extends AbstractGridComponentLayout {
showDetailsLayout(); showDetailsLayout();
} }
/** @Override
* Restore the target grid state
*/
public void restoreState() { public void restoreState() {
targetGridHeader.restoreState(); targetGridHeader.restoreState();
targetGrid.restoreState(); targetGrid.restoreState();
countMessageLabel.updateTotalAndFilteredCount();
countMessageLabel.updatePinningDetails();
} }
/** @Override
* Unsubscribe all the listeners public void onViewEnter() {
*/ targetGridHeader.checkBulkUpload();
public void unsubscribeListener() { targetGrid.getSelectionSupport().reselectCurrentEntity();
countMessageLabel.updateTotalAndFilteredCount();
countMessageLabel.updatePinningDetails();
}
@Override
public void subscribeListeners() {
filterTabChangedListener.subscribe();
targetFilterListener.subscribe();
pinningChangedListener.subscribe();
targetChangedListener.subscribe();
selectTargetListener.subscribe();
targetModifiedListener.subscribe();
tagModifiedListener.subscribe();
bulkUploadListener.subscribe();
}
@Override
public void unsubscribeListeners() {
filterTabChangedListener.unsubscribe(); filterTabChangedListener.unsubscribe();
targetFilterListener.unsubscribe(); targetFilterListener.unsubscribe();
pinningChangedListener.unsubscribe(); pinningChangedListener.unsubscribe();

View File

@@ -59,7 +59,8 @@ public class MultipleTargetFilter extends Accordion {
private final transient EntityModifiedListener<ProxyTag> entityTagModifiedListener; private final transient EntityModifiedListener<ProxyTag> entityTagModifiedListener;
private final transient EntityModifiedListener<ProxyTargetFilterQuery> entityFilterQueryModifiedListener; private final transient EntityModifiedListener<ProxyTargetFilterQuery> entityFilterQueryModifiedListener;
MultipleTargetFilter(final CommonUiDependencies uiDependencies, final TargetFilterQueryManagement targetFilterQueryManagement, MultipleTargetFilter(final CommonUiDependencies uiDependencies,
final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement, final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState, final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState,
final TargetTagWindowBuilder targetTagWindowBuilder) { final TargetTagWindowBuilder targetTagWindowBuilder) {
@@ -74,14 +75,16 @@ public class MultipleTargetFilter extends Accordion {
this.customFilterTab = new TargetFilterQueryButtons(i18n, eventBus, targetFilterQueryManagement, this.customFilterTab = new TargetFilterQueryButtons(i18n, eventBus, targetFilterQueryManagement,
targetTagFilterLayoutUiState); targetTagFilterLayoutUiState);
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(eventBus, final EventLayoutViewAware layoutViewAware = new EventLayoutViewAware(EventLayout.TARGET_TAG_FILTER,
new EventLayoutViewAware(EventLayout.TARGET_TAG_FILTER, EventView.DEPLOYMENT), EventView.DEPLOYMENT);
this.gridActionsVisibilityListener = new GridActionsVisibilityListener(eventBus, layoutViewAware,
filterByButtons::hideActionColumns, filterByButtons::showEditColumn, filterByButtons::showDeleteColumn); filterByButtons::hideActionColumns, filterByButtons::showEditColumn, filterByButtons::showDeleteColumn);
this.entityTagModifiedListener = new EntityModifiedListener.Builder<>(eventBus, ProxyTag.class) this.entityTagModifiedListener = new EntityModifiedListener.Builder<>(eventBus, ProxyTag.class)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).parentEntityType(ProxyTarget.class).build(); .parentEntityType(ProxyTarget.class).viewAware(layoutViewAware)
.entityModifiedAwareSupports(getTagModifiedAwareSupports()).build();
this.entityFilterQueryModifiedListener = new EntityModifiedListener.Builder<>(eventBus, this.entityFilterQueryModifiedListener = new EntityModifiedListener.Builder<>(eventBus,
ProxyTargetFilterQuery.class).entityModifiedAwareSupports(getFilterQueryModifiedAwareSupports()) ProxyTargetFilterQuery.class).viewAware(layoutViewAware)
.build(); .entityModifiedAwareSupports(getFilterQueryModifiedAwareSupports()).build();
init(); init();
addTabs(); addTabs();
@@ -176,9 +179,26 @@ public class MultipleTargetFilter extends Accordion {
} }
/** /**
* Unsubscribe the event listener * Update components on view enter
*/ */
public void unsubscribeListener() { public void onViewEnter() {
filterByButtons.reevaluateFilter();
customFilterTab.reevaluateFilter();
}
/**
* Subscribe event listeners
*/
public void subscribeListeners() {
gridActionsVisibilityListener.subscribe();
entityTagModifiedListener.subscribe();
entityFilterQueryModifiedListener.subscribe();
}
/**
* Unsubscribe event listeners
*/
public void unsubscribeListeners() {
gridActionsVisibilityListener.unsubscribe(); gridActionsVisibilityListener.unsubscribe();
entityTagModifiedListener.unsubscribe(); entityTagModifiedListener.unsubscribe();
entityFilterQueryModifiedListener.unsubscribe(); entityFilterQueryModifiedListener.unsubscribe();

View File

@@ -44,6 +44,7 @@ public class TargetFilterQueryButtons extends AbstractGrid<ProxyTargetFilterQuer
private static final String FILTER_BUTTON_COLUMN_ID = "filterButton"; private static final String FILTER_BUTTON_COLUMN_ID = "filterButton";
private final transient TargetFilterQueryManagement targetFilterQueryManagement;
private final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState; private final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState;
private final CustomTargetTagFilterButtonClick customTargetTagFilterButtonClick; private final CustomTargetTagFilterButtonClick customTargetTagFilterButtonClick;
@@ -53,6 +54,7 @@ public class TargetFilterQueryButtons extends AbstractGrid<ProxyTargetFilterQuer
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState) { final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState) {
super(i18n, eventBus); super(i18n, eventBus);
this.targetFilterQueryManagement = targetFilterQueryManagement;
this.targetTagFilterLayoutUiState = targetTagFilterLayoutUiState; this.targetTagFilterLayoutUiState = targetTagFilterLayoutUiState;
this.customTargetTagFilterButtonClick = new CustomTargetTagFilterButtonClick(this::onFilterChangedEvent); this.customTargetTagFilterButtonClick = new CustomTargetTagFilterButtonClick(this::onFilterChangedEvent);
@@ -141,7 +143,7 @@ public class TargetFilterQueryButtons extends AbstractGrid<ProxyTargetFilterQuer
* Reselect filter when target filter query updated * Reselect filter when target filter query updated
* *
* @param updatedTargetFilterQueryIds * @param updatedTargetFilterQueryIds
* List of update query id * List of update query id
*/ */
public void reselectFilterOnTfqUpdated(final Collection<Long> updatedTargetFilterQueryIds) { public void reselectFilterOnTfqUpdated(final Collection<Long> updatedTargetFilterQueryIds) {
if (isClickedTfqInIds(updatedTargetFilterQueryIds)) { if (isClickedTfqInIds(updatedTargetFilterQueryIds)) {
@@ -159,7 +161,7 @@ public class TargetFilterQueryButtons extends AbstractGrid<ProxyTargetFilterQuer
* Reselect filter when target filter query deleted * Reselect filter when target filter query deleted
* *
* @param deletedTargetFilterQueryIds * @param deletedTargetFilterQueryIds
* List of deleted query id * List of deleted query id
*/ */
public void resetFilterOnTfqDeleted(final Collection<Long> deletedTargetFilterQueryIds) { public void resetFilterOnTfqDeleted(final Collection<Long> deletedTargetFilterQueryIds) {
if (isClickedTfqInIds(deletedTargetFilterQueryIds)) { if (isClickedTfqInIds(deletedTargetFilterQueryIds)) {
@@ -173,8 +175,29 @@ public class TargetFilterQueryButtons extends AbstractGrid<ProxyTargetFilterQuer
final Long targetFilterQueryIdToRestore = targetTagFilterLayoutUiState.getClickedTargetFilterQueryId(); final Long targetFilterQueryIdToRestore = targetTagFilterLayoutUiState.getClickedTargetFilterQueryId();
if (targetFilterQueryIdToRestore != null) { if (targetFilterQueryIdToRestore != null) {
customTargetTagFilterButtonClick if (targetFilterQueryExists(targetFilterQueryIdToRestore)) {
.setPreviouslyClickedFilterId(targetTagFilterLayoutUiState.getClickedTargetFilterQueryId()); customTargetTagFilterButtonClick
.setPreviouslyClickedFilterId(targetTagFilterLayoutUiState.getClickedTargetFilterQueryId());
} else {
targetTagFilterLayoutUiState.setClickedTargetFilterQueryId(null);
}
}
}
private boolean targetFilterQueryExists(final Long targetFilterQueryId) {
return targetFilterQueryManagement.get(targetFilterQueryId).isPresent();
}
/**
* Re-evaluates a filter (usually after view enter).
*
*/
public void reevaluateFilter() {
final Long clickedTargetFilterQueryId = customTargetTagFilterButtonClick.getPreviouslyClickedFilterId();
if (clickedTargetFilterQueryId != null && !targetFilterQueryExists(clickedTargetFilterQueryId)) {
customTargetTagFilterButtonClick.setPreviouslyClickedFilterId(null);
publishFilterChangedEvent(null);
} }
} }
} }

View File

@@ -8,8 +8,11 @@
*/ */
package org.eclipse.hawkbit.ui.management.targettag.filter; package org.eclipse.hawkbit.ui.management.targettag.filter;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
@@ -106,4 +109,9 @@ public class TargetTagFilterButtons extends AbstractTagFilterButtons {
protected Window getUpdateWindow(final ProxyTag clickedFilter) { protected Window getUpdateWindow(final ProxyTag clickedFilter) {
return targetTagWindowBuilder.getWindowForUpdate(clickedFilter); return targetTagWindowBuilder.getWindowForUpdate(clickedFilter);
} }
@Override
protected Collection<Long> filterExistingTagIds(final Collection<Long> tagIds) {
return targetTagManagement.get(tagIds).stream().map(Identifiable::getId).collect(Collectors.toSet());
}
} }

View File

@@ -52,12 +52,13 @@ public class TargetTagFilterLayout extends AbstractFilterLayout {
final TargetFilterQueryManagement targetFilterQueryManagement, final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetTagManagement targetTagManagement, final TargetManagement targetManagement, final TargetTagManagement targetTagManagement, final TargetManagement targetManagement,
final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState) { final TargetTagFilterLayoutUiState targetTagFilterLayoutUiState) {
final TargetTagWindowBuilder targetTagWindowBuilder = new TargetTagWindowBuilder(uiDependencies, targetTagManagement); final TargetTagWindowBuilder targetTagWindowBuilder = new TargetTagWindowBuilder(uiDependencies,
targetTagManagement);
this.targetTagFilterHeader = new TargetTagFilterHeader(uiDependencies, targetTagFilterLayoutUiState, this.targetTagFilterHeader = new TargetTagFilterHeader(uiDependencies, targetTagFilterLayoutUiState,
targetTagWindowBuilder); targetTagWindowBuilder);
this.multipleTargetFilter = new MultipleTargetFilter(uiDependencies, targetFilterQueryManagement, targetTagManagement, this.multipleTargetFilter = new MultipleTargetFilter(uiDependencies, targetFilterQueryManagement,
targetManagement, targetTagFilterLayoutUiState, targetTagWindowBuilder); targetTagManagement, targetManagement, targetTagFilterLayoutUiState, targetTagWindowBuilder);
this.filterTabChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(), this.filterTabChangedListener = new GenericEventListener<>(uiDependencies.getEventBus(),
EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged); EventTopics.TARGET_FILTER_TAB_CHANGED, this::onTargetFilterTabChanged);
@@ -83,19 +84,26 @@ public class TargetTagFilterLayout extends AbstractFilterLayout {
return multipleTargetFilter; return multipleTargetFilter;
} }
/** @Override
* Restore the target filter state
*/
public void restoreState() { public void restoreState() {
targetTagFilterHeader.restoreState(); targetTagFilterHeader.restoreState();
multipleTargetFilter.restoreState(); multipleTargetFilter.restoreState();
} }
/** @Override
* Unsubscribe the event listener public void onViewEnter() {
*/ multipleTargetFilter.onViewEnter();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
filterTabChangedListener.subscribe();
multipleTargetFilter.subscribeListeners();
}
@Override
public void unsubscribeListeners() {
filterTabChangedListener.unsubscribe(); filterTabChangedListener.unsubscribe();
multipleTargetFilter.unsubscribeListener(); multipleTargetFilter.unsubscribeListeners();
} }
} }

View File

@@ -45,7 +45,6 @@ import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBus.SessionEventBus;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.nimbusds.oauth2.sdk.util.CollectionUtils; import com.nimbusds.oauth2.sdk.util.CollectionUtils;
@@ -286,7 +285,7 @@ public class DelayedEventBusPushStrategy
/** /**
* An application event publisher subscriber which subscribes * An application event publisher subscriber which subscribes
* {@link EntityIdEvent} from the repository to dispatch these events to the * {@link EntityIdEvent} from the repository to dispatch these events to the
* UI {@link SessionEventBus} . * UI {@link UIEventBus} .
* *
* @param applicationEvent * @param applicationEvent
* the entity event which has been published from the repository * the entity event which has been published from the repository

View File

@@ -8,12 +8,10 @@
*/ */
package org.eclipse.hawkbit.ui.rollout; package org.eclipse.hawkbit.ui.rollout;
import java.util.Arrays;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
@@ -26,6 +24,7 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.AbstractEventListenersAwareView;
import org.eclipse.hawkbit.ui.common.CommonUiDependencies; import org.eclipse.hawkbit.ui.common.CommonUiDependencies;
import org.eclipse.hawkbit.ui.common.event.EventLayout; import org.eclipse.hawkbit.ui.common.event.EventLayout;
import org.eclipse.hawkbit.ui.common.event.EventView; import org.eclipse.hawkbit.ui.common.event.EventView;
@@ -40,18 +39,16 @@ import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventBus.UIEventBus;
import com.vaadin.navigator.View;
import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.SpringView;
import com.vaadin.spring.annotation.UIScope; import com.vaadin.spring.annotation.UIScope;
import com.vaadin.ui.Alignment; import com.vaadin.ui.Alignment;
import com.vaadin.ui.VerticalLayout;
/** /**
* Rollout management view. * Rollout management view.
*/ */
@UIScope @UIScope
@SpringView(name = RolloutView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = RolloutView.VIEW_NAME, ui = AbstractHawkbitUI.class)
public class RolloutView extends VerticalLayout implements View { public class RolloutView extends AbstractEventListenersAwareView {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "rollout"; public static final String VIEW_NAME = "rollout";
@@ -74,8 +71,8 @@ public class RolloutView extends VerticalLayout implements View {
final SystemSecurityContext systemSecurityContext) { final SystemSecurityContext systemSecurityContext) {
this.rolloutManagementUIState = rolloutManagementUIState; this.rolloutManagementUIState = rolloutManagementUIState;
final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus, uiNotification, final CommonUiDependencies uiDependencies = new CommonUiDependencies(i18n, entityFactory, eventBus,
permissionChecker); uiNotification, permissionChecker);
this.rolloutsLayout = new RolloutGridLayout(uiDependencies, rolloutManagementUIState, rolloutManagement, this.rolloutsLayout = new RolloutGridLayout(uiDependencies, rolloutManagementUIState, rolloutManagement,
targetManagement, uiProperties, targetFilterQueryManagement, rolloutGroupManagement, quotaManagement, targetManagement, uiProperties, targetFilterQueryManagement, rolloutGroupManagement, quotaManagement,
@@ -85,6 +82,8 @@ public class RolloutView extends VerticalLayout implements View {
this.rolloutGroupTargetsLayout = new RolloutGroupTargetGridLayout(uiDependencies, rolloutGroupManagement, this.rolloutGroupTargetsLayout = new RolloutGroupTargetGridLayout(uiDependencies, rolloutGroupManagement,
rolloutManagementUIState); rolloutManagementUIState);
addEventAwareLayouts(Arrays.asList(rolloutsLayout, rolloutGroupsLayout, rolloutGroupTargetsLayout));
final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class); final Map<EventLayout, VisibilityHandler> layoutVisibilityHandlers = new EnumMap<>(EventLayout.class);
layoutVisibilityHandlers.put(EventLayout.ROLLOUT_LIST, layoutVisibilityHandlers.put(EventLayout.ROLLOUT_LIST,
new VisibilityHandler(this::showRolloutListLayout, this::showRolloutGroupListLayout)); new VisibilityHandler(this::showRolloutListLayout, this::showRolloutGroupListLayout));
@@ -96,13 +95,8 @@ public class RolloutView extends VerticalLayout implements View {
layoutVisibilityHandlers); layoutVisibilityHandlers);
} }
@PostConstruct @Override
void init() { protected void buildLayout() {
buildLayout();
restoreState();
}
private void buildLayout() {
setSpacing(false); setSpacing(false);
setMargin(false); setMargin(false);
setSizeFull(); setSizeFull();
@@ -152,7 +146,8 @@ public class RolloutView extends VerticalLayout implements View {
rolloutGroupTargetsLayout.setVisible(true); rolloutGroupTargetsLayout.setVisible(true);
} }
private void restoreState() { @Override
protected void restoreState() {
final EventLayout layout = rolloutManagementUIState.getCurrentLayout().orElse(EventLayout.ROLLOUT_LIST); final EventLayout layout = rolloutManagementUIState.getCurrentLayout().orElse(EventLayout.ROLLOUT_LIST);
switch (layout) { switch (layout) {
case ROLLOUT_LIST: case ROLLOUT_LIST:
@@ -168,17 +163,25 @@ public class RolloutView extends VerticalLayout implements View {
break; break;
} }
rolloutsLayout.restoreState(); super.restoreState();
rolloutGroupsLayout.restoreState();
rolloutGroupTargetsLayout.restoreState();
} }
@PreDestroy @Override
void destroy() { public String getViewName() {
return RolloutView.VIEW_NAME;
}
@Override
protected void subscribeListeners() {
layoutVisibilityListener.subscribe();
super.subscribeListeners();
}
@Override
protected void unsubscribeListeners() {
layoutVisibilityListener.unsubscribe(); layoutVisibilityListener.unsubscribe();
rolloutsLayout.unsubscribeListener(); super.unsubscribeListeners();
rolloutGroupsLayout.unsubscribeListener();
rolloutGroupTargetsLayout.unsubscribeListener();
} }
} }

View File

@@ -244,7 +244,7 @@ public class RolloutGrid extends AbstractGrid<ProxyRollout, String> {
} }
private void updateGridItem(final Rollout rollout) { private void updateGridItem(final Rollout rollout) {
final ProxyRollout proxyRollout = RolloutToProxyRolloutMapper.mapRollout(rollout); final ProxyRollout proxyRollout = rolloutMapper.map(rollout);
if (rollout.getRolloutGroupsCreated() == 0) { if (rollout.getRolloutGroupsCreated() == 0) {
final Long groupsCount = rolloutGroupManagement.countByRollout(rollout.getId()); final Long groupsCount = rolloutGroupManagement.countByRollout(rollout.getId());
@@ -359,6 +359,10 @@ public class RolloutGrid extends AbstractGrid<ProxyRollout, String> {
getSelectionSupport().sendSelectionChangedEvent(SelectionChangedEventType.ENTITY_SELECTED, rollout); getSelectionSupport().sendSelectionChangedEvent(SelectionChangedEventType.ENTITY_SELECTED, rollout);
rolloutManagementUIState.setSelectedRolloutName(rollout.getName()); rolloutManagementUIState.setSelectedRolloutName(rollout.getName());
showRolloutGroupListLayout();
}
private void showRolloutGroupListLayout() {
eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this, new LayoutVisibilityEventPayload( eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this, new LayoutVisibilityEventPayload(
VisibilityType.SHOW, EventLayout.ROLLOUT_GROUP_LIST, EventView.ROLLOUT)); VisibilityType.SHOW, EventLayout.ROLLOUT_GROUP_LIST, EventView.ROLLOUT));
} }
@@ -428,14 +432,36 @@ public class RolloutGrid extends AbstractGrid<ProxyRollout, String> {
uiNotification.displayWarning( uiNotification.displayWarning(
i18n.getMessage("rollout.not.exists", rolloutManagementUIState.getSelectedRolloutName())); i18n.getMessage("rollout.not.exists", rolloutManagementUIState.getSelectedRolloutName()));
showRolloutListLayout(); final EventLayout currentLayout = rolloutManagementUIState.getCurrentLayout().orElse(null);
if (currentLayout == null || currentLayout != EventLayout.ROLLOUT_LIST) {
showRolloutListLayout();
}
} }
private void showRolloutListLayout() { private void showRolloutListLayout() {
if (rolloutManagementUIState.getCurrentLayout().map(currentLayout -> currentLayout != EventLayout.ROLLOUT_LIST) eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this,
.orElse(true)) { new LayoutVisibilityEventPayload(VisibilityType.SHOW, EventLayout.ROLLOUT_LIST, EventView.ROLLOUT));
eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this, }
new LayoutVisibilityEventPayload(VisibilityType.SHOW, EventLayout.ROLLOUT_LIST, EventView.ROLLOUT));
/**
* Re-fetches and re-selects currently selected rollout in order to update
* details layouts.
*
*/
public void reselectCurrentRollout() {
final Long selectedRolloutId = rolloutManagementUIState.getSelectedRolloutId();
if (selectedRolloutId == null) {
return;
}
final Optional<ProxyRollout> refetchedRollout = mapIdToProxyEntity(selectedRolloutId);
refetchedRollout.ifPresent(rollout -> {
getSelectionSupport().sendSelectionChangedEvent(SelectionChangedEventType.ENTITY_SELECTED, rollout);
rolloutManagementUIState.setSelectedRolloutName(rollout.getName());
});
if (!refetchedRollout.isPresent()) {
onSelectedRolloutDeleted(selectedRolloutId);
} }
} }
} }

View File

@@ -72,9 +72,10 @@ public class RolloutGridLayout extends AbstractGridComponentLayout {
* @param systemSecurityContext * @param systemSecurityContext
* SystemSecurityContext * SystemSecurityContext
*/ */
public RolloutGridLayout(final CommonUiDependencies uiDependencies, final RolloutManagementUIState rolloutManagementUIState, public RolloutGridLayout(final CommonUiDependencies uiDependencies,
final RolloutManagement rolloutManagement, final TargetManagement targetManagement, final RolloutManagementUIState rolloutManagementUIState, final RolloutManagement rolloutManagement,
final UiProperties uiProperties, final TargetFilterQueryManagement targetFilterQueryManagement, final TargetManagement targetManagement, final UiProperties uiProperties,
final TargetFilterQueryManagement targetFilterQueryManagement,
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement, final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
final TenantConfigurationManagement tenantConfigManagement, final TenantConfigurationManagement tenantConfigManagement,
final DistributionSetManagement distributionSetManagement, final DistributionSetManagement distributionSetManagement,
@@ -89,10 +90,12 @@ public class RolloutGridLayout extends AbstractGridComponentLayout {
this.rolloutListGrid = new RolloutGrid(uiDependencies, rolloutManagement, rolloutGroupManagement, this.rolloutListGrid = new RolloutGrid(uiDependencies, rolloutManagement, rolloutGroupManagement,
rolloutManagementUIState, tenantConfigManagement, rolloutWindowBuilder, systemSecurityContext); rolloutManagementUIState, tenantConfigManagement, rolloutWindowBuilder, systemSecurityContext);
final EventViewAware viewAware = new EventViewAware(EventView.ROLLOUT);
this.rolloutFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyRollout.class, this.rolloutFilterListener = new FilterChangedListener<>(uiDependencies.getEventBus(), ProxyRollout.class,
new EventViewAware(EventView.ROLLOUT), rolloutListGrid.getFilterSupport()); viewAware, rolloutListGrid.getFilterSupport());
this.rolloutModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), ProxyRollout.class) this.rolloutModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
.entityModifiedAwareSupports(getRolloutModifiedAwareSupports()).build(); ProxyRollout.class).viewAware(viewAware).entityModifiedAwareSupports(getRolloutModifiedAwareSupports())
.build();
buildLayout(rolloutListHeader, rolloutListGrid); buildLayout(rolloutListHeader, rolloutListGrid);
} }
@@ -104,18 +107,25 @@ public class RolloutGridLayout extends AbstractGridComponentLayout {
rolloutListGrid::mapIdToProxyEntity, rolloutListGrid::onSelectedRolloutDeleted)); rolloutListGrid::mapIdToProxyEntity, rolloutListGrid::onSelectedRolloutDeleted));
} }
/** @Override
* Restore the rollout grid state
*/
public void restoreState() { public void restoreState() {
rolloutListHeader.restoreState(); rolloutListHeader.restoreState();
rolloutListGrid.restoreState(); rolloutListGrid.restoreState();
} }
/** @Override
* unsubscribe all listener public void onViewEnter() {
*/ rolloutListGrid.reselectCurrentRollout();
public void unsubscribeListener() { }
@Override
public void subscribeListeners() {
rolloutFilterListener.subscribe();
rolloutModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
rolloutFilterListener.unsubscribe(); rolloutFilterListener.unsubscribe();
rolloutModifiedListener.unsubscribe(); rolloutModifiedListener.unsubscribe();
} }

View File

@@ -163,6 +163,10 @@ public class RolloutGroupGrid extends AbstractGrid<ProxyRolloutGroup, Long> {
getSelectionSupport().sendSelectionChangedEvent(SelectionChangedEventType.ENTITY_SELECTED, rolloutGroup); getSelectionSupport().sendSelectionChangedEvent(SelectionChangedEventType.ENTITY_SELECTED, rolloutGroup);
rolloutManagementUIState.setSelectedRolloutGroupName(rolloutGroup.getName()); rolloutManagementUIState.setSelectedRolloutGroupName(rolloutGroup.getName());
showRolloutGroupTargetsListLayout();
}
private void showRolloutGroupTargetsListLayout() {
eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this, new LayoutVisibilityEventPayload( eventBus.publish(CommandTopics.CHANGE_LAYOUT_VISIBILITY, this, new LayoutVisibilityEventPayload(
VisibilityType.SHOW, EventLayout.ROLLOUT_GROUP_TARGET_LIST, EventView.ROLLOUT)); VisibilityType.SHOW, EventLayout.ROLLOUT_GROUP_TARGET_LIST, EventView.ROLLOUT));
} }
@@ -179,8 +183,7 @@ public class RolloutGroupGrid extends AbstractGrid<ProxyRolloutGroup, Long> {
} }
private void updateGridItem(final RolloutGroup rolloutGroup) { private void updateGridItem(final RolloutGroup rolloutGroup) {
final ProxyRolloutGroup proxyRolloutGroup = RolloutGroupToProxyRolloutGroupMapper.mapGroup(rolloutGroup); getDataProvider().refreshItem(rolloutGroupMapper.map(rolloutGroup));
getDataProvider().refreshItem(proxyRolloutGroup);
} }
@Override @Override

View File

@@ -50,19 +50,21 @@ public class RolloutGroupGridLayout extends AbstractGridComponentLayout {
* @param rolloutManagementUIState * @param rolloutManagementUIState
* UIState * UIState
*/ */
public RolloutGroupGridLayout(final CommonUiDependencies uiDependencies, final RolloutGroupManagement rolloutGroupManagement, public RolloutGroupGridLayout(final CommonUiDependencies uiDependencies,
final RolloutGroupManagement rolloutGroupManagement,
final RolloutManagementUIState rolloutManagementUIState) { final RolloutManagementUIState rolloutManagementUIState) {
this.rolloutGroupsListHeader = new RolloutGroupGridHeader(uiDependencies, rolloutManagementUIState); this.rolloutGroupsListHeader = new RolloutGroupGridHeader(uiDependencies, rolloutManagementUIState);
this.rolloutGroupListGrid = new RolloutGroupGrid(uiDependencies, rolloutGroupManagement, rolloutManagementUIState); this.rolloutGroupListGrid = new RolloutGroupGrid(uiDependencies, rolloutGroupManagement,
rolloutManagementUIState);
final EventLayoutViewAware masterLayoutView = new EventLayoutViewAware(EventLayout.ROLLOUT_LIST, final EventLayoutViewAware masterLayoutView = new EventLayoutViewAware(EventLayout.ROLLOUT_LIST,
EventView.ROLLOUT); EventView.ROLLOUT);
this.masterEntityChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(),
this.masterEntityChangedListener = new SelectionChangedListener<>(uiDependencies.getEventBus(), masterLayoutView, masterLayoutView, getMasterEntityAwareComponents());
getMasterEntityAwareComponents());
this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(), this.entityModifiedListener = new EntityModifiedListener.Builder<>(uiDependencies.getEventBus(),
ProxyRolloutGroup.class).entityModifiedAwareSupports(getEntityModifiedAwareSupports()) ProxyRolloutGroup.class).parentEntityType(ProxyRollout.class)
.parentEntityType(ProxyRollout.class).parentEntityIdProvider(this::getMasterEntityId).build(); .parentEntityIdProvider(this::getMasterEntityId).viewAware(masterLayoutView)
.entityModifiedAwareSupports(getEntityModifiedAwareSupports()).build();
buildLayout(rolloutGroupsListHeader, rolloutGroupListGrid); buildLayout(rolloutGroupsListHeader, rolloutGroupListGrid);
} }
@@ -83,18 +85,20 @@ public class RolloutGroupGridLayout extends AbstractGridComponentLayout {
return Optional.ofNullable(rolloutGroupListGrid.getMasterEntitySupport().getMasterId()); return Optional.ofNullable(rolloutGroupListGrid.getMasterEntitySupport().getMasterId());
} }
/** @Override
* Restore the rollout group grid list state
*/
public void restoreState() { public void restoreState() {
rolloutGroupsListHeader.restoreState(); rolloutGroupsListHeader.restoreState();
rolloutGroupListGrid.restoreState(); rolloutGroupListGrid.restoreState();
} }
/** @Override
* Unsubscribe the event listener public void subscribeListeners() {
*/ masterEntityChangedListener.subscribe();
public void unsubscribeListener() { entityModifiedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
masterEntityChangedListener.unsubscribe(); masterEntityChangedListener.unsubscribe();
entityModifiedListener.unsubscribe(); entityModifiedListener.unsubscribe();
} }

View File

@@ -80,18 +80,20 @@ public class RolloutGroupTargetGridLayout extends AbstractGridComponentLayout {
return Arrays.asList(rolloutGroupTargetsListHeader, rolloutGroupTargetsListGrid.getMasterEntitySupport()); return Arrays.asList(rolloutGroupTargetsListHeader, rolloutGroupTargetsListGrid.getMasterEntitySupport());
} }
/** @Override
* Restore the rollout group target list state
*/
public void restoreState() { public void restoreState() {
rolloutGroupTargetsListHeader.restoreState(); rolloutGroupTargetsListHeader.restoreState();
rolloutGroupTargetsListGrid.restoreState(); rolloutGroupTargetsListGrid.restoreState();
} }
/** @Override
* unsubscribe all listener public void subscribeListeners() {
*/ rolloutChangedListener.subscribe();
public void unsubscribeListener() { rolloutGroupChangedListener.subscribe();
}
@Override
public void unsubscribeListeners() {
rolloutChangedListener.unsubscribe(); rolloutChangedListener.unsubscribe();
rolloutGroupChangedListener.unsubscribe(); rolloutGroupChangedListener.unsubscribe();
} }

View File

@@ -77,11 +77,11 @@ public class RolloutFormLayout extends ValidatableLayout {
* Constructor for RolloutFormLayout * Constructor for RolloutFormLayout
* *
* @param i18n * @param i18n
* VaadinMessageSource * VaadinMessageSource
* @param distributionSetDataProvider * @param distributionSetDataProvider
* DistributionSetStatelessDataProvider * DistributionSetStatelessDataProvider
* @param targetFilterQueryDataProvider * @param targetFilterQueryDataProvider
* TargetFilterQueryDataProvider * TargetFilterQueryDataProvider
*/ */
public RolloutFormLayout(final VaadinMessageSource i18n, public RolloutFormLayout(final VaadinMessageSource i18n,
final DistributionSetStatelessDataProvider distributionSetDataProvider, final DistributionSetStatelessDataProvider distributionSetDataProvider,
@@ -206,7 +206,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* Add rollout form to add layout * Add rollout form to add layout
* *
* @param layout * @param layout
* Grid layout * Grid layout
*/ */
public void addFormToAddLayout(final GridLayout layout) { public void addFormToAddLayout(final GridLayout layout) {
targetFilterQueryField.unbind(); targetFilterQueryField.unbind();
@@ -218,7 +218,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* Add rollout form to edit layout * Add rollout form to edit layout
* *
* @param layout * @param layout
* Grid layout * Grid layout
*/ */
public void addFormToEditLayout(final GridLayout layout) { public void addFormToEditLayout(final GridLayout layout) {
targetFilterQueryCombo.unbind(); targetFilterQueryCombo.unbind();
@@ -252,6 +252,7 @@ public class RolloutFormLayout extends ValidatableLayout {
*/ */
public void disableFieldsOnEditForInActive() { public void disableFieldsOnEditForInActive() {
targetFilterQueryField.getComponent().setEnabled(false); targetFilterQueryField.getComponent().setEnabled(false);
dsCombo.setEnabled(false);
} }
/** /**
@@ -260,7 +261,6 @@ public class RolloutFormLayout extends ValidatableLayout {
public void disableFieldsOnEditForActive() { public void disableFieldsOnEditForActive() {
disableFieldsOnEditForInActive(); disableFieldsOnEditForInActive();
dsCombo.setEnabled(false);
actionTypeLayout.getComponent().setEnabled(false); actionTypeLayout.getComponent().setEnabled(false);
autoStartOptionGroupLayout.getComponent().setEnabled(false); autoStartOptionGroupLayout.getComponent().setEnabled(false);
} }
@@ -279,7 +279,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* Sets the changed listener for filter query * Sets the changed listener for filter query
* *
* @param filterQueryChangedListener * @param filterQueryChangedListener
* Changed listener * Changed listener
*/ */
public void setFilterQueryChangedListener(final Consumer<String> filterQueryChangedListener) { public void setFilterQueryChangedListener(final Consumer<String> filterQueryChangedListener) {
this.filterQueryChangedListener = filterQueryChangedListener; this.filterQueryChangedListener = filterQueryChangedListener;
@@ -289,7 +289,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* Sets the count of total targets * Sets the count of total targets
* *
* @param totalTargets * @param totalTargets
* Total targets * Total targets
*/ */
public void setTotalTargets(final Long totalTargets) { public void setTotalTargets(final Long totalTargets) {
this.totalTargets = totalTargets; this.totalTargets = totalTargets;
@@ -301,7 +301,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* Sets the rollout form bean in binder * Sets the rollout form bean in binder
* *
* @param bean * @param bean
* ProxyRolloutForm * ProxyRolloutForm
*/ */
public void setBean(final ProxyRolloutForm bean) { public void setBean(final ProxyRolloutForm bean) {
rolloutId = bean.getId(); rolloutId = bean.getId();
@@ -312,7 +312,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* @return Updated rollout form bean * @return Updated rollout form bean
* *
* @throws ValidationException * @throws ValidationException
* ValidationException * ValidationException
*/ */
public ProxyRolloutForm getBean() throws ValidationException { public ProxyRolloutForm getBean() throws ValidationException {
final ProxyRolloutForm bean = new ProxyRolloutForm(); final ProxyRolloutForm bean = new ProxyRolloutForm();

View File

@@ -15,6 +15,7 @@ import javax.annotation.PostConstruct;
import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.AbstractHawkbitUI;
import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.ViewNameAware;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxySystemConfigWindow; import org.eclipse.hawkbit.ui.common.data.proxies.ProxySystemConfigWindow;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder;
@@ -44,7 +45,8 @@ import com.vaadin.ui.VerticalLayout;
*/ */
@ViewScope @ViewScope
@SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = AbstractHawkbitUI.class) @SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = AbstractHawkbitUI.class)
public class TenantConfigurationDashboardView extends CustomComponent implements View, ConfigurationItemChangeListener { public class TenantConfigurationDashboardView extends CustomComponent
implements View, ViewNameAware, ConfigurationItemChangeListener {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "spSystemConfig"; public static final String VIEW_NAME = "spSystemConfig";
@@ -163,4 +165,8 @@ public class TenantConfigurationDashboardView extends CustomComponent implements
// This view is constructed in the init() method() // This view is constructed in the init() method()
} }
@Override
public String getViewName() {
return TenantConfigurationDashboardView.VIEW_NAME;
}
} }

View File

@@ -106,6 +106,7 @@ caption.artifact.details.of = Artifact Details of
caption.action.states= Action States caption.action.states= Action States
caption.action.messages = Messages caption.action.messages = Messages
caption.error = Error caption.error = Error
caption.entity.missing.error = Entity is missing
caption.new.softwaremodule.application = Configure New Application caption.new.softwaremodule.application = Configure New Application
caption.new.softwaremodule.os = Configure New OS caption.new.softwaremodule.os = Configure New OS
caption.filter.simple = Simple Filter caption.filter.simple = Simple Filter
@@ -209,11 +210,11 @@ label.target.filter.count = Total Targets
label.filter.selected = Selected: label.filter.selected = Selected:
label.filter.shown = Shown: label.filter.shown = Shown:
label.filter.targets = Filtered Targets: label.filter.targets = Filtered Targets:
label.filter.status = Status, label.filter.status = Status
label.filter.overdue = Overdue, label.filter.overdue = Overdue
label.filter.tags = Tags, label.filter.tags = Tags
label.filter.text = Search Text label.filter.text = Search Text
label.filter.dist = Distribution, label.filter.dist = Distribution
label.filter.custom = Custom label.filter.custom = Custom
label.target.filter.truncated={0} targets has been truncated in the list due the target size limit of {1}, use filters to reduce the targets to be shown label.target.filter.truncated={0} targets has been truncated in the list due the target size limit of {1}, use filters to reduce the targets to be shown
label.unknown = Unknown label.unknown = Unknown
@@ -768,7 +769,8 @@ controller.polling.title=Polling Configuration
controller.polling.time=Polling Time controller.polling.time=Polling Time
# entity not exist # entity not exist
rollout.not.exists=Rollout {0} does not exist. Maybe the rollout was deleted. rollout.not.exists=Rollout {0} does not exist. Maybe the it was deleted.
rollout.group.not.exists=Rollout Group {0} does not exist. Maybe the it was deleted.
color.not.exists=There is no mapping for the provided colour {0} color.not.exists=There is no mapping for the provided colour {0}
caption.entity.target.tag = Target Tag caption.entity.target.tag = Target Tag