diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 070854990..da5655046 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -202,10 +202,10 @@ public interface TargetManagement { void delete(@NotEmpty Collection targetIDs); /** - * Deletes target with the given IDs. + * Deletes target with the given controller ID. * * @param controllerID - * the ID of the targets to be deleted + * the controller ID of the target to be deleted * * @throws EntityNotFoundException * if target with given ID does not exist diff --git a/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch b/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch new file mode 100644 index 000000000..149f30ed0 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.eclipse.m2e.core.maven2Builder.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.sonarlint.eclipse.core.sonarlintBuilder.launch b/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.sonarlint.eclipse.core.sonarlintBuilder.launch new file mode 100644 index 000000000..58946ee5c --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/.externalToolBuilders/org.sonarlint.eclipse.core.sonarlintBuilder.launch @@ -0,0 +1,7 @@ + + + + + + + diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java index 65b0b6da1..dfed2079f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui; import org.eclipse.hawkbit.ui.menu.DashboardMenu; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.beans.factory.annotation.Autowired; @@ -64,7 +64,7 @@ public class ErrorView extends VerticalLayout implements View { final Notification nt = new Notification("Access denied", i18n.getMessage("message.accessdenied.view", new Object[] { event.getViewName() }), Type.ERROR_MESSAGE, false); - nt.setStyleName(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE); + nt.setStyleName(SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE); nt.setPosition(Position.BOTTOM_RIGHT); nt.show(UI.getCurrent().getPage()); message.setValue(i18n.getMessage("message.accessdenied.view", new Object[] { event.getViewName() })); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java index 6e55bf8cb..c5aae1a3a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java @@ -21,11 +21,11 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout; import org.eclipse.hawkbit.ui.artifacts.event.ArtifactDetailsEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.footer.SMDeleteActionsLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleTableLayout; -import org.eclipse.hawkbit.ui.artifacts.smtype.SMTypeFilterLayout; +import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterButtons; +import org.eclipse.hawkbit.ui.artifacts.smtype.filter.SMTypeFilterLayout; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.upload.UploadLayout; +import org.eclipse.hawkbit.ui.artifacts.upload.UploadDropAreaLayout; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -45,9 +45,7 @@ import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.UIScope; import com.vaadin.ui.Alignment; -import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.VerticalLayout; /** @@ -77,18 +75,12 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private final ArtifactDetailsLayout artifactDetailsLayout; - private final UploadLayout uploadLayout; - - private final SMDeleteActionsLayout deleteActionsLayout; + private final UploadDropAreaLayout dropAreaLayout; private VerticalLayout detailAndUploadLayout; - private HorizontalLayout uplaodButtonsLayout; - private GridLayout mainLayout; - private DragAndDropWrapper dadw; - @Autowired UploadArtifactView(final UIEventBus eventBus, final SpPermissionChecker permChecker, final VaadinMessageSource i18n, final UINotification uiNotification, final ArtifactUploadState artifactUploadState, @@ -101,17 +93,18 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW this.i18n = i18n; this.uiNotification = uiNotification; this.artifactUploadState = artifactUploadState; - this.filterByTypeLayout = new SMTypeFilterLayout(artifactUploadState, i18n, permChecker, eventBus, - entityFactory, uiNotification, softwareModuleTypeManagement, uploadViewClientCriterion); this.smTableLayout = new SoftwareModuleTableLayout(i18n, permChecker, artifactUploadState, uiNotification, eventBus, softwareModuleManagement, softwareModuleTypeManagement, entityFactory, uploadViewClientCriterion); this.artifactDetailsLayout = new ArtifactDetailsLayout(i18n, eventBus, artifactUploadState, uiNotification, artifactManagement, softwareModuleManagement); - this.uploadLayout = new UploadLayout(i18n, uiNotification, eventBus, artifactUploadState, - multipartConfigElement, artifactManagement, softwareModuleManagement); - this.deleteActionsLayout = new SMDeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, - artifactUploadState, softwareModuleManagement, softwareModuleTypeManagement, uploadViewClientCriterion); + final SMTypeFilterButtons smTypeFilterButtons = new SMTypeFilterButtons(eventBus, artifactUploadState, + uploadViewClientCriterion, softwareModuleTypeManagement, i18n, entityFactory, permChecker, + uiNotification); + this.filterByTypeLayout = new SMTypeFilterLayout(artifactUploadState, i18n, permChecker, eventBus, + entityFactory, uiNotification, softwareModuleTypeManagement, smTypeFilterButtons); + this.dropAreaLayout = new UploadDropAreaLayout(i18n, eventBus, uiNotification, artifactUploadState, + multipartConfigElement, softwareModuleManagement, artifactManagement); } @PostConstruct @@ -168,15 +161,13 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private VerticalLayout createDetailsAndUploadLayout() { detailAndUploadLayout = new VerticalLayout(); detailAndUploadLayout.addComponent(artifactDetailsLayout); - detailAndUploadLayout.setComponentAlignment(artifactDetailsLayout, Alignment.MIDDLE_CENTER); + detailAndUploadLayout.setComponentAlignment(artifactDetailsLayout, Alignment.TOP_CENTER); + detailAndUploadLayout.setExpandRatio(artifactDetailsLayout, 1.0F); if (permChecker.hasCreateRepositoryPermission()) { - dadw = uploadLayout.getDropAreaWrapper(); - detailAndUploadLayout.addComponent(dadw); - detailAndUploadLayout.setComponentAlignment(dadw, Alignment.MIDDLE_CENTER); + detailAndUploadLayout.addComponent(dropAreaLayout.getDropAreaWrapper()); } - detailAndUploadLayout.setExpandRatio(artifactDetailsLayout, 1.0F); detailAndUploadLayout.setSizeFull(); detailAndUploadLayout.addStyleName("group"); detailAndUploadLayout.setSpacing(true); @@ -185,28 +176,19 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private GridLayout createMainLayout() { createDetailsAndUploadLayout(); - createUploadButtonLayout(); - mainLayout = new GridLayout(3, 2); + mainLayout = new GridLayout(3, 1); mainLayout.setSizeFull(); mainLayout.setSpacing(true); + mainLayout.setStyleName("fullSize"); mainLayout.addComponent(filterByTypeLayout, 0, 0); mainLayout.addComponent(smTableLayout, 1, 0); mainLayout.addComponent(detailAndUploadLayout, 2, 0); - mainLayout.addComponent(deleteActionsLayout, 1, 1); - mainLayout.addComponent(uplaodButtonsLayout, 2, 1); + mainLayout.setRowExpandRatio(0, 1.0F); mainLayout.setColumnExpandRatio(1, 0.5F); mainLayout.setColumnExpandRatio(2, 0.5F); - mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); - mainLayout.setComponentAlignment(uplaodButtonsLayout, Alignment.BOTTOM_CENTER); - return mainLayout; - } - private void createUploadButtonLayout() { - uplaodButtonsLayout = new HorizontalLayout(); - if (permChecker.hasCreateRepositoryPermission()) { - uplaodButtonsLayout = uploadLayout.getFileUploadLayout(); - } + return mainLayout; } private void minimizeSwTable() { @@ -216,14 +198,13 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private void maximizeSwTable() { mainLayout.removeComponent(detailAndUploadLayout); - removeOtherComponents(); mainLayout.setColumnExpandRatio(1, 1F); mainLayout.setColumnExpandRatio(2, 0F); } private void minimizeArtifactoryDetails() { mainLayout.setSpacing(true); - detailAndUploadLayout.addComponent(dadw); + detailAndUploadLayout.addComponent(dropAreaLayout.getDropAreaWrapper()); mainLayout.addComponent(filterByTypeLayout, 0, 0); mainLayout.addComponent(smTableLayout, 1, 0); addOtherComponents(); @@ -233,24 +214,14 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW mainLayout.setSpacing(false); mainLayout.removeComponent(filterByTypeLayout); mainLayout.removeComponent(smTableLayout); - detailAndUploadLayout.removeComponent(dadw); - removeOtherComponents(); + detailAndUploadLayout.removeComponent(dropAreaLayout.getDropAreaWrapper()); mainLayout.setColumnExpandRatio(1, 0F); mainLayout.setColumnExpandRatio(2, 1F); } private void addOtherComponents() { - mainLayout.addComponent(deleteActionsLayout, 1, 1); - mainLayout.addComponent(uplaodButtonsLayout, 2, 1); mainLayout.setColumnExpandRatio(1, 0.5F); mainLayout.setColumnExpandRatio(2, 0.5F); - mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); - mainLayout.setComponentAlignment(uplaodButtonsLayout, Alignment.BOTTOM_CENTER); - } - - private void removeOtherComponents() { - mainLayout.removeComponent(deleteActionsLayout); - mainLayout.removeComponent(uplaodButtonsLayout); } private void checkNoDataAvaialble() { @@ -278,6 +249,7 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW public void enter(final ViewChangeEvent event) { smTableLayout.getSoftwareModuleTable() .selectEntity(artifactUploadState.getSelectedBaseSwModuleId().orElse(null)); + dropAreaLayout.getUploadButtonLayout().restoreState(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java index 7a9f3d733..ce318092e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.artifacts.details; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -27,7 +28,7 @@ import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -180,10 +181,9 @@ public class ArtifactDetailsLayout extends VerticalLayout { private SPUIButton createMaxMinButton() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(SPUIDefinitions.EXPAND_ACTION_HISTORY, - "", "", null, true, FontAwesome.EXPAND, SPUIButtonStyleSmallNoBorder.class); + "", "", null, true, FontAwesome.EXPAND, SPUIButtonStyleNoBorder.class); button.addClickListener(event -> maxArtifactDetails()); return button; - } private void buildLayout() { @@ -267,31 +267,24 @@ public class ArtifactDetailsLayout extends VerticalLayout { final Button deleteIcon = SPUIComponentProvider.getButton( fileName + "-" + UIComponentIdProvider.UPLOAD_FILE_DELETE_ICON, "", SPUILabelDefinitions.DISCARD, ValoTheme.BUTTON_TINY + " " + "blueicon", true, - FontAwesome.TRASH_O, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TRASH_O, SPUIButtonStyleNoBorder.class); deleteIcon.setData(itemId); deleteIcon.addClickListener(event -> confirmAndDeleteArtifact((Long) itemId, fileName)); return deleteIcon; } }); - } private void confirmAndDeleteArtifact(final Long id, final String fileName) { final ConfirmationDialog confirmDialog = new ConfirmationDialog( i18n.getMessage("caption.delete.artifact.confirmbox"), - i18n.getMessage("message.delete.artifact", new Object[] { fileName }), i18n.getMessage("button.ok"), - i18n.getMessage("button.cancel"), ok -> { + i18n.getMessage("message.delete.artifact", new Object[] { fileName }), + i18n.getMessage(SPUIDefinitions.BUTTON_OK), i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (ok) { artifactManagement.delete(id); uINotification.displaySuccess(i18n.getMessage("message.artifact.deleted", fileName)); final Optional softwareModule = findSelectedSoftwareModule(); - if (softwareModule.isPresent()) { - populateArtifactDetails(softwareModule.get().getId(), - HawkbitCommonUtil.getFormattedNameVersion(softwareModule.get().getName(), - softwareModule.get().getVersion())); - } else { - populateArtifactDetails(null, null); - } + populateArtifactDetails(softwareModule.orElse(null)); } }); UI.getCurrent().addWindow(confirmDialog.getWindow()); @@ -299,7 +292,6 @@ public class ArtifactDetailsLayout extends VerticalLayout { } private void setTableColumnDetails(final Table table) { - table.setColumnHeader(PROVIDED_FILE_NAME, i18n.getMessage("upload.file.name")); table.setColumnHeader(SIZE, i18n.getMessage("upload.size")); if (fullWindowMode) { @@ -359,15 +351,13 @@ public class ArtifactDetailsLayout extends VerticalLayout { private void maxArtifactDetails() { final Boolean flag = (Boolean) maxMinButton.getData(); if (flag == null || Boolean.FALSE.equals(flag)) { - // Clicked on max Button maximizedArtifactDetailsView(); } else { - // Clicked on min Button - minimizeArtifactDetailsView(); + minimizedArtifactDetailsView(); } } - private void minimizeArtifactDetailsView() { + private void minimizedArtifactDetailsView() { fullWindowMode = Boolean.FALSE; showMaxIcon(); setTableColumnDetails(artifactDetailsTable); @@ -380,7 +370,6 @@ public class ArtifactDetailsLayout extends VerticalLayout { showMinIcon(); setTableColumnDetails(artifactDetailsTable); createArtifactDetailsMaxView(); - } /** @@ -398,7 +387,6 @@ public class ArtifactDetailsLayout extends VerticalLayout { } private void createArtifactDetailsMaxView() { - artifactDetailsTable.setValue(null); artifactDetailsTable.setSelectable(false); artifactDetailsTable.setMultiSelect(false); @@ -417,12 +405,19 @@ public class ArtifactDetailsLayout extends VerticalLayout { /** * Populate artifact details. * - * @param baseSwModuleId - * software module id - * @param swModuleName - * software module name + * @param softwareModule + * software module */ - public void populateArtifactDetails(final Long baseSwModuleId, final String swModuleName) { + public void populateArtifactDetails(final SoftwareModule softwareModule) { + if (softwareModule == null) { + populateArtifactDetails(null, null); + } else { + populateArtifactDetails(softwareModule.getId(), + HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())); + } + } + + private void populateArtifactDetails(final Long baseSwModuleId, final String swModuleName) { if (!readOnly) { if (StringUtils.isEmpty(swModuleName)) { setTitleOfLayoutHeader(); @@ -456,18 +451,35 @@ public class ArtifactDetailsLayout extends VerticalLayout { @EventBusListenerMethod(scope = EventScope.UI) void onEvent(final SoftwareModuleEvent softwareModuleEvent) { - if (softwareModuleEvent.getEventType() == BaseEntityEventType.SELECTED_ENTITY - || softwareModuleEvent.getSoftwareModuleEventType() == SoftwareModuleEventType.ARTIFACTS_CHANGED) { + if (softwareModuleEvent.getEventType() == BaseEntityEventType.SELECTED_ENTITY) { UI.getCurrent().access(() -> { if (softwareModuleEvent.getEntity() != null) { - populateArtifactDetails(softwareModuleEvent.getEntity().getId(), - HawkbitCommonUtil.getFormattedNameVersion(softwareModuleEvent.getEntity().getName(), - softwareModuleEvent.getEntity().getVersion())); + populateArtifactDetails(softwareModuleEvent.getEntity()); } else { populateArtifactDetails(null, null); } }); } + if (isArtifactChangedEvent(softwareModuleEvent) && areEntityIdsNotEmpty(softwareModuleEvent)) { + UI.getCurrent().access(() -> findSelectedSoftwareModule().ifPresent(selectedSoftwareModule -> { + if (hasSelectedSoftwareModuleChanged(softwareModuleEvent.getEntityIds(), selectedSoftwareModule)) { + populateArtifactDetails(selectedSoftwareModule); + } + })); + } + } + + private static boolean areEntityIdsNotEmpty(final SoftwareModuleEvent softwareModuleEvent) { + return softwareModuleEvent.getEntityIds() != null && !softwareModuleEvent.getEntityIds().isEmpty(); + } + + private static boolean isArtifactChangedEvent(final SoftwareModuleEvent softwareModuleEvent) { + return softwareModuleEvent.getSoftwareModuleEventType() == SoftwareModuleEventType.ARTIFACTS_CHANGED; + } + + private static boolean hasSelectedSoftwareModuleChanged(final Collection changedSoftwareModuleIds, + final SoftwareModule selectedSoftwareModule) { + return changedSoftwareModuleIds.stream().anyMatch(smId -> selectedSoftwareModule.getId().equals(smId)); } public Table getArtifactDetailsTable() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java index e8e5060b9..8b8c6791f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.ui.artifacts.event; +import java.util.Arrays; import java.util.Collection; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -78,6 +79,19 @@ public class SoftwareModuleEvent extends BaseUIEntityEvent { this.softwareModuleEventType = softwareModuleEventType; } + /** + * Creates software module event. + * + * @param softwareModuleEventType + * the event type + * @param softwareModuleId + * the id of the {@link SoftwareModule} + */ + public SoftwareModuleEvent(final SoftwareModuleEventType softwareModuleEventType, final long softwareModuleId) { + super(null, Arrays.asList(softwareModuleId), SoftwareModule.class); + this.softwareModuleEventType = softwareModuleEventType; + } + public SoftwareModuleEventType getSoftwareModuleEventType() { return softwareModuleEventType; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java index aedb8830b..25dd93a73 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java @@ -19,7 +19,7 @@ public class SoftwareModuleTypeEvent { * Software module type events in the Upload UI. */ public enum SoftwareModuleTypeEnum { - ADD_SOFTWARE_MODULE_TYPE, DELETE_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE + ADD_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE } private SoftwareModuleType softwareModuleType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java index f96db0082..8f4f526c6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadArtifactUIEvent.java @@ -15,5 +15,5 @@ package org.eclipse.hawkbit.ui.artifacts.event; * */ public enum UploadArtifactUIEvent { - SHOW_DROP_HINTS, HIDE_DROP_HINTS, SOFTWARE_DRAG_START, SOFTWARE_TYPE_DRAG_START, UPDATE_UPLOAD_COUNT, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFWARE, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFWARE_TYPE, MINIMIZED_STATUS_POPUP, MAXIMIZED_STATUS_POPUP, UPLOAD_IN_PROGESS, ARTIFACT_RESULT_POPUP_CLOSED + HIDE_DROP_HINTS, HIDE_FILTER_BY_TYPE, SHOW_FILTER_BY_TYPE, DISCARD_DELETE_SOFTWARE, DISCARD_ALL_DELETE_SOFTWARE, DELETED_ALL_SOFTWARE, DISCARD_DELETE_SOFTWARE_TYPE, DISCARD_ALL_DELETE_SOFTWARE_TYPE, DELETED_ALL_SOFTWARE_TYPE } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java deleted file mode 100644 index 5d432ff04..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadFileStatus.java +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.event; - -import java.io.Serializable; - -import org.eclipse.hawkbit.repository.model.SoftwareModule; - -/** - * - * Holds file and upload status details.Meta data sent with upload events. - * - */ -public class UploadFileStatus implements Serializable { - - private static final long serialVersionUID = -3599629192216760811L; - - private final String fileName; - - private long contentLength; - - private long bytesRead; - - private String failureReason; - - private SoftwareModule softwareModule; - - /** - * constructor for UploadFileStatus - * - * @param fileName - * name of the file to be uploaded - */ - public UploadFileStatus(final String fileName) { - this.fileName = fileName; - } - - /** - * constructor for UploadFileStatus - * - * @param fileName - * name of the file to be uploaded - * @param bytesRead - * number of bytes - * @param contentLength - * length of the content (stream) - * @param softwareModule - * softwareModule - */ - public UploadFileStatus(final String fileName, final long bytesRead, final long contentLength, - final SoftwareModule softwareModule) { - this.fileName = fileName; - this.contentLength = contentLength; - this.bytesRead = bytesRead; - this.softwareModule = softwareModule; - } - - /** - * constructor for UploadFileStatus - * - * @param fileName - * name of the file to be uploaded - * @param failureReason - * reason of failure - * @param selectedSw - * the selected softwareModule - */ - public UploadFileStatus(final String fileName, final String failureReason, final SoftwareModule selectedSw) { - this.failureReason = failureReason; - this.fileName = fileName; - this.softwareModule = selectedSw; - } - - public String getFileName() { - return fileName; - } - - public long getContentLength() { - return contentLength; - } - - public long getBytesRead() { - return bytesRead; - } - - public String getFailureReason() { - return failureReason; - } - - public SoftwareModule getSoftwareModule() { - return softwareModule; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java deleted file mode 100644 index cc6b3ca5c..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadStatusEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.event; - -/** - * - * Holds the upload file status. - * - */ -public class UploadStatusEvent { - - /** - * TenantAwareEvent type definition of events during the artifact upload - * life-cycle from receiving the upload until the process end. - */ - public enum UploadStatusEventType { - RECEIVE_UPLOAD, UPLOAD_FAILED, UPLOAD_IN_PROGRESS, UPLOAD_STARTED, UPLOAD_FINISHED, UPLOAD_SUCCESSFUL, UPLOAD_STREAMING_FAILED, UPLOAD_STREAMING_FINISHED, ABORT_UPLOAD - } - - private final UploadStatusEventType uploadProgressEventType; - - private UploadFileStatus uploadStatus; - - /** - * Constructor. - * - * @param eventType - * the type of the event - * @param uploadStatus - * the upload status of this event - */ - public UploadStatusEvent(final UploadStatusEventType eventType, final UploadFileStatus uploadStatus) { - this.uploadProgressEventType = eventType; - this.uploadStatus = uploadStatus; - } - - public UploadFileStatus getUploadStatus() { - return uploadStatus; - } - - public void setUploadStatus(final UploadFileStatus uploadStatus) { - this.uploadStatus = uploadStatus; - } - - public UploadStatusEventType getUploadProgressEventType() { - return uploadProgressEventType; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java deleted file mode 100644 index 4d95c2e16..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.footer; - -import java.util.Set; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout; -import org.eclipse.hawkbit.ui.common.table.AbstractTable; -import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.ui.Component; -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.TableTransferable; -import com.vaadin.ui.UI; - -/** - * Upload view footer layout implementation. - */ -public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout { - - private static final long serialVersionUID = -3273982053389866299L; - - private final ArtifactUploadState artifactUploadState; - - private final UploadViewConfirmationWindowLayout uploadViewConfirmationWindowLayout; - - private final UploadViewClientCriterion uploadViewClientCriterion; - - public SMDeleteActionsLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, - final UIEventBus eventBus, final UINotification notification, final ArtifactUploadState artifactUploadState, - final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final UploadViewClientCriterion uploadViewClientCriterion) { - super(i18n, permChecker, eventBus, notification); - this.artifactUploadState = artifactUploadState; - this.uploadViewConfirmationWindowLayout = new UploadViewConfirmationWindowLayout(i18n, eventBus, - softwareModuleManagement, softwareModuleTypeManagement, artifactUploadState); - this.uploadViewClientCriterion = uploadViewClientCriterion; - - init(); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadArtifactUIEvent event) { - - if (isSoftwareEvent(event) || isSoftwareTypeEvent(event)) { - - UI.getCurrent().access(() -> { - if (!hasUnsavedActions()) { - closeUnsavedActionsWindow(); - final String message = uploadViewConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - } - updateSWActionCount(); - }); - } - } - - private boolean isSoftwareEvent(final UploadArtifactUIEvent event) { - return event == UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE - || event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE - || event == UploadArtifactUIEvent.DISCARD_DELETE_SOFTWARE; - } - - private boolean isSoftwareTypeEvent(final UploadArtifactUIEvent event) { - return event == UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE_TYPE - || event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE_TYPE - || event == UploadArtifactUIEvent.DISCARD_DELETE_SOFTWARE_TYPE; - } - - @Override - protected boolean hasDeletePermission() { - return permChecker.hasDeleteRepositoryPermission(); - } - - @Override - protected boolean hasUpdatePermission() { - /** - * Footer layout should be displayed only when software modeule has - * delete permission.So update permission need not be checked in this - * case. - */ - return false; - } - - @Override - protected String getDeleteAreaLabel() { - return i18n.getMessage("label.software.module.drop.area"); - } - - @Override - protected String getDeleteAreaId() { - return UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID; - } - - @Override - protected AcceptCriterion getDeleteLayoutAcceptCriteria() { - return uploadViewClientCriterion; - } - - @Override - protected void processDroppedComponent(final DragAndDropEvent event) { - final Component sourceComponent = event.getTransferable().getSourceComponent(); - if (sourceComponent instanceof Table) { - final Table sourceTable = (Table) event.getTransferable().getSourceComponent(); - addToDeleteList(sourceTable, (TableTransferable) event.getTransferable()); - updateSWActionCount(); - } - if (sourceComponent.getId().startsWith(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)) { - - final String swModuleTypeName = sourceComponent.getId() - .replace(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX, ""); - if (artifactUploadState.getSoftwareModuleFilters().getSoftwareModuleType() - .map(type -> type.getName().equalsIgnoreCase(swModuleTypeName)).orElse(false)) { - notification.displayValidationError( - i18n.getMessage("message.swmodule.type.check.delete", new Object[] { swModuleTypeName })); - } else { - deleteSWModuleType(swModuleTypeName); - updateSWActionCount(); - } - - } - } - - private void deleteSWModuleType(final String swModuleTypeName) { - artifactUploadState.getSelectedDeleteSWModuleTypes().add(swModuleTypeName); - } - - private void addToDeleteList(final Table sourceTable, final TableTransferable transferable) { - final AbstractTable swTable = (AbstractTable) sourceTable; - final Set swModuleIdNameSet = swTable.getDeletedEntityByTransferable(transferable); - - swModuleIdNameSet.forEach(id -> { - final String swModuleName = (String) sourceTable.getContainerDataSource().getItem(id) - .getItemProperty(SPUILabelDefinitions.NAME_VERSION).getValue(); - artifactUploadState.getDeleteSofwareModules().put(id, swModuleName); - }); - } - - private void updateSWActionCount() { - final int count = artifactUploadState.getDeleteSofwareModules().size() - + artifactUploadState.getSelectedDeleteSWModuleTypes().size(); - updateActionsCount(count); - } - - @Override - protected void restoreActionCount() { - updateSWActionCount(); - } - - @Override - protected void unsavedActionsWindowClosed() { - final String message = uploadViewConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - } - - @Override - protected Component getUnsavedActionsWindowContent() { - uploadViewConfirmationWindowLayout.initialize(); - return uploadViewConfirmationWindowLayout; - } - - @Override - protected boolean hasUnsavedActions() { - return !artifactUploadState.getDeleteSofwareModules().isEmpty() - || !artifactUploadState.getSelectedDeleteSWModuleTypes().isEmpty(); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java deleted file mode 100644 index 86b9431fb..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.footer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.state.CustomFile; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.google.common.collect.Maps; -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Table.Align; - -/** - * Layout of confirm actions window on the Upload View. - */ -public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWindowLayout { - - private static final long serialVersionUID = 1L; - - private static final String SW_MODULE_NAME_MSG = "SW MOdule Name"; - - private static final String SW_DISCARD_CHGS = "DiscardChanges"; - - private static final String SW_MODULE_TYPE_NAME = "SoftwareModuleTypeName"; - - private static final String DISCARD = "Discard"; - - private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; - - private final transient SoftwareModuleManagement softwareModuleManagement; - - private final ArtifactUploadState artifactUploadState; - - UploadViewConfirmationWindowLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, - final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final ArtifactUploadState artifactUploadState) { - super(i18n, eventBus); - this.softwareModuleTypeManagement = softwareModuleTypeManagement; - this.softwareModuleManagement = softwareModuleManagement; - this.artifactUploadState = artifactUploadState; - } - - @Override - protected Map getConfirmationTabs() { - final Map tabs = Maps.newHashMapWithExpectedSize(2); - if (!artifactUploadState.getDeleteSofwareModules().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab()); - } - if (!artifactUploadState.getSelectedDeleteSWModuleTypes().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.sw.module.type.accordion.tab"), - createSMtypeDeleteConfirmationTab()); - } - return tabs; - } - - private ConfirmationTab createSMDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.SW_DELETE_ALL); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage("button.delete.all")); - tab.getConfirmAll().addClickListener(event -> deleteSMAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage("button.discard.all")); - tab.getDiscardAll().addClickListener(event -> discardSMAll(tab)); - - // Add items container to the table. - tab.getTable().setContainerDataSource(getSWModuleTableContainer()); - - // Add the discard action column - tab.getTable().addGeneratedColumn(SW_DISCARD_CHGS, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardSoftwareDelete(event, itemId, tab); - return createDiscardButton(itemId, clickListener); - }); - - tab.getTable().setVisibleColumns(SW_MODULE_NAME_MSG, SW_DISCARD_CHGS); - tab.getTable().setColumnHeaders(i18n.getMessage("upload.swModuleTable.header"), - i18n.getMessage("header.second.deletetarget.table")); - - tab.getTable().setColumnExpandRatio(SW_MODULE_NAME_MSG, SPUIDefinitions.TARGET_DISTRIBUTION_COLUMN_WIDTH); - tab.getTable().setColumnExpandRatio(SW_DISCARD_CHGS, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(SW_DISCARD_CHGS, Align.CENTER); - return tab; - } - - /** - * Get SWModule table container. - * - * @return IndexedContainer - */ - @SuppressWarnings("unchecked") - private IndexedContainer getSWModuleTableContainer() { - final IndexedContainer swcontactContainer = new IndexedContainer(); - swcontactContainer.addContainerProperty("SWModuleId", String.class, ""); - swcontactContainer.addContainerProperty(SW_MODULE_NAME_MSG, String.class, ""); - for (final Long swModuleID : artifactUploadState.getDeleteSofwareModules().keySet()) { - final Item item = swcontactContainer.addItem(swModuleID); - item.getItemProperty("SWModuleId").setValue(swModuleID.toString()); - item.getItemProperty(SW_MODULE_NAME_MSG) - .setValue(artifactUploadState.getDeleteSofwareModules().get(swModuleID)); - } - return swcontactContainer; - } - - private void discardSoftwareDelete(final Button.ClickEvent event, final Object itemId, final ConfirmationTab tab) { - - final Long swmoduleId = (Long) ((Button) event.getComponent()).getData(); - if (null != artifactUploadState.getDeleteSofwareModules() - && !artifactUploadState.getDeleteSofwareModules().isEmpty() - && artifactUploadState.getDeleteSofwareModules().containsKey(swmoduleId)) { - artifactUploadState.getDeleteSofwareModules().remove(swmoduleId); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE); - } else { - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_DELETE_SOFTWARE); - } - } - - private void deleteSMAll(final ConfirmationTab tab) { - final Set swmoduleIds = artifactUploadState.getDeleteSofwareModules().keySet(); - softwareModuleManagement.delete(swmoduleIds); - eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.REMOVE_ENTITY, swmoduleIds)); - - addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.swModule.deleted", artifactUploadState.getDeleteSofwareModules().size())); - /* - * Check if any information / files pending to upload for the deleted - * software modules. If so, then delete the files from the upload list. - */ - final List tobeRemoved = new ArrayList<>(); - for (final Long id : swmoduleIds) { - final String deleteSoftwareNameVersion = artifactUploadState.getDeleteSofwareModules().get(id); - - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String swNameVersion = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (deleteSoftwareNameVersion != null && deleteSoftwareNameVersion.equals(swNameVersion)) { - tobeRemoved.add(customFile); - } - } - } - if (!tobeRemoved.isEmpty()) { - artifactUploadState.getFileSelected().removeAll(tobeRemoved); - } - artifactUploadState.getDeleteSofwareModules().clear(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.software.delete.success")); - eventBus.publish(this, UploadArtifactUIEvent.DELETED_ALL_SOFWARE); - } - - private void discardSMAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - artifactUploadState.getDeleteSofwareModules().clear(); - setActionMessage(i18n.getMessage("message.software.discard.success")); - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE); - } - - private ConfirmationTab createSMtypeDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.SAVE_DELETE_SW_MODULE_TYPE); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage("button.delete.all")); - tab.getConfirmAll().addClickListener(event -> deleteSMtypeAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage("button.discard.all")); - tab.getDiscardAll().addClickListener(event -> discardSMtypeAll(tab)); - - // Add items container to the table. - tab.getTable().setContainerDataSource(getSWModuleTypeTableContainer()); - - // Add the discard action column - tab.getTable().addGeneratedColumn(DISCARD, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardSoftwareTypeDelete( - (String) ((Button) event.getComponent()).getData(), itemId, tab); - return createDiscardButton(itemId, clickListener); - }); - - tab.getTable().setVisibleColumns(SW_MODULE_TYPE_NAME, DISCARD); - tab.getTable().setColumnHeaders(i18n.getMessage("header.first.delete.swmodule.type.table"), - i18n.getMessage("header.second.delete.swmodule.type.table")); - - tab.getTable().setColumnExpandRatio(SW_MODULE_TYPE_NAME, 2); - tab.getTable().setColumnExpandRatio(SW_DISCARD_CHGS, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(SW_DISCARD_CHGS, Align.CENTER); - return tab; - } - - private Container getSWModuleTypeTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(SW_MODULE_TYPE_NAME, String.class, ""); - for (final String swModuleTypeName : artifactUploadState.getSelectedDeleteSWModuleTypes()) { - final Item saveTblitem = contactContainer.addItem(swModuleTypeName); - saveTblitem.getItemProperty(SW_MODULE_TYPE_NAME).setValue(swModuleTypeName); - } - return contactContainer; - } - - private void discardSoftwareTypeDelete(final String discardSWModuleType, final Object itemId, - final ConfirmationTab tab) { - if (null != artifactUploadState.getSelectedDeleteSWModuleTypes() - && !artifactUploadState.getSelectedDeleteSWModuleTypes().isEmpty() - && artifactUploadState.getSelectedDeleteSWModuleTypes().contains(discardSWModuleType)) { - artifactUploadState.getSelectedDeleteSWModuleTypes().remove(discardSWModuleType); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE_TYPE); - } else { - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_DELETE_SOFTWARE_TYPE); - } - } - - private void deleteSMtypeAll(final ConfirmationTab tab) { - final int deleteSWModuleTypeCount = artifactUploadState.getSelectedDeleteSWModuleTypes().size(); - for (final String swModuleTypeName : artifactUploadState.getSelectedDeleteSWModuleTypes()) { - softwareModuleTypeManagement.getByName(swModuleTypeName).map(SoftwareModuleType::getId) - .ifPresent(softwareModuleTypeManagement::delete); - } - addToConsolitatedMsg(FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.sw.module.type.delete", new Object[] { deleteSWModuleTypeCount })); - artifactUploadState.getSelectedDeleteSWModuleTypes().clear(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.software.type.delete.success")); - eventBus.publish(this, UploadArtifactUIEvent.DELETED_ALL_SOFWARE_TYPE); - } - - private void discardSMtypeAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - artifactUploadState.getSelectedDeleteSWModuleTypes().clear(); - setActionMessage(i18n.getMessage("message.software.type.discard.success")); - eventBus.publish(this, UploadArtifactUIEvent.DISCARD_ALL_DELETE_SOFTWARE_TYPE); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index e418c3fb3..912964d7d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -21,6 +21,7 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.CommonDialogWindow.SaveDialogCloseListener; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; @@ -83,6 +84,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent { private final AbstractTable softwareModuleTable; + private Label softwareModuleType; + /** * Constructor for SoftwareModuleAddUpdateWindow * @@ -248,7 +251,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent { nameTextField.clear(); versionTextField.clear(); descTextArea.clear(); - typeComboBox.clear(); + if (!editSwModule) { + typeComboBox.clear(); + } editSwModule = Boolean.FALSE; } @@ -261,7 +266,13 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent { formLayout = new FormLayout(); formLayout.setCaption(null); - formLayout.addComponent(typeComboBox); + if (editSwModule) { + formLayout.addComponent(softwareModuleType); + } else { + formLayout.addComponent(typeComboBox); + typeComboBox.focus(); + } + formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); formLayout.addComponent(vendorTextField); @@ -270,12 +281,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent { setCompositionRoot(formLayout); final CommonDialogWindow window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW) - .caption(i18n.getMessage("upload.caption.add.new.swmodule")).content(this).layout(formLayout).i18n(i18n) - .saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow(); + .caption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.software.module"))).id(UIComponentIdProvider.SW_MODULE_CREATE_DIALOG) + .content(this).layout(formLayout).i18n(i18n).saveDialogCloseListener(new SaveOnDialogCloseListener()) + .buildCommonDialogWindow(); nameTextField.setEnabled(!editSwModule); versionTextField.setEnabled(!editSwModule); - typeComboBox.setEnabled(!editSwModule); - typeComboBox.focus(); return window; } @@ -293,11 +303,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent { versionTextField.setValue(swModule.getVersion()); vendorTextField.setValue(swModule.getVendor()); descTextArea.setValue(swModule.getDescription()); - - if (swModule.getType().isDeleted()) { - typeComboBox.addItem(swModule.getType().getName()); - } - typeComboBox.setValue(swModule.getType().getName()); + softwareModuleType = new LabelBuilder().name(swModule.getType().getName()).caption("Type").buildLabel(); }); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 67e8e22d5..37e3ea601 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -12,24 +12,22 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.RefreshSoftwareModuleByFilterEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout; import org.eclipse.hawkbit.ui.push.SoftwareModuleUpdatedEventContainer; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -47,9 +45,6 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Button; -import com.vaadin.ui.Table; import com.vaadin.ui.UI; /** @@ -65,17 +60,13 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable swQF = new BeanQueryFactory<>(BaseSwModuleBeanQuery.class); swQF.setQueryConfiguration(queryConfiguration); - return new LazyQueryContainer(new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, "swId"), swQF); + return new LazyQueryContainer( + new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_SWM_ID), swQF); } private Map prepareQueryConfigFilters() { final Map queryConfig = Maps.newHashMapWithExpectedSize(2); artifactUploadState.getSoftwareModuleFilters().getSearchText() .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); - artifactUploadState.getSoftwareModuleFilters().getSoftwareModuleType() .ifPresent(type -> queryConfig.put(SPUIDefinitions.BY_SOFTWARE_MODULE_TYPE, type)); - return queryConfig; } @@ -128,11 +118,6 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId())) - .filter(Objects::nonNull) - .forEach(event -> updateSoftwareModuleInTable(event.getEntity())); + .filter(Objects::nonNull).forEach(event -> updateSoftwareModuleInTable(event.getEntity())); } private void updateSoftwareModuleInTable(final SoftwareModule editedSm) { @@ -196,30 +180,13 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable showMetadataDetails((Long) itemId)); - return manageMetaDataBtn; - } - }); - } - @Override protected List getTableVisibleColumns() { final List columnList = super.getTableVisibleColumns(); - if (!isMaximized()) { - columnList.add(new TableColumn(SPUILabelDefinitions.METADATA_ICON, "", 0.1F)); - return columnList; + if (isMaximized()) { + columnList + .add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, getI18n().getMessage("header.vendor"), 0.1F)); } - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, i18n.getMessage("header.vendor"), 0.1F)); return columnList; } @@ -238,25 +205,54 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable entitiesToDelete) { + if (isUploadInProgressForSoftwareModule(entitiesToDelete)) { + getNotification().displayValidationError(getI18n().getMessage("message.error.swModule.notDeleted")); + return; + } + softwareModuleManagement.delete(entitiesToDelete); + getEventBus().publish(this, new SoftwareModuleEvent(BaseEntityEventType.REMOVE_ENTITY, entitiesToDelete)); + getNotification().displaySuccess(getI18n().getMessage("message.delete.success", + entitiesToDelete.size() + " " + getI18n().getMessage("caption.software.module") + "(s)")); + + artifactUploadState.getSelectedSoftwareModules().clear(); + getEventBus().publish(this, UploadArtifactUIEvent.DELETED_ALL_SOFTWARE); } - private String getNameAndVerion(final Object itemId) { - final Item item = getItem(itemId); - final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); - final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); - return name + "." + version; + private boolean isUploadInProgressForSoftwareModule(final List entitiesToDelete) { + for (final Long id : entitiesToDelete) { + if (artifactUploadState.isUploadInProgressForSelectedSoftwareModule(id)) { + return true; + } + } + return false; } - private void showMetadataDetails(final Long itemId) { - softwareModuleManagement.get(itemId) - .ifPresent(swmodule -> UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, null))); + @Override + protected String getEntityType() { + return getI18n().getMessage("upload.swModuleTable.header"); + } + + @Override + protected Set getSelectedEntities() { + return artifactUploadState.getSelectedSoftwareModules(); + } + + @Override + protected String getEntityId(final Object itemId) { + final String entityId = String.valueOf( + getContainerDataSource().getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_SWM_ID).getValue()); + return "softwareModule." + entityId; + } + + @Override + protected String getDeletedEntityName(final Long entityId) { + final Optional softwareModule = softwareModuleManagement.get(entityId); + if (softwareModule.isPresent()) { + return softwareModule.get().getName() + ":" + softwareModule.get().getVersion(); + } + return ""; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java index 0a1faf757..8f0154c43 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java @@ -38,7 +38,7 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout { + + private static final long serialVersionUID = 1L; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private String singleAssignStr; + + private String multiAssignStr; + + private Label singleAssign; + + private Label multiAssign; + + private OptionGroup assignOptiongroup; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + */ + public AbstractSoftwareModuleTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final SoftwareModuleTypeManagement softwareModuleTypeManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification); + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + } + + @Override + protected int getTagNameSize() { + return SoftwareModuleType.NAME_MAX_SIZE; + } + + @Override + protected int getTagDescSize() { + return SoftwareModuleType.DESCRIPTION_MAX_SIZE; + } + + @Override + protected int getTypeKeySize() { + return SoftwareModuleType.KEY_MAX_SIZE; + } + + @Override + protected String getTagNameId() { + return UIComponentIdProvider.NEW_SOFTWARE_TYPE_NAME; + } + + @Override + protected String getTagDescId() { + return UIComponentIdProvider.NEW_SOFTWARE_TYPE_DESC; + } + + @Override + protected String getTypeKeyId() { + return UIComponentIdProvider.NEW_SOFTWARE_TYPE_KEY; + } + + @Override + protected void createRequiredComponents() { + super.createRequiredComponents(); + singleAssignStr = getI18n().getMessage("label.singleAssign.type"); + multiAssignStr = getI18n().getMessage("label.multiAssign.type"); + singleAssign = new LabelBuilder().name(singleAssignStr).buildLabel(); + multiAssign = new LabelBuilder().name(multiAssignStr).buildLabel(); + singleMultiOptionGroup(); + } + + @Override + protected void buildLayout() { + super.buildLayout(); + getFormLayout().addComponent(assignOptiongroup); + } + + @Override + protected Optional findEntityByKey() { + return softwareModuleTypeManagement.getByKey(getTypeKey().getValue()); + } + + @Override + protected Optional findEntityByName() { + return softwareModuleTypeManagement.getByName(getTagName().getValue()); + } + + @Override + protected String getDuplicateKeyErrorMessage(final SoftwareModuleType existingType) { + return getI18n().getMessage("message.type.key.swmodule.duplicate.check", existingType.getKey()); + } + + public SoftwareModuleTypeManagement getSoftwareModuleTypeManagement() { + return softwareModuleTypeManagement; + } + + public String getSingleAssignStr() { + return singleAssignStr; + } + + public void setSingleAssignStr(final String singleAssignStr) { + this.singleAssignStr = singleAssignStr; + } + + public String getMultiAssignStr() { + return multiAssignStr; + } + + public void setMultiAssignStr(final String multiAssignStr) { + this.multiAssignStr = multiAssignStr; + } + + public Label getSingleAssign() { + return singleAssign; + } + + public void setSingleAssign(final Label singleAssign) { + this.singleAssign = singleAssign; + } + + public Label getMultiAssign() { + return multiAssign; + } + + public void setMultiAssign(final Label multiAssign) { + this.multiAssign = multiAssign; + } + + public OptionGroup getAssignOptiongroup() { + return assignOptiongroup; + } + + public void setAssignOptiongroup(final OptionGroup assignOptiongroup) { + this.assignOptiongroup = assignOptiongroup; + } + + private void singleMultiOptionGroup() { + final List optionValues = new ArrayList<>(); + optionValues.add(singleAssign.getValue()); + optionValues.add(multiAssign.getValue()); + assignOptionGroupByValues(optionValues); + } + + private void assignOptionGroupByValues(final List tagOptions) { + assignOptiongroup = new OptionGroup("", tagOptions); + assignOptiongroup.setStyleName(ValoTheme.OPTIONGROUP_SMALL); + assignOptiongroup.addStyleName("custom-option-group"); + assignOptiongroup.setNullSelectionAllowed(false); + assignOptiongroup.setId(UIComponentIdProvider.ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); + assignOptiongroup.select(tagOptions.get(0)); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateSoftwareModuleTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateSoftwareModuleTypeLayout.java new file mode 100644 index 000000000..435b894c5 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateSoftwareModuleTypeLayout.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.smtype; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Layout for the pop-up window which is created when creating a software module + * type on the Upload or Distribution View. + */ +public class CreateSoftwareModuleTypeLayout extends AbstractSoftwareModuleTypeLayout { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for CreateUpdateSoftwareTypeLayout + * + * @param i18n + * I18N + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * management for {@link SoftwareModuleType}s + */ + public CreateSoftwareModuleTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final SoftwareModuleTypeManagement softwareModuleTypeManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, softwareModuleTypeManagement); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.create.new", getI18n().getMessage("caption.type")); + } + + @Override + protected void saveEntity() { + createNewSWModuleType(); + } + + private void createNewSWModuleType() { + int assignNumber = 0; + final String colorPicked = ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()); + final String typeNameValue = getTagName().getValue(); + final String typeKeyValue = getTypeKey().getValue(); + final String typeDescValue = getTagDesc().getValue(); + final String assignValue = (String) getAssignOptiongroup().getValue(); + if (assignValue != null && assignValue.equalsIgnoreCase(getSingleAssignStr())) { + assignNumber = 1; + } else if (assignValue != null && assignValue.equalsIgnoreCase(getMultiAssignStr())) { + assignNumber = Integer.MAX_VALUE; + } + + if (typeNameValue != null && typeKeyValue != null) { + final SoftwareModuleType newSWType = getSoftwareModuleTypeManagement() + .create(getEntityFactory().softwareModuleType().create().key(typeKeyValue).name(typeNameValue) + .description(typeDescValue).colour(colorPicked).maxAssignments(assignNumber)); + getUiNotification().displaySuccess(getI18n().getMessage("message.save.success", newSWType.getName())); + getEventBus().publish(this, + new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); + } else { + getUiNotification().displayValidationError(getI18n().getMessage("message.error.missing.typenameorkey")); + } + } + + @Override + protected boolean isUpdateAction() { + return false; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java deleted file mode 100644 index f64eb8040..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ /dev/null @@ -1,310 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; -import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; -import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; -import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; -import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.Label; -import com.vaadin.ui.OptionGroup; -import com.vaadin.ui.TextField; -import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Layout for the create or update software module type. - * - */ -public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { - - private static final long serialVersionUID = 1L; - private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class); - - private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; - - private String singleAssignStr; - private String multiAssignStr; - private Label singleAssign; - private Label multiAssign; - private OptionGroup assignOptiongroup; - - /** - * Constructor for CreateUpdateSoftwareTypeLayout - * - * @param i18n - * I18N - * @param entityFactory - * EntityFactory - * @param eventBus - * UIEventBus - * @param permChecker - * SpPermissionChecker - * @param uiNotification - * UINotification - * @param softwareModuleTypeManagement - * management for {@link SoftwareModuleType}s - */ - public CreateUpdateSoftwareTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, - final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, - final SoftwareModuleTypeManagement softwareModuleTypeManagement) { - super(i18n, entityFactory, eventBus, permChecker, uiNotification); - this.softwareModuleTypeManagement = softwareModuleTypeManagement; - } - - @Override - protected void addListeners() { - super.addListeners(); - optiongroup.addValueChangeListener(this::optionValueChanged); - } - - @Override - protected void createRequiredComponents() { - - super.createRequiredComponents(); - - singleAssignStr = i18n.getMessage("label.singleAssign.type"); - multiAssignStr = i18n.getMessage("label.multiAssign.type"); - singleAssign = new LabelBuilder().name(singleAssignStr).buildLabel(); - - multiAssign = new LabelBuilder().name(multiAssignStr).buildLabel(); - - tagName = createTextField("textfield.name", SPUIDefinitions.TYPE_NAME, SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME, - SoftwareModuleType.NAME_MAX_SIZE); - - typeKey = createTextField("textfield.key", SPUIDefinitions.TYPE_KEY, SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY, - SoftwareModuleType.KEY_MAX_SIZE); - - tagDesc = new TextAreaBuilder(SoftwareModuleType.DESCRIPTION_MAX_SIZE) - .caption(i18n.getMessage("textfield.description")) - .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC) - .id(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC).buildTextComponent(); - - singleMultiOptionGroup(); - } - - @Override - protected Color getColorForColorPicker() { - - final Optional typeSelected = softwareModuleTypeManagement - .getByName(tagNameComboBox.getValue().toString()); - if (typeSelected.isPresent()) { - return typeSelected.get().getColour() != null - ? ColorPickerHelper.rgbToColorConverter(typeSelected.get().getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR); - } - return ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR); - } - - private TextField createTextField(final String in18Key, final String styleName, final String id, - final int maxLength) { - return new TextFieldBuilder(maxLength).caption(i18n.getMessage(in18Key)) - .styleName(ValoTheme.TEXTFIELD_TINY + " " + styleName).required(true, i18n).id(id).buildTextComponent(); - } - - @Override - protected void buildLayout() { - - super.buildLayout(); - ColorPickerHelper.setRgbSliderValues(colorPickerLayout); - getFormLayout().addComponent(typeKey, 4); - getFormLayout().addComponent(assignOptiongroup); - } - - @Override - protected String getWindowCaption() { - return i18n.getMessage("caption.add.type"); - } - - /** - * Listener for option group - Create tag/Update. - * - * @param event - * ValueChangeEvent - */ - @Override - protected void optionValueChanged(final ValueChangeEvent event) { - - super.optionValueChanged(event); - - if (updateTagStr.equals(event.getProperty().getValue())) { - assignOptiongroup.setEnabled(false); - } else { - assignOptiongroup.setEnabled(true); - } - assignOptiongroup.select(singleAssignStr); - } - - /** - * reset the components. - */ - @Override - protected void reset() { - - super.reset(); - assignOptiongroup.select(singleAssignStr); - } - - @Override - protected void resetTagNameField() { - - super.resetTagNameField(); - typeKey.clear(); - tagDesc.clear(); - assignOptiongroup.select(singleAssignStr); - } - - /** - * Select tag & set tag name & tag desc values corresponding to selected - * tag. - * - * @param targetTagSelected - * as the selected tag from combo - */ - @Override - protected void setTagDetails(final String targetTagSelected) { - tagName.setValue(targetTagSelected); - softwareModuleTypeManagement.getByName(targetTagSelected).ifPresent(selectedTypeTag -> { - tagDesc.setValue(selectedTypeTag.getDescription()); - typeKey.setValue(selectedTypeTag.getKey()); - if (selectedTypeTag.getMaxAssignments() == 1) { - assignOptiongroup.setValue(singleAssignStr); - } else { - assignOptiongroup.setValue(multiAssignStr); - } - setColorPickerComponentsColor(selectedTypeTag.getColour()); - }); - } - - private void singleMultiOptionGroup() { - final List optionValues = new ArrayList<>(); - optionValues.add(singleAssign.getValue()); - optionValues.add(multiAssign.getValue()); - assignOptionGroupByValues(optionValues); - } - - private void assignOptionGroupByValues(final List tagOptions) { - assignOptiongroup = new OptionGroup("", tagOptions); - assignOptiongroup.setStyleName(ValoTheme.OPTIONGROUP_SMALL); - assignOptiongroup.addStyleName("custom-option-group"); - assignOptiongroup.setNullSelectionAllowed(false); - assignOptiongroup.setId(SPUIDefinitions.ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); - assignOptiongroup.select(tagOptions.get(0)); - } - - @Override - protected void createEntity() { - createNewSWModuleType(); - } - - @Override - protected void updateEntity(final SoftwareModuleType entity) { - updateSWModuleType(entity); - } - - @Override - protected Optional findEntityByKey() { - return softwareModuleTypeManagement.getByKey(typeKey.getValue()); - } - - @Override - protected Optional findEntityByName() { - return softwareModuleTypeManagement.getByName(tagName.getValue()); - } - - @Override - protected String getDuplicateKeyErrorMessage(final SoftwareModuleType existingType) { - return i18n.getMessage("message.type.key.swmodule.duplicate.check", new Object[] { existingType.getKey() }); - } - - private void createNewSWModuleType() { - int assignNumber = 0; - final String colorPicked = ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()); - final String typeNameValue = tagName.getValue(); - final String typeKeyValue = typeKey.getValue(); - final String typeDescValue = tagDesc.getValue(); - final String assignValue = (String) assignOptiongroup.getValue(); - if (assignValue != null && assignValue.equalsIgnoreCase(singleAssignStr)) { - assignNumber = 1; - } else if (assignValue != null && assignValue.equalsIgnoreCase(multiAssignStr)) { - assignNumber = Integer.MAX_VALUE; - } - - if (typeNameValue != null && typeKeyValue != null) { - final SoftwareModuleType newSWType = softwareModuleTypeManagement - .create(entityFactory.softwareModuleType().create().key(typeKeyValue).name(typeNameValue) - .description(typeDescValue).colour(colorPicked).maxAssignments(assignNumber)); - uiNotification - .displaySuccess(i18n.getMessage("message.save.success", new Object[] { newSWType.getName() })); - eventBus.publish(this, - new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); - } else { - uiNotification.displayValidationError(i18n.getMessage("message.error.missing.typenameorkey")); - } - } - - private void updateSWModuleType(final SoftwareModuleType existingType) { - softwareModuleTypeManagement - .update(entityFactory.softwareModuleType().update(existingType.getId()).description(tagDesc.getValue()) - .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()))); - uiNotification - .displaySuccess(i18n.getMessage("message.update.success", new Object[] { existingType.getName() })); - eventBus.publish(this, - new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); - } - - @Override - public void addColorChangeListener(final ColorChangeListener listener) { - LOG.debug("inside addColorChangeListener"); - } - - @Override - public void removeColorChangeListener(final ColorChangeListener listener) { - LOG.debug("inside removeColorChangeListener"); - - } - - @Override - public Color getColor() { - return null; - } - - @Override - protected void populateTagNameCombo() { - tagNameComboBox.setContainerDataSource( - HawkbitCommonUtil.createLazyQueryContainer(new BeanQueryFactory<>(SoftwareModuleTypeBeanQuery.class))); - tagNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java deleted file mode 100644 index 76d84e62e..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java +++ /dev/null @@ -1,117 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import java.util.EnumSet; - -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; -import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; -import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; - -/** - * Software module type filter buttons. - * - */ -public class SMTypeFilterButtons extends AbstractFilterButtons { - - private static final long serialVersionUID = 169198312654380358L; - - private final ArtifactUploadState artifactUploadState; - - private final UploadViewClientCriterion uploadViewClientCriterion; - - SMTypeFilterButtons(final UIEventBus eventBus, final ArtifactUploadState artifactUploadState, - final UploadViewClientCriterion uploadViewClientCriterion, - final SoftwareModuleTypeManagement softwareModuleTypeManagement) { - super(eventBus, new SMTypeFilterButtonClick(eventBus, artifactUploadState, softwareModuleTypeManagement)); - this.artifactUploadState = artifactUploadState; - this.uploadViewClientCriterion = uploadViewClientCriterion; - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final SoftwareModuleTypeEvent event) { - if (event.getSoftwareModuleType() != null - && EnumSet.allOf(SoftwareModuleTypeEnum.class).contains(event.getSoftwareModuleTypeEnum())) { - refreshTable(); - } - - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE_TYPE) { - refreshTable(); - } - } - - @Override - protected String getButtonsTableId() { - return UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; - } - - @Override - protected LazyQueryContainer createButtonsLazyQueryContainer() { - return HawkbitCommonUtil.createLazyQueryContainer(new BeanQueryFactory<>(SoftwareModuleTypeBeanQuery.class)); - } - - @Override - protected boolean isClickedByDefault(final String typeName) { - return artifactUploadState.getSoftwareModuleFilters().getSoftwareModuleType() - .map(type -> type.getName().equals(typeName)).orElse(false); - } - - @Override - protected String createButtonId(final String name) { - return UIComponentIdProvider.SM_TYPE_FILTER_BTN_ID + name; - } - - @Override - protected DropHandler getFilterButtonDropHandler() { - return new DropHandler() { - private static final long serialVersionUID = 1L; - - @Override - public AcceptCriterion getAcceptCriterion() { - return uploadViewClientCriterion; - } - - @Override - public void drop(final DragAndDropEvent event) { - /* Not required */ - } - }; - } - - @Override - protected String getButttonWrapperIdPrefix() { - return UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX; - } - - @Override - protected String getButtonWrapperData() { - return null; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterHeader.java deleted file mode 100644 index 4cec2fda0..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterHeader.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.smtype; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.UI; -import com.vaadin.ui.Window; - -/** - * Software module type filter buttons header. - */ -public class SMTypeFilterHeader extends AbstractFilterHeader { - - private static final long serialVersionUID = -4855810338059032342L; - - private final ArtifactUploadState artifactUploadState; - private final CreateUpdateSoftwareTypeLayout createUpdateSWTypeLayout; - - SMTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, - final ArtifactUploadState artifactUploadState, final EntityFactory entityFactory, - final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuletypeManagement) { - super(permChecker, eventBus, i18n); - this.artifactUploadState = artifactUploadState; - this.createUpdateSWTypeLayout = new CreateUpdateSoftwareTypeLayout(i18n, entityFactory, eventBus, permChecker, - uiNotification, softwareModuletypeManagement); - - if (permChecker.hasCreateRepositoryPermission() || permChecker.hasUpdateRepositoryPermission()) { - createUpdateSWTypeLayout.init(); - } - } - - @Override - protected boolean hasCreateUpdatePermission() { - return permChecker.hasCreateRepositoryPermission() || permChecker.hasUpdateRepositoryPermission(); - } - - @Override - protected String getTitle() { - return SPUILabelDefinitions.TYPE; - } - - @Override - protected void settingsIconClicked(final ClickEvent event) { - final Window addUpdateWindow = createUpdateSWTypeLayout.getWindow(); - UI.getCurrent().addWindow(addUpdateWindow); - addUpdateWindow.setVisible(Boolean.TRUE); - } - - @Override - protected boolean dropHitsRequired() { - return false; - } - - @Override - protected void hideFilterButtonLayout() { - artifactUploadState.setSwTypeFilterClosed(true); - eventBus.publish(this, UploadArtifactUIEvent.HIDE_FILTER_BY_TYPE); - } - - @Override - protected String getConfigureFilterButtonId() { - return SPUIDefinitions.ADD_SOFTWARE_MODULE_TYPE; - } - - @Override - protected String getHideButtonId() { - return UIComponentIdProvider.SM_SHOW_FILTER_BUTTON_ID; - } - - @Override - protected boolean isAddTagRequired() { - return true; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSoftwareModuleTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSoftwareModuleTypeLayout.java new file mode 100644 index 000000000..22b4ee633 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/UpdateSoftwareModuleTypeLayout.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.smtype; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.layouts.UpdateTag; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +import com.vaadin.ui.Window.CloseListener; + +/** + * Layout for the pop-up window which is created when updating a Software Module + * Type on the Upload View. + * + */ +public class UpdateSoftwareModuleTypeLayout extends AbstractSoftwareModuleTypeLayout implements UpdateTag { + + private static final long serialVersionUID = 1L; + + private final String selectedTypeName; + + private final CloseListener closeListener; + + /** + * Constructor for initializing the pop-up window for updating a software + * module type. The form fields are filled with the current data of the + * selected software module type. + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param selectedTypeName + * The name of the selected software module type to update + * @param closeListener + * CloseListener which describes the action to do when closing + * the window + */ + public UpdateSoftwareModuleTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final SoftwareModuleTypeManagement softwareModuleTypeManagement, final String selectedTypeName, + final CloseListener closeListener) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, softwareModuleTypeManagement); + this.selectedTypeName = selectedTypeName; + this.closeListener = closeListener; + initUpdatePopup(); + } + + private void initUpdatePopup() { + setTagDetails(selectedTypeName); + getWindow().addCloseListener(closeListener); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.update", getI18n().getMessage("caption.type")); + } + + @Override + protected void saveEntity() { + updateSWModuleType(findEntityByName() + .orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, getTagName().getValue()))); + } + + @Override + protected void buildLayout() { + super.buildLayout(); + disableFields(); + } + + @Override + protected void disableFields() { + getTagName().setEnabled(false); + getTypeKey().setEnabled(false); + getAssignOptiongroup().setEnabled(false); + } + + @Override + public void setTagDetails(final String selectedEntity) { + getSoftwareModuleTypeManagement().getByName(selectedEntity).ifPresent(selectedTypeTag -> { + getTagName().setValue(selectedTypeTag.getName()); + getTagDesc().setValue(selectedTypeTag.getDescription()); + getTypeKey().setValue(selectedTypeTag.getKey()); + if (selectedTypeTag.getMaxAssignments() == 1) { + getAssignOptiongroup().setValue(getSingleAssignStr()); + } else { + getAssignOptiongroup().setValue(getMultiAssignStr()); + } + setColorPickerComponentsColor(selectedTypeTag.getColour()); + }); + disableFields(); + } + + private void updateSWModuleType(final SoftwareModuleType existingType) { + getSoftwareModuleTypeManagement().update(getEntityFactory().softwareModuleType().update(existingType.getId()) + .description(getTagDesc().getValue()) + .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()))); + getUiNotification().displaySuccess(getI18n().getMessage("message.update.success", existingType.getName())); + getEventBus().publish(this, + new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); + } + + @Override + protected boolean isUpdateAction() { + return true; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtonClick.java similarity index 97% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtonClick.java index 52a0e63ac..f78c92c55 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtonClick.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.artifacts.smtype; +package org.eclipse.hawkbit.ui.artifacts.smtype.filter; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.ui.artifacts.event.RefreshSoftwareModuleByFilterEvent; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java new file mode 100644 index 000000000..e2fd1b1f3 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterButtons.java @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.smtype.filter; + +import java.util.EnumSet; +import java.util.Optional; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; +import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; +import org.eclipse.hawkbit.ui.artifacts.smtype.UpdateSoftwareModuleTypeLayout; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.SoftwareModuleTypeFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; +import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; +import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.ui.Button.ClickEvent; + +/** + * Software module type filter buttons. + * + */ +public class SMTypeFilterButtons extends AbstractFilterButtons { + + private static final long serialVersionUID = 1L; + + private final ArtifactUploadState artifactUploadState; + + private final UploadViewClientCriterion uploadViewClientCriterion; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private final transient EntityFactory entityFactory; + + private final SpPermissionChecker permChecker; + + private final UINotification uiNotification; + + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param artifactUploadState + * ArtifactUploadState + * @param uploadViewClientCriterion + * UploadViewClientCriterion + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + */ + public SMTypeFilterButtons(final UIEventBus eventBus, final ArtifactUploadState artifactUploadState, + final UploadViewClientCriterion uploadViewClientCriterion, + final SoftwareModuleTypeManagement softwareModuleTypeManagement, final VaadinMessageSource i18n, + final EntityFactory entityFactory, final SpPermissionChecker permChecker, + final UINotification uiNotification) { + super(eventBus, new SMTypeFilterButtonClick(eventBus, artifactUploadState, softwareModuleTypeManagement), i18n); + this.artifactUploadState = artifactUploadState; + this.uploadViewClientCriterion = uploadViewClientCriterion; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.entityFactory = entityFactory; + this.permChecker = permChecker; + this.uiNotification = uiNotification; + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final SoftwareModuleTypeEvent event) { + if (event.getSoftwareModuleType() != null + && EnumSet.allOf(SoftwareModuleTypeEnum.class).contains(event.getSoftwareModuleTypeEnum())) { + refreshTable(); + } + + if (isUpdate(event)) { + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + } + + private static boolean isUpdate(final SoftwareModuleTypeEvent event) { + return event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE; + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final UploadArtifactUIEvent event) { + if (event == UploadArtifactUIEvent.DELETED_ALL_SOFTWARE_TYPE) { + refreshTable(); + } + } + + @Override + protected String getButtonsTableId() { + return UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; + } + + @Override + protected LazyQueryContainer createButtonsLazyQueryContainer() { + return HawkbitCommonUtil.createLazyQueryContainer(new BeanQueryFactory<>(SoftwareModuleTypeBeanQuery.class)); + } + + @Override + protected boolean isClickedByDefault(final String typeName) { + return artifactUploadState.getSoftwareModuleFilters().getSoftwareModuleType() + .map(type -> type.getName().equals(typeName)).orElse(false); + } + + @Override + protected String createButtonId(final String name) { + return UIComponentIdProvider.SM_TYPE_FILTER_BTN_ID + name; + } + + @Override + protected DropHandler getFilterButtonDropHandler() { + return new DropHandler() { + private static final long serialVersionUID = 1L; + + @Override + public AcceptCriterion getAcceptCriterion() { + return uploadViewClientCriterion; + } + + @Override + public void drop(final DragAndDropEvent event) { + /* Not required */ + } + }; + } + + @Override + protected String getButttonWrapperIdPrefix() { + return UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX; + } + + @Override + protected String getButtonWrapperData() { + return null; + } + + @Override + protected void addEditButtonClickListener(final ClickEvent event) { + new UpdateSoftwareModuleTypeLayout(getI18n(), entityFactory, getEventBus(), permChecker, uiNotification, + softwareModuleTypeManagement, getEntityId(event), getCloseListenerForEditAndDeleteTag( + new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR))); + } + + @Override + protected void addDeleteButtonClickListener(final ClickEvent event) { + openConfirmationWindowForDeletion(getEntityId(event), + getI18n().getMessage("caption.entity.software.module.type"), + new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + + @Override + protected void deleteEntity(final String entityToDelete) { + final Optional swmTypeToDelete = softwareModuleTypeManagement.getByName(entityToDelete); + swmTypeToDelete.ifPresent(tag -> { + if (artifactUploadState.getSoftwareModuleFilters().getSoftwareModuleType().equals(swmTypeToDelete)) { + uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityToDelete)); + removeUpdateAndDeleteColumn(); + } else { + softwareModuleTypeManagement.delete(swmTypeToDelete.get().getId()); + getEventBus().publish(this, UploadArtifactUIEvent.DELETED_ALL_SOFTWARE_TYPE); + uiNotification.displaySuccess(getI18n().getMessage("message.delete.success", entityToDelete)); + } + }); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java new file mode 100644 index 000000000..2241c7bb8 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterHeader.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.smtype.filter; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; +import org.eclipse.hawkbit.ui.artifacts.smtype.CreateSoftwareModuleTypeLayout; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.SoftwareModuleTypeFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.MenuBar.Command; + +/** + * Software module type filter buttons header. + */ +public class SMTypeFilterHeader extends AbstractFilterHeader { + + private static final long serialVersionUID = 1L; + + private final ArtifactUploadState artifactUploadState; + + private final transient EntityFactory entityFactory; + + private final UINotification uiNotification; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private final SMTypeFilterButtons smTypeFilterButtons; + + SMTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, + final ArtifactUploadState artifactUploadState, final EntityFactory entityFactory, + final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final SMTypeFilterButtons smTypeFilterButtons) { + super(permChecker, eventBus, i18n); + this.artifactUploadState = artifactUploadState; + this.entityFactory = entityFactory; + this.uiNotification = uiNotification; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.smTypeFilterButtons = smTypeFilterButtons; + } + + @Override + protected String getTitle() { + return SPUILabelDefinitions.TYPE; + } + + @Override + protected boolean dropHitsRequired() { + return false; + } + + @Override + protected void hideFilterButtonLayout() { + artifactUploadState.setSwTypeFilterClosed(true); + getEventBus().publish(this, UploadArtifactUIEvent.HIDE_FILTER_BY_TYPE); + } + + @Override + protected String getConfigureFilterButtonId() { + return UIComponentIdProvider.ADD_SOFTWARE_MODULE_TYPE; + } + + @Override + protected String getHideButtonId() { + return UIComponentIdProvider.SM_SHOW_FILTER_BUTTON_ID; + } + + @Override + protected boolean isAddTagRequired() { + return true; + } + + @Override + protected Command getAddButtonCommand() { + return command -> new CreateSoftwareModuleTypeLayout(getI18n(), entityFactory, getEventBus(), getPermChecker(), + uiNotification, softwareModuleTypeManagement); + } + + @Override + protected Command getDeleteButtonCommand() { + return command -> { + smTypeFilterButtons.addDeleteColumn(); + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected Command getUpdateButtonCommand() { + return command -> { + smTypeFilterButtons.addUpdateColumn(); + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + super.cancelUpdateOrDeleteTag(event); + smTypeFilterButtons.removeUpdateAndDeleteColumn(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + private void onEvent(final SoftwareModuleTypeFilterHeaderEvent event) { + processFilterHeaderEvent(event); + } + + @Override + protected String getMenuBarId() { + return UIComponentIdProvider.SOFT_MODULE_TYPE_MENU_BAR_ID; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java similarity index 71% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java index ec871ca31..e5ebd1844 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/filter/SMTypeFilterLayout.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.artifacts.smtype; +package org.eclipse.hawkbit.ui.artifacts.smtype.filter; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; @@ -14,7 +14,6 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterLayout; -import org.eclipse.hawkbit.ui.dd.criteria.UploadViewClientCriterion; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -26,23 +25,38 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; */ public class SMTypeFilterLayout extends AbstractFilterLayout { - private static final long serialVersionUID = 1581066345157393665L; + private static final long serialVersionUID = 1L; private final ArtifactUploadState artifactUploadState; + /** + * Constructor + * + * @param artifactUploadState + * ArtifactUploadState + * @param i18n + * VaadinMessageSource + * @param permChecker + * SpPermissionChecker + * @param eventBus + * UIEventBus + * @param entityFactory + * EntityFactory + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param sMTypeFilterButtons + * SMTypeFilterButtons + */ public SMTypeFilterLayout(final ArtifactUploadState artifactUploadState, final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, final EntityFactory entityFactory, final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final UploadViewClientCriterion uploadViewClientCriterion) { + final SMTypeFilterButtons sMTypeFilterButtons) { super(new SMTypeFilterHeader(i18n, permChecker, eventBus, artifactUploadState, entityFactory, uiNotification, - softwareModuleTypeManagement), - new SMTypeFilterButtons(eventBus, artifactUploadState, uploadViewClientCriterion, - softwareModuleTypeManagement)); - + softwareModuleTypeManagement, sMTypeFilterButtons), sMTypeFilterButtons, eventBus); this.artifactUploadState = artifactUploadState; restoreState(); - - eventBus.subscribe(this); } @EventBusListenerMethod(scope = EventScope.UI) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java index 8828229c0..a37c3375c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadState.java @@ -8,22 +8,29 @@ */ package org.eclipse.hawkbit.ui.artifacts.state; +import java.io.File; import java.io.Serializable; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.upload.UploadStatusObject; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadId; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; import org.eclipse.hawkbit.ui.common.ManagementEntityState; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; @@ -36,16 +43,14 @@ public class ArtifactUploadState implements ManagementEntityState, Serializable private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(ArtifactUploadState.class); + private final SoftwareModuleFilters softwareModuleFilters; private final Map deleteSofwareModules = new HashMap<>(); - private final Set fileSelected = new HashSet<>(); - private transient Optional selectedBaseSwModuleId = Optional.empty(); - private final Map baseSwModuleList = new HashMap<>(); - private Set selectedSoftwareModules = Collections.emptySet(); private boolean swTypeFilterClosed; @@ -60,49 +65,17 @@ public class ArtifactUploadState implements ManagementEntityState, Serializable private boolean statusPopupMinimized; - private boolean uploadCompleted; - - private List uploadedFileStatusList = new ArrayList<>(); - - private final AtomicInteger numberOfFileUploadsExpected = new AtomicInteger(); - - private final AtomicInteger numberOfFilesActuallyUpload = new AtomicInteger(); - - private final AtomicInteger numberOfFileUploadsFailed = new AtomicInteger(); + /** + * Map that holds all files that were selected for upload. They remain in + * the list even if upload fails, succeeds or is aborted by the user. + */ + private Map overallFilesInUploadProcess; @Autowired ArtifactUploadState(final SoftwareModuleFilters softwareModuleFilters) { this.softwareModuleFilters = softwareModuleFilters; } - public AtomicInteger getNumberOfFileUploadsFailed() { - return numberOfFileUploadsFailed; - } - - public AtomicInteger getNumberOfFilesActuallyUpload() { - return numberOfFilesActuallyUpload; - } - - public AtomicInteger getNumberOfFileUploadsExpected() { - return numberOfFileUploadsExpected; - } - - public List getUploadedFileStatusList() { - return uploadedFileStatusList; - } - - public void setUploadedFileStatusList(final List uploadedFileStatusList) { - this.uploadedFileStatusList = uploadedFileStatusList; - } - - public boolean isUploadCompleted() { - return uploadCompleted; - } - - public void setUploadCompleted(final boolean uploadCompleted) { - this.uploadCompleted = uploadCompleted; - } - public void setStatusPopupMinimized(final boolean statusPopupMinimized) { this.statusPopupMinimized = statusPopupMinimized; } @@ -115,22 +88,14 @@ public class ArtifactUploadState implements ManagementEntityState, Serializable return softwareModuleFilters; } - public Map getDeleteSofwareModules() { + public Map getDeleteSoftwareModules() { return deleteSofwareModules; } - public Set getFileSelected() { - return fileSelected; - } - public Optional getSelectedBaseSwModuleId() { return selectedBaseSwModuleId; } - public Map getBaseSwModuleList() { - return baseSwModuleList; - } - public Set getSelectedSoftwareModules() { return selectedSoftwareModules; } @@ -180,4 +145,150 @@ public class ArtifactUploadState implements ManagementEntityState, Serializable public void setNoDataAvilableSoftwareModule(final boolean noDataAvilableSoftwareModule) { this.noDataAvilableSoftwareModule = noDataAvilableSoftwareModule; } + + public boolean isMoreThanOneSoftwareModulesSelected() { + return getSelectedSoftwareModules().size() > 1; + } + + public boolean isNoSoftwareModuleSelected() { + return !getSelectedBaseSwModuleId().isPresent(); + } + + public void removeFilesFromOverallUploadProcessList(final Collection filesToRemove) { + getOverallFilesInUploadProcessMap().keySet().removeAll(filesToRemove); + } + + public Set getAllFileUploadIdsFromOverallUploadProcessList() { + return Collections.unmodifiableSet(getOverallFilesInUploadProcessMap().keySet()); + } + + public Collection getAllFileUploadProgressValuesFromOverallUploadProcessList() { + return Collections.unmodifiableCollection(getOverallFilesInUploadProcessMap().values()); + } + + public Set getFilesInFailedState() { + return Collections.unmodifiableSet(getFailedUploads()); + } + + public FileUploadProgress getFileUploadProgress(final FileUploadId fileUploadId) { + return getOverallFilesInUploadProcessMap().get(fileUploadId); + } + + public void updateFileUploadProgress(final FileUploadId fileUploadId, final FileUploadProgress fileUploadProgress) { + getOverallFilesInUploadProcessMap().put(fileUploadId, fileUploadProgress); + } + + public boolean isFileInUploadState(final FileUploadId fileUploadId) { + return getOverallFilesInUploadProcessMap().containsKey(fileUploadId); + } + + public boolean isFileInUploadState(final String filename, final SoftwareModule softwareModule) { + return isFileInUploadState(new FileUploadId(filename, softwareModule)); + } + + public boolean isAtLeastOneUploadInProgress() { + return getInProgressCount() > 0; + } + + public boolean areAllUploadsFinished() { + return getInProgressCount() == 0; + } + + private int getInProgressCount() { + final int succeededUploadCount = getSucceededUploads().size(); + final int failedUploadCount = getFailedUploads().size(); + final int overallUploadCount = getOverallFilesInUploadProcessMap().size(); + + final int inProgressCount = overallUploadCount - failedUploadCount - succeededUploadCount; + + assertFileStateConsistency(inProgressCount, overallUploadCount, succeededUploadCount, failedUploadCount); + + return inProgressCount; + } + + private static void assertFileStateConsistency(final int inProgressCount, final int overallUploadCount, + final int succeededUploadCount, final int failedUploadCount) { + if (inProgressCount < 0) { + LOG.error("IllegalState: \n{}", + getStateListLogMessage(overallUploadCount, succeededUploadCount, failedUploadCount)); + } + } + + private static String getStateListLogMessage(final int overallUploadCount, final int succeededUploadCount, + final int failedUploadCount) { + final StringBuilder buffer = new StringBuilder(); + buffer.append("Overall uploads: " + overallUploadCount); + buffer.append("| succeeded uploads: " + succeededUploadCount); + buffer.append("| Failed Uploads: " + failedUploadCount); + return buffer.toString(); + } + + void clearFileStates() { + getOverallFilesInUploadProcessMap().clear(); + } + + /** + * Clears all temp data collected while uploading files. + */ + public void clearUploadTempData() { + LOG.debug("Cleaning up temp data..."); + // delete file system zombies + for (final FileUploadProgress fileUploadProgress : getAllFileUploadProgressValuesFromOverallUploadProcessList()) { + if (!StringUtils.isBlank(fileUploadProgress.getFilePath())) { + final boolean deleted = FileUtils.deleteQuietly(new File(fileUploadProgress.getFilePath())); + if (!deleted) { + LOG.warn("TempFile was not deleted: " + fileUploadProgress.getFilePath()); + } + } + } + clearFileStates(); + } + + /** + * Checks if an upload is in progress for the given Software Module + * + * @param softwareModuleId + * id of the software module + * @return boolean + */ + public boolean isUploadInProgressForSelectedSoftwareModule(final Long softwareModuleId) { + for (final FileUploadId fileUploadId : getAllFileUploadIdsFromOverallUploadProcessList()) { + if (fileUploadId.getSoftwareModuleId().equals(softwareModuleId)) { + return true; + } + } + return false; + } + + private Map getOverallFilesInUploadProcessMap() { + if (overallFilesInUploadProcess == null) { + overallFilesInUploadProcess = Maps.newConcurrentMap(); + } + return overallFilesInUploadProcess; + } + + private Set getFailedUploads() { + final Collection allFileUploadProgressObjects = getOverallFilesInUploadProcessMap() + .values(); + final Set failedFileUploads = Sets.newHashSet(); + for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) { + if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_FAILED) { + failedFileUploads.add(fileUploadProgress.getFileUploadId()); + } + } + return failedFileUploads; + } + + private Set getSucceededUploads() { + final Collection allFileUploadProgressObjects = getOverallFilesInUploadProcessMap() + .values(); + final Set succeededFileUploads = Sets.newHashSet(); + for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) { + if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_SUCCESSFUL) { + succeededFileUploads.add(fileUploadProgress.getFileUploadId()); + } + } + return succeededFileUploads; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/CustomFile.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/CustomFile.java deleted file mode 100644 index df36f88a0..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/CustomFile.java +++ /dev/null @@ -1,205 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.state; - -import java.io.Serializable; - -/** - * Custom file to hold details of uploaded file. - * - * - * - */ -public class CustomFile implements Serializable { - - private static final long serialVersionUID = -5902321650745311767L; - - private final String fileName; - - private long fileSize; - - private String filePath; - - private String baseSoftwareModuleName; - - private String baseSoftwareModuleVersion; - - private String mimeType; - - /** - * Used to specify if the file is uploaded successfully. - */ - private Boolean isValid = Boolean.TRUE; - - /** - * Reason if upload fails. - */ - private String failureReason; - - /** - * Initialize details. - * - * @param fileName - * uploaded file name - * @param fileSize - * uploaded file size - * @param filePath - * uploaded file path - * @param baseSoftwareModuleName - * software module name - * @param baseSoftwareModuleVersion - * software module version - * @param mimeType - * the mimeType of the file - */ - public CustomFile(final String fileName, final long fileSize, final String filePath, - final String baseSoftwareModuleName, final String baseSoftwareModuleVersion, final String mimeType) { - this.fileName = fileName; - this.fileSize = fileSize; - this.filePath = filePath; - this.baseSoftwareModuleName = baseSoftwareModuleName; - this.baseSoftwareModuleVersion = baseSoftwareModuleVersion; - this.mimeType = mimeType; - } - - /** - * Initialize details. - * - * @param fileName - * uploaded file name - * @param baseSoftwareModuleName - * software module name - * @param baseSoftwareModuleVersion - * software module version - */ - public CustomFile(final String fileName, final String baseSoftwareModuleName, - final String baseSoftwareModuleVersion) { - this.fileName = fileName; - this.baseSoftwareModuleName = baseSoftwareModuleName; - this.baseSoftwareModuleVersion = baseSoftwareModuleVersion; - } - - public String getBaseSoftwareModuleName() { - return baseSoftwareModuleName; - } - - public void setBaseSoftwareModuleName(final String baseSoftwareModuleName) { - this.baseSoftwareModuleName = baseSoftwareModuleName; - } - - public String getBaseSoftwareModuleVersion() { - return baseSoftwareModuleVersion; - } - - public void setBaseSoftwareModuleVersion(final String baseSoftwareModuleVersion) { - this.baseSoftwareModuleVersion = baseSoftwareModuleVersion; - } - - public String getFileName() { - return fileName; - } - - public long getFileSize() { - return fileSize; - } - - public void setFileSize(final long fileSize) { - this.fileSize = fileSize; - } - - public String getFilePath() { - return filePath; - } - - public void setFilePath(final String filePath) { - this.filePath = filePath; - } - - public String getMimeType() { - return mimeType; - } - - /** - * - * @return the isValid - */ - public Boolean getIsValid() { - return isValid; - } - - /** - * @param isValid - * the isValid to set - */ - public void setIsValid(final Boolean isValid) { - this.isValid = isValid; - } - - /** - * @param mimeType - * the mimeType to set - */ - public void setMimeType(final String mimeType) { - this.mimeType = mimeType; - } - - /** - * @return the failureReason - */ - public String getFailureReason() { - return failureReason; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((baseSoftwareModuleName == null) ? 0 : baseSoftwareModuleName.hashCode()); - result = prime * result + ((baseSoftwareModuleVersion == null) ? 0 : baseSoftwareModuleVersion.hashCode()); - result = prime * result + ((fileName == null) ? 0 : fileName.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final CustomFile other = (CustomFile) obj; - if (baseSoftwareModuleName == null) { - if (other.baseSoftwareModuleName != null) { - return false; - } - } else if (!baseSoftwareModuleName.equals(other.baseSoftwareModuleName)) { - return false; - } - if (baseSoftwareModuleVersion == null) { - if (other.baseSoftwareModuleVersion != null) { - return false; - } - } else if (!baseSoftwareModuleVersion.equals(other.baseSoftwareModuleVersion)) { - return false; - } - if (fileName == null) { - if (other.fileName != null) { - return false; - } - } else if (!fileName.equals(other.fileName)) { - return false; - } - return true; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/SoftwareModuleFilters.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/SoftwareModuleFilters.java index adbc40c29..4ea48f7c2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/SoftwareModuleFilters.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/state/SoftwareModuleFilters.java @@ -17,7 +17,7 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; /** - * Softwrae module filters. + * Software module filters. * * */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java new file mode 100644 index 000000000..8f727b0cc --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/AbstractFileTransferHandler.java @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; +import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException; +import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException; +import org.eclipse.hawkbit.repository.model.Artifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; +import org.eclipse.hawkbit.ui.utils.SpringContextHelper; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.vaadin.spring.events.EventBus; +import org.vaadin.spring.events.EventBus.UIEventBus; + +import com.google.common.io.ByteStreams; + +/** + * Abstract base class for transferring files from the browser to the + * repository. + */ +public abstract class AbstractFileTransferHandler implements Serializable { + + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(AbstractFileTransferHandler.class); + + private volatile boolean duplicateFile; + + private volatile boolean uploadInterrupted; + + private volatile String tempFilePath; + + private volatile String failureReason; + + private final ArtifactUploadState artifactUploadState; + + private final transient UIEventBus eventBus; + + private final transient ArtifactManagement artifactManagement; + + private final VaadinMessageSource i18n; + + AbstractFileTransferHandler(final ArtifactManagement artifactManagement, final VaadinMessageSource i18n) { + this.artifactManagement = artifactManagement; + this.i18n = i18n; + this.eventBus = SpringContextHelper.getBean(EventBus.UIEventBus.class); + this.artifactUploadState = SpringContextHelper.getBean(ArtifactUploadState.class); + } + + protected boolean isDuplicateFile() { + return duplicateFile; + } + + protected void setDuplicateFile() { + uploadInterrupted = true; + duplicateFile = true; + } + + protected void setUploadInterrupted() { + uploadInterrupted = true; + } + + protected boolean isUploadInterrupted() { + return uploadInterrupted; + } + + protected void resetState() { + duplicateFile = false; + uploadInterrupted = false; + failureReason = null; + } + + protected ArtifactUploadState getUploadState() { + return artifactUploadState; + } + + protected VaadinMessageSource getI18n() { + return i18n; + } + + private void setFailureReason(final String failureReason) { + this.failureReason = failureReason; + } + + protected void setFailureReasonUploadFailed() { + setFailureReason(i18n.getMessage("message.upload.failed")); + } + + protected void setFailureReasonFileSizeExceeded(final long maxSize) { + setFailureReason(i18n.getMessage("message.uploadedfile.size.exceeded", maxSize)); + } + + protected boolean isFileAlreadyContainedInSoftwareModule(final FileUploadId newFileUploadId, + final SoftwareModule softwareModule) { + for (final Artifact artifact : softwareModule.getArtifacts()) { + final FileUploadId existingId = new FileUploadId(artifact.getFilename(), softwareModule); + if (existingId.equals(newFileUploadId)) { + return true; + } + } + + return false; + } + + protected void publishUploadStarted(final FileUploadId fileUploadId) { + LOG.info("Upload started for file {}", fileUploadId); + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, FileUploadStatus.UPLOAD_STARTED); + artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); + eventBus.publish(this, fileUploadProgress); + } + + protected void publishUploadProgressEvent(final FileUploadId fileUploadId, final long bytesReceived, + final long fileSize, final String tempFilePath) { + if (LOG.isTraceEnabled()) { + LOG.trace("Upload in progress for file {} - {}%", fileUploadId, + String.format("%.0f", (double) bytesReceived / (double) fileSize * 100)); + } + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_IN_PROGRESS, bytesReceived, fileSize, tempFilePath); + artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); + eventBus.publish(this, fileUploadProgress); + } + + private void publishUploadSucceeded(final FileUploadId fileUploadId, final long fileSize, + final String tempFilePath) { + LOG.info("Upload succeeded for file {}", fileUploadId); + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_SUCCESSFUL, fileSize, fileSize, tempFilePath); + artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); + eventBus.publish(this, fileUploadProgress); + } + + protected void publishUploadFinishedEvent(final FileUploadId fileUploadId) { + LOG.info("Upload finished for file {}", fileUploadId); + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_FINISHED); + eventBus.publish(this, fileUploadProgress); + } + + protected void publishUploadFailedEvent(final FileUploadId fileUploadId, final String failureReason, + final Exception uploadException) { + LOG.info("Upload failed for file {} due to {}", fileUploadId, + StringUtils.isBlank(failureReason) ? uploadException.getMessage() : failureReason); + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_FAILED, + StringUtils.isBlank(failureReason) ? uploadException.getMessage() : failureReason); + artifactUploadState.updateFileUploadProgress(fileUploadId, fileUploadProgress); + eventBus.publish(this, fileUploadProgress); + } + + protected void publishUploadFailedEvent(final FileUploadId fileUploadId, final Exception uploadException) { + publishUploadFailedEvent(fileUploadId, failureReason, uploadException); + } + + protected void assertStateConsistency(final FileUploadId fileUploadId, final String filenameExtractedFromEvent) { + if (!filenameExtractedFromEvent.equals(fileUploadId.getFilename())) { + throw new IllegalStateException("Event filename " + filenameExtractedFromEvent + " but stored filename " + + fileUploadId.getFilename()); + } + } + + protected OutputStream createOutputStreamForTempFile() throws IOException { + + if (isUploadInterrupted()) { + return ByteStreams.nullOutputStream(); + } + + final File tempFile = File.createTempFile("spUiArtifactUpload", null); + + // we return the outputstream so we cannot close it here + @SuppressWarnings("squid:S2095") + final OutputStream out = new FileOutputStream(tempFile); + + tempFilePath = tempFile.getAbsolutePath(); + + return out; + } + + protected String getTempFilePath() { + return tempFilePath; + } + + // Exception squid:S3655 - Optional access is checked in + // checkIfArtifactDetailsDispalyed subroutine + @SuppressWarnings("squid:S3655") + protected void transferArtifactToRepository(final FileUploadId fileUploadId, final long fileSize, + final String mimeType, final String tempFilePath) { + + final File newFile = new File(tempFilePath); + + final String filename = fileUploadId.getFilename(); + LOG.info("Transfering tempfile {} - {} to repository", filename, tempFilePath); + try (FileInputStream fis = new FileInputStream(newFile)) { + + artifactManagement.create(fis, fileUploadId.getSoftwareModuleId(), filename, null, null, true, mimeType, + fileSize); + + publishUploadSucceeded(fileUploadId, fileSize, tempFilePath); + + eventBus.publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, + fileUploadId.getSoftwareModuleId())); + + } catch (final ArtifactUploadFailedException | InvalidSHA1HashException | InvalidMD5HashException + | IOException e) { + publishUploadFailedEvent(fileUploadId, i18n.getMessage("message.upload.failed"), e); + LOG.error("Failed to transfer file to repository", e); + } finally { + LOG.debug("Deleting tempfile {} - {}", filename, newFile.getAbsolutePath()); + if (newFile.exists() && !newFile.delete()) { + LOG.error("Could not delete temporary file: {}", newFile.getAbsolutePath()); + } + } + + publishUploadFinishedEvent(fileUploadId); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java new file mode 100644 index 000000000..af8dc425c --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerStreamVariable.java @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.IOException; +import java.io.OutputStream; + +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.ByteStreams; +import com.vaadin.server.StreamVariable; +import com.vaadin.ui.Upload.FinishedEvent; +import com.vaadin.ui.Upload.SucceededEvent; + +/** + * {@link StreamVariable} implementation to read and upload a file. One instance + * per file stream is used. + * + * The handler manages the output to the user and at the same time ensures that + * the upload does not exceed the configured max file size. + * + */ +public class FileTransferHandlerStreamVariable extends AbstractFileTransferHandler implements StreamVariable { + + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(FileTransferHandlerStreamVariable.class); + + private final long maxSize; + private final long fileSize; + private final String mimeType; + private final FileUploadId fileUploadId; + + private final SoftwareModule selectedSoftwareModule; + + FileTransferHandlerStreamVariable(final String fileName, final long fileSize, final long maxSize, + final String mimeType, final SoftwareModule selectedSw, final ArtifactManagement artifactManagement, + final VaadinMessageSource i18n) { + super(artifactManagement, i18n); + this.fileSize = fileSize; + this.maxSize = maxSize; + this.mimeType = mimeType; + this.selectedSoftwareModule = selectedSw; + this.fileUploadId = new FileUploadId(fileName, selectedSw); + + publishUploadStarted(fileUploadId); + } + + @Override + public void streamingStarted(final StreamingStartEvent event) { + assertStateConsistency(fileUploadId, event.getFileName()); + + if (isFileAlreadyContainedInSoftwareModule(fileUploadId, selectedSoftwareModule)) { + LOG.info("File {} already contained in Software Module {}", fileUploadId.getFilename(), + selectedSoftwareModule); + getUploadState().updateFileUploadProgress(fileUploadId, + new FileUploadProgress(fileUploadId, FileUploadStatus.UPLOAD_FAILED)); + setDuplicateFile(); + } + } + + @Override + public final OutputStream getOutputStream() { + + // we return the outputstream so we cannot close it here + @SuppressWarnings("squid:S2095") + OutputStream outputStream = ByteStreams.nullOutputStream(); + try { + outputStream = createOutputStreamForTempFile(); + publishUploadProgressEvent(fileUploadId, 0, fileSize, getTempFilePath()); + + } catch (final IOException e) { + LOG.error("Creating temp file for upload failed {}.", e); + try { + outputStream.close(); + } catch (final IOException e1) { + LOG.error("Closing output stream caused an exception {}", e1); + } + + setFailureReasonUploadFailed(); + setUploadInterrupted(); + } + + return outputStream; + } + + /** + * listen progress. + * + * @return boolean + */ + @Override + public boolean listenProgress() { + return true; + } + + /** + * Reports progress in {@link StreamVariable} variant. Interrupts + * + * @see com.vaadin.server.StreamVariable#onProgress(com.vaadin.server.StreamVariable.StreamingProgressEvent) + */ + @Override + public void onProgress(final StreamingProgressEvent event) { + assertStateConsistency(fileUploadId, event.getFileName()); + + if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { + LOG.error("User tried to upload more than was allowed ({}).", maxSize); + setFailureReasonFileSizeExceeded(maxSize); + setUploadInterrupted(); + return; + } + if (isUploadInterrupted()) { + return; + } + + publishUploadProgressEvent(fileUploadId, event.getBytesReceived(), event.getContentLength(), getTempFilePath()); + } + + /** + * Upload finished for {@link StreamVariable} variant. Called only in good + * case. So a combination of {@link #uploadSucceeded(SucceededEvent)} and + * {@link #uploadFinished(FinishedEvent)}. + * + * @see com.vaadin.server.StreamVariable#streamingFinished(com.vaadin.server.StreamVariable.StreamingEndEvent) + */ + @Override + public void streamingFinished(final StreamingEndEvent event) { + assertStateConsistency(fileUploadId, event.getFileName()); + + transferArtifactToRepository(fileUploadId, event.getContentLength(), mimeType, getTempFilePath()); + } + + /** + * Upload failed for{@link StreamVariable} variant. + * + * @param event + * StreamingEndEvent + */ + @Override + public void streamingFailed(final StreamingErrorEvent event) { + assertStateConsistency(fileUploadId, event.getFileName()); + + if (isDuplicateFile()) { + publishUploadFailedEvent(fileUploadId, getI18n().getMessage("message.no.duplicateFiles"), + event.getException()); + } else { + publishUploadFailedEvent(fileUploadId, event.getException()); + } + publishUploadFinishedEvent(fileUploadId); + } + + @Override + public boolean isInterrupted() { + return isUploadInterrupted(); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java new file mode 100644 index 000000000..08589c5eb --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileTransferHandlerVaadinUpload.java @@ -0,0 +1,226 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Optional; + +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.ByteStreams; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.FailedEvent; +import com.vaadin.ui.Upload.FailedListener; +import com.vaadin.ui.Upload.FinishedEvent; +import com.vaadin.ui.Upload.FinishedListener; +import com.vaadin.ui.Upload.ProgressListener; +import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload.StartedEvent; +import com.vaadin.ui.Upload.StartedListener; +import com.vaadin.ui.Upload.SucceededEvent; +import com.vaadin.ui.Upload.SucceededListener; + +/** + * Vaadin Upload implementation to read and upload a file. One instance is used + * to handle all the uploads. + * + * The handler manages the output to the user and at the same time ensures that + * the upload does not exceed the configured max file size. + * + */ +public class FileTransferHandlerVaadinUpload extends AbstractFileTransferHandler + implements Receiver, SucceededListener, FailedListener, FinishedListener, ProgressListener, StartedListener { + + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(FileTransferHandlerVaadinUpload.class); + + private final transient SoftwareModuleManagement softwareModuleManagement; + private final long maxSize; + + private volatile String mimeType; + private volatile FileUploadId fileUploadId; + + FileTransferHandlerVaadinUpload(final long maxSize, final SoftwareModuleManagement softwareManagement, + final ArtifactManagement artifactManagement, final VaadinMessageSource i18n) { + super(artifactManagement, i18n); + this.maxSize = maxSize; + this.softwareModuleManagement = softwareManagement; + } + + /** + * Upload started for {@link Upload} variant. + * + * @see com.vaadin.ui.Upload.StartedListener#uploadStarted(com.vaadin.ui.Upload.StartedEvent) + */ + @Override + public void uploadStarted(final StartedEvent event) { + // reset internal state here because instance is reused for next upload! + resetState(); + this.mimeType = null; + this.fileUploadId = null; + + assertThatOneSoftwareModuleIsSelected(); + + // selected software module at the time of this callback is considered + SoftwareModule softwareModule = null; + final Optional selectedSoftwareModuleId = getUploadState().getSelectedBaseSwModuleId(); + final Long softwareModuleId = selectedSoftwareModuleId.orElse(null); + if (softwareModuleId != null) { + softwareModule = softwareModuleManagement.get(softwareModuleId).orElse(null); + } + + this.fileUploadId = new FileUploadId(event.getFilename(), softwareModule); + this.mimeType = event.getMIMEType(); + + if (getUploadState().isFileInUploadState(this.fileUploadId)) { + setFailureReasonUploadFailed(); + // actual interrupt will happen a bit late so setting the below + // flag + setDuplicateFile(); + event.getUpload().interruptUpload(); + } else { + LOG.info("Uploading file {}", fileUploadId); + publishUploadStarted(fileUploadId); + + if (isFileAlreadyContainedInSoftwareModule(fileUploadId, softwareModule)) { + LOG.info("File {} already contained in Software Module {}", fileUploadId.getFilename(), softwareModule); + getUploadState().updateFileUploadProgress(fileUploadId, + new FileUploadProgress(fileUploadId, FileUploadStatus.UPLOAD_FAILED)); + setDuplicateFile(); + event.getUpload().interruptUpload(); + } + } + } + + private void assertThatOneSoftwareModuleIsSelected() { + // FileUpload button should be disabled if no SoftwareModul or more + // than one is selected! + if (getUploadState().isNoSoftwareModuleSelected()) { + throw new IllegalStateException("No SoftwareModul selected"); + } else if (getUploadState().isMoreThanOneSoftwareModulesSelected()) { + throw new IllegalStateException("More than one SoftwareModul selected but only one is allowed"); + } + } + + /** + * Create stream for {@link Upload} variant. + * + * @see com.vaadin.ui.Upload.Receiver#receiveUpload(java.lang.String, + * java.lang.String) + */ + @Override + public OutputStream receiveUpload(final String fileName, final String mimeType) { + + if (isUploadInterrupted()) { + return ByteStreams.nullOutputStream(); + } + + // we return the outputstream so we cannot close it here + @SuppressWarnings("squid:S2095") + OutputStream outputStream = ByteStreams.nullOutputStream(); + try { + outputStream = createOutputStreamForTempFile(); + this.mimeType = mimeType; + publishUploadProgressEvent(fileUploadId, 0, 0, getTempFilePath()); + + } catch (final IOException e) { + LOG.error("Creating temp file for upload failed {}.", e); + if (outputStream != null) { + try { + outputStream.close(); + } catch (final IOException e1) { + LOG.error("Closing output stream caused an exception {}", e1); + } + } + + setFailureReasonUploadFailed(); + setUploadInterrupted(); + } + + return outputStream; + } + + /** + * Reports progress in {@link Upload} variant. + * + * @see com.vaadin.ui.Upload.ProgressListener#updateProgress(long, long) + */ + @Override + public void updateProgress(final long readBytes, final long contentLength) { + if (readBytes > maxSize || contentLength > maxSize) { + LOG.error("User tried to upload more than was allowed ({}).", maxSize); + setFailureReasonFileSizeExceeded(maxSize); + setUploadInterrupted(); + return; + } + if (isUploadInterrupted()) { + // Upload interruption is delayed maybe another event is fired + // before + return; + } + + publishUploadProgressEvent(fileUploadId, readBytes, contentLength, getTempFilePath()); + } + + /** + * + * Upload sucessfull for {@link Upload} variant. + * + * @see com.vaadin.ui.Upload.SucceededListener#uploadSucceeded(com.vaadin.ui.Upload.SucceededEvent) + */ + @Override + public void uploadSucceeded(final SucceededEvent event) { + if (isUploadInterrupted()) { + // Upload interruption is delayed maybe another event is fired + // before + return; + } + assertStateConsistency(fileUploadId, event.getFilename()); + + transferArtifactToRepository(fileUploadId, event.getLength(), mimeType, getTempFilePath()); + } + + /** + * Upload finished for {@link Upload} variant. Both for good and error + * variant. + * + * @see com.vaadin.ui.Upload.FinishedListener#uploadFinished(com.vaadin.ui.Upload.FinishedEvent) + */ + @Override + public void uploadFinished(final FinishedEvent event) { + // ignore this event + } + + /** + * Upload failed for {@link Upload} variant. + * + * @see com.vaadin.ui.Upload.FailedListener#uploadFailed(com.vaadin.ui.Upload.FailedEvent) + */ + @Override + public void uploadFailed(final FailedEvent event) { + assertStateConsistency(fileUploadId, event.getFilename()); + + if (isDuplicateFile()) { + publishUploadFailedEvent(fileUploadId, getI18n().getMessage("message.no.duplicateFiles"), + event.getReason()); + } else { + publishUploadFailedEvent(fileUploadId, event.getReason()); + } + publishUploadFinishedEvent(fileUploadId); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java new file mode 100644 index 000000000..881a03071 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadId.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.Serializable; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; + +/** + * The {@link FileUploadId} identifies a file that is uploaded for a + * {@link SoftwareModule}. + * + */ +public class FileUploadId implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String filename; + + private final String softwareModuleName; + + private final String softwareModuleVersion; + + private Long softwareModuleId; + + private final String id; + + /** + * Creates a new {@link FileUploadId} instance. + * + * @param filename + * the name of the file + * @param softwareModule + * the {@link SoftwareModule} for which the file is uploaded + */ + public FileUploadId(final String filename, final SoftwareModule softwareModule) { + this.filename = filename; + this.softwareModuleName = softwareModule.getName(); + this.softwareModuleVersion = softwareModule.getVersion(); + this.softwareModuleId = softwareModule.getId(); + this.id = createFileUploadIdString(filename, softwareModuleName, softwareModuleVersion); + } + + /** + * Creates a new {@link FileUploadId} instance. + * + * @param filename + * the name of the file + * @param softwareModuleName + * the name of a {@link SoftwareModule} for which the file is + * uploaded + * @param softwareModuleVersion + * the version of a {@link SoftwareModule} for which the file is + * uploaded + */ + public FileUploadId(final String filename, final String softwareModuleName, final String softwareModuleVersion) { + this.filename = filename; + this.softwareModuleName = softwareModuleName; + this.softwareModuleVersion = softwareModuleVersion; + this.id = createFileUploadIdString(filename, softwareModuleName, softwareModuleVersion); + } + + private static String createFileUploadIdString(final String filename, final String softwareModuleName, + final String softwareModuleVersion) { + return new StringBuilder(filename).append(":") + .append(HawkbitCommonUtil.getFormattedNameVersion(softwareModuleName, softwareModuleVersion)) + .toString(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FileUploadId other = (FileUploadId) obj; + return new EqualsBuilder().append(id, other.id).isEquals(); + } + + + @Override + public int hashCode() { + return new HashCodeBuilder().append(id).toHashCode(); + } + + @Override + public String toString() { + return id; + } + + public String getFilename() { + return filename; + } + + public String getSoftwareModuleName() { + return softwareModuleName; + } + + public String getSoftwareModuleVersion() { + return softwareModuleVersion; + } + + public Long getSoftwareModuleId() { + return softwareModuleId; + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java new file mode 100644 index 000000000..2f1034a58 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/FileUploadProgress.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.Serializable; + +/** + * Holds file and upload progress details. + */ +public class FileUploadProgress implements Serializable { + + /** + * Status of a file upload. + */ + public enum FileUploadStatus { + + /** + * An upload for a file has been started. + */ + UPLOAD_STARTED, + + /** + * Progress changed for one file upload. + */ + UPLOAD_IN_PROGRESS, + + /** + * Upload of one file failed. + */ + UPLOAD_FAILED, + + /** + * One file upload succeeded. + */ + UPLOAD_SUCCESSFUL, + + /** + * One file upload finished () + */ + UPLOAD_FINISHED + } + + private static final long serialVersionUID = 1L; + + private final FileUploadId fileUploadId; + + private long contentLength; + + private long bytesRead; + + private String failureReason; + + private String filePath; + + private final FileUploadStatus fileUploadStatus; + + + /** + * Creates a new {@link FileUploadProgress} instance. + * + * @param fileUploadId + * the {@link FileUploadId} to which this progress information + * belongs. + * @param fileUploadStatus + * the {@link FileUploadStatus} of this progress + */ + public FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus) { + this.fileUploadId = fileUploadId; + this.fileUploadStatus = fileUploadStatus; + } + + /** + * Creates a new {@link FileUploadProgress} instance. + * + * @param fileUploadId + * the {@link FileUploadId} to which this progress information + * belongs. + * @param fileUploadStatus + * the {@link FileUploadStatus} of this progress + * @param bytesRead + * number of bytes read + * @param contentLength + * size of the file in bytes + * @param filePath + * the path of the file + */ + FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus, + final long bytesRead, final long contentLength, + final String filePath) { + this.fileUploadId = fileUploadId; + this.fileUploadStatus = fileUploadStatus; + this.contentLength = contentLength; + this.bytesRead = bytesRead; + this.filePath = filePath; + } + + /** + * Creates a new {@link FileUploadProgress} instance. + * + * @param fileUploadId + * the {@link FileUploadId} to which this progress information + * belongs. + * @param fileUploadStatus + * the {@link FileUploadStatus} of this progress + * @param failureReason + * the reason of the failed upload + */ + FileUploadProgress(final FileUploadId fileUploadId, final FileUploadStatus fileUploadStatus, + final String failureReason) { + this.fileUploadId = fileUploadId; + this.fileUploadStatus = fileUploadStatus; + this.failureReason = failureReason; + } + + public FileUploadId getFileUploadId() { + return fileUploadId; + } + + public long getContentLength() { + return contentLength; + } + + public long getBytesRead() { + return bytesRead; + } + + public String getFailureReason() { + return failureReason; + } + + public String getFilePath() { + return filePath; + } + + public FileUploadStatus getFileUploadStatus() { + return fileUploadStatus; + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java deleted file mode 100644 index 23e54796a..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationWindow.java +++ /dev/null @@ -1,687 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; -import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException; -import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException; -import org.eclipse.hawkbit.repository.exception.QuotaExceededException; -import org.eclipse.hawkbit.repository.model.Artifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.state.CustomFile; -import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.server.FontAwesome; -import com.vaadin.server.Page; -import com.vaadin.shared.ui.label.ContentMode; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Table; -import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Artifact upload confirmation popup. - * - */ -public class UploadConfirmationWindow implements Button.ClickListener { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(UploadConfirmationWindow.class); - - private static final String MD5_CHECKSUM = "md5Checksum"; - - private static final String SHA1_CHECKSUM = "sha1Checksum"; - - private static final String FILE_NAME = "fileName"; - - private static final String SW_MODULE_NAME = "swModuleName"; - - private static final String SIZE = "size"; - - private static final String ACTION = "action"; - - private static final String BASE_SOFTWARE_ID = "softwareModuleId"; - - private static final String FILE_NAME_LAYOUT = "fileNameLayout"; - - private static final String WARNING_ICON = "warningIcon"; - - private static final String CUSTOM_FILE = "customFile"; - - private static final String ARTIFACT_UPLOAD_EXCEPTION = "Artifact upload exception:"; - - private static final String ALREADY_EXISTS_MSG = "upload.artifact.alreadyExists"; - - private final VaadinMessageSource i18n; - - private Window window; - - private Button uploadBtn; - - private Button cancelBtn; - - private Table uploadDetailsTable; - - private final UploadLayout uploadLayout; - - private IndexedContainer tableContainer; - - private final List uploadResultList = new ArrayList<>(); - - private VerticalLayout uploadArtifactDetails; - - private UploadResultWindow currentUploadResultWindow; - - private int redErrorLabelCount; - - private final ArtifactUploadState artifactUploadState; - - private final transient UIEventBus eventBus; - - private final transient ArtifactManagement artifactManagement; - - /** - * Initialize the upload confirmation window. - * - * @param artifactUploadView - * reference of upload layout. - * @param artifactUploadState - * reference of session variable {@link ArtifactUploadState}. - */ - UploadConfirmationWindow(final UploadLayout artifactUploadView, final ArtifactUploadState artifactUploadState, - final UIEventBus eventBus, final ArtifactManagement artifactManagement) { - this.uploadLayout = artifactUploadView; - this.artifactUploadState = artifactUploadState; - this.eventBus = eventBus; - this.artifactManagement = artifactManagement; - i18n = artifactUploadView.getI18n(); - createRequiredComponents(); - buildLayout(); - } - - private boolean checkIfArtifactDetailsDisplayed(final Long bSoftwareModuleId) { - return artifactUploadState.getSelectedBaseSwModuleId().map(moduleId -> moduleId.equals(bSoftwareModuleId)) - .orElse(false); - } - - private Boolean preUploadValidation(final List itemIds) { - Boolean validationSuccess = true; - for (final String itemId : itemIds) { - final Item item = tableContainer.getItem(itemId); - final String providedFileName = (String) item.getItemProperty(FILE_NAME).getValue(); - if (!StringUtils.hasText(providedFileName)) { - validationSuccess = false; - break; - } - } - return validationSuccess; - } - - private void createRequiredComponents() { - uploadBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_BUTTON, SPUILabelDefinitions.SUBMIT, - SPUILabelDefinitions.SUBMIT, ValoTheme.BUTTON_PRIMARY, false, null, SPUIButtonStyleTiny.class); - uploadBtn.addClickListener(this); - cancelBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_DISCARD_DETAILS_BUTTON, - SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, - SPUIButtonStyleTiny.class); - cancelBtn.addClickListener(this); - - uploadDetailsTable = new Table(); - uploadDetailsTable.addStyleName("artifact-table"); - uploadDetailsTable.setSizeFull(); - uploadDetailsTable.setId(UIComponentIdProvider.UPLOAD_ARTIFACT_DETAILS_TABLE); - uploadDetailsTable.addStyleName(ValoTheme.TABLE_BORDERLESS); - uploadDetailsTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); - uploadDetailsTable.addStyleName(ValoTheme.TABLE_SMALL); - - setTableContainer(); - populateUploadDetailsTable(); - } - - /** - * Warning icon is displayed, if an artifact exists with same provided file - * name. Error icon is displayed, if file name entered is duplicate. - * - * @param warningIconLabel - * warning/error label - * @param fileName - * provided file name - * @param itemId - * item id of the current row - */ - private void setWarningIcon(final Label warningIconLabel, final String fileName, final Object itemId) { - final Item item = uploadDetailsTable.getItem(itemId); - if (StringUtils.hasText(fileName)) { - final String fileNameTrimmed = StringUtils.trimWhitespace(fileName); - final Long baseSwId = (Long) item.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final Optional artifact = artifactManagement.getByFilenameAndSoftwareModule(fileNameTrimmed, - baseSwId); - if (artifact.isPresent()) { - warningIconLabel.setVisible(true); - if (isErrorIcon(warningIconLabel)) { - warningIconLabel.removeStyleName(SPUIStyleDefinitions.ERROR_LABEL); - redErrorLabelCount--; - } - warningIconLabel.setDescription(i18n.getMessage(ALREADY_EXISTS_MSG)); - if (checkForDuplicate(fileNameTrimmed, itemId, baseSwId)) { - warningIconLabel.setDescription(i18n.getMessage("message.duplicate.filename")); - warningIconLabel.addStyleName(SPUIStyleDefinitions.ERROR_LABEL); - redErrorLabelCount++; - } - } else { - warningIconLabel.setVisible(false); - if (warningIconLabel.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL)) { - warningIconLabel.removeStyleName(SPUIStyleDefinitions.ERROR_LABEL); - warningIconLabel.setDescription(i18n.getMessage(ALREADY_EXISTS_MSG)); - redErrorLabelCount--; - } - } - } - } - - private Boolean checkForDuplicate(final String fileName, final Object itemId, final Long currentBaseSwId) { - for (final Object newItemId : tableContainer.getItemIds()) { - final Item newItem = tableContainer.getItem(newItemId); - final Long newBaseSwId = (Long) newItem.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final String newFileName = (String) newItem.getItemProperty(FILE_NAME).getValue(); - if (!newItemId.equals(itemId) && newBaseSwId.equals(currentBaseSwId) && newFileName.equals(fileName)) { - return true; - } - } - return false; - } - - private void populateUploadDetailsTable() { - for (final CustomFile customFile : uploadLayout.getFileSelected()) { - final String swNameVersion = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - final String itemId = swNameVersion + "/" + customFile.getFileName(); - final Item newItem = tableContainer.addItem(itemId); - final SoftwareModule bSoftwareModule = artifactUploadState.getBaseSwModuleList().get(swNameVersion); - newItem.getItemProperty(BASE_SOFTWARE_ID).setValue(bSoftwareModule.getId()); - - addFileNameLayout(newItem, swNameVersion, customFile.getFileName(), itemId); - - newItem.getItemProperty(SW_MODULE_NAME).setValue(HawkbitCommonUtil.getFormatedLabel(swNameVersion)); - newItem.getItemProperty(SIZE).setValue(customFile.getFileSize()); - final Button deleteIcon = SPUIComponentProvider.getButton( - UIComponentIdProvider.UPLOAD_DELETE_ICON + "-" + itemId, "", SPUILabelDefinitions.DISCARD, - ValoTheme.BUTTON_TINY + " " + "blueicon", true, FontAwesome.TRASH_O, - SPUIButtonStyleSmallNoBorder.class); - deleteIcon.addClickListener(this); - deleteIcon.setData(itemId); - newItem.getItemProperty(ACTION).setValue(deleteIcon); - - final TextField sha1 = createTextField(swNameVersion + "/" + customFile.getFileName() + "/sha1"); - - final TextField md5 = createTextField(swNameVersion + "/" + customFile.getFileName() + "/md5"); - - createTextField(swNameVersion + "/" + customFile.getFileName() + "/customFileName"); - - newItem.getItemProperty(SHA1_CHECKSUM).setValue(sha1); - newItem.getItemProperty(MD5_CHECKSUM).setValue(md5); - newItem.getItemProperty(CUSTOM_FILE).setValue(customFile); - } - } - - private static TextField createTextField(final String id) { - return new TextFieldBuilder(64).id(id).buildTextComponent(); - } - - private void addFileNameLayout(final Item newItem, final String baseSoftwareModuleNameVersion, - final String customFileName, final String itemId) { - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - final TextField fileNameTextField = createTextField( - baseSoftwareModuleNameVersion + "/" + customFileName + "/customFileName"); - fileNameTextField.setData(baseSoftwareModuleNameVersion + "/" + customFileName); - fileNameTextField.setValue(customFileName); - - newItem.getItemProperty(FILE_NAME).setValue(fileNameTextField.getValue()); - - final Label warningIconLabel = getWarningLabel(); - warningIconLabel.setId(baseSoftwareModuleNameVersion + "/" + customFileName + "/icon"); - setWarningIcon(warningIconLabel, fileNameTextField.getValue(), itemId); - newItem.getItemProperty(WARNING_ICON).setValue(warningIconLabel); - - horizontalLayout.addComponent(fileNameTextField); - horizontalLayout.setComponentAlignment(fileNameTextField, Alignment.MIDDLE_LEFT); - horizontalLayout.addComponent(warningIconLabel); - horizontalLayout.setComponentAlignment(warningIconLabel, Alignment.MIDDLE_RIGHT); - newItem.getItemProperty(FILE_NAME_LAYOUT).setValue(horizontalLayout); - - fileNameTextField.addTextChangeListener(event -> onFileNameChange(event, warningIconLabel, newItem)); - } - - private void onFileNameChange(final TextChangeEvent event, final Label warningIconLabel, final Item newItem) { - - final String itemId = (String) ((TextField) event.getComponent()).getData(); - final String fileName = event.getText(); - - final Boolean isWarningIconDisplayed = isWarningIcon(warningIconLabel); - setWarningIcon(warningIconLabel, fileName, itemId); - - final Long currentSwId = (Long) newItem.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final String oldFileName = (String) newItem.getItemProperty(FILE_NAME).getValue(); - newItem.getItemProperty(FILE_NAME).setValue(event.getText()); - - // if warning was displayed prior and not displayed currently - if (isWarningIconDisplayed && !warningIconLabel.isVisible()) { - modifyIconOfSameSwId(itemId, currentSwId, oldFileName); - } - checkDuplicateEntry(itemId, currentSwId, event.getText(), oldFileName); - enableOrDisableUploadBtn(); - } - - private void enableOrDisableUploadBtn() { - if (redErrorLabelCount == 0) { - uploadBtn.setEnabled(true); - } else { - uploadBtn.setEnabled(false); - } - } - - /** - * If warning was displayed prior and not displayed currently ,the update - * other warning labels accordingly. - * - * @param itemId - * id of row which is deleted/whose file name modified. - * @param oldSwId - * software module id - * @param oldFileName - * file name before modification - */ - private void modifyIconOfSameSwId(final Object itemId, final Long oldSwId, final String oldFileName) { - for (final Object rowId : tableContainer.getItemIds()) { - final Item newItem = tableContainer.getItem(rowId); - final Long newBaseSwId = (Long) newItem.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final String newFileName = (String) newItem.getItemProperty(FILE_NAME).getValue(); - if (!rowId.equals(itemId) && newBaseSwId.equals(oldSwId) && newFileName.equals(oldFileName)) { - final HorizontalLayout layout = (HorizontalLayout) newItem.getItemProperty(FILE_NAME_LAYOUT).getValue(); - final Label warningLabel = (Label) layout.getComponent(1); - if (warningLabel.isVisible()) { - warningLabel.removeStyleName(SPUIStyleDefinitions.ERROR_LABEL); - warningLabel.setDescription(i18n.getMessage(ALREADY_EXISTS_MSG)); - newItem.getItemProperty(WARNING_ICON).setValue(warningLabel); - redErrorLabelCount--; - break; - } - } - } - } - - /** - * Check if icon is warning icon and visible. - * - * @param icon - * label - * @return Boolean - */ - private static boolean isWarningIcon(final Label icon) { - return !isErrorIcon(icon); - } - - /** - * Check if icon is error icon and visible. - * - * @param icon - * label - * @return Boolean - */ - private static boolean isErrorIcon(final Label icon) { - return icon.isVisible() && icon.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL); - } - - private static Label getWarningLabel() { - final Label warningIconLabel = new Label(); - warningIconLabel.addStyleName(ValoTheme.LABEL_SMALL); - warningIconLabel.setHeightUndefined(); - warningIconLabel.setContentMode(ContentMode.HTML); - warningIconLabel.setValue(FontAwesome.WARNING.getHtml()); - warningIconLabel.addStyleName("warningLabel"); - warningIconLabel.setVisible(false); - return warningIconLabel; - } - - private void newFileNameIsDuplicate(final Object itemId, final Long currentSwId, final String currentChangedText) { - for (final Object rowId : tableContainer.getItemIds()) { - final Item currentItem = tableContainer.getItem(itemId); - final Item newItem = tableContainer.getItem(rowId); - final Long newBaseSwId = (Long) newItem.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final String fileName = (String) newItem.getItemProperty(FILE_NAME).getValue(); - if (!rowId.equals(itemId) && newBaseSwId.equals(currentSwId) && fileName.equals(currentChangedText)) { - final HorizontalLayout layout = (HorizontalLayout) currentItem.getItemProperty(FILE_NAME_LAYOUT) - .getValue(); - final Label iconLabel = (Label) layout.getComponent(1); - if (!iconLabel.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL)) { - iconLabel.setVisible(true); - iconLabel.setDescription(i18n.getMessage("message.duplicate.filename")); - iconLabel.addStyleName(SPUIStyleDefinitions.ERROR_LABEL); - redErrorLabelCount++; - } - break; - } - } - } - - private void reValidateOtherFileNamesOfSameBaseSw(final Object itemId, final Long currentSwId, - final String oldFileName) { - Label warningLabel = null; - Label errorLabel = null; - int errorLabelCount = 0; - int duplicateCount = 0; - for (final Object rowId : tableContainer.getItemIds()) { - final Item newItem = tableContainer.getItem(rowId); - final Long newBaseSwId = (Long) newItem.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final String newFileName = (String) newItem.getItemProperty(FILE_NAME).getValue(); - if (!rowId.equals(itemId) && newBaseSwId.equals(currentSwId) && newFileName.equals(oldFileName)) { - final HorizontalLayout layout = (HorizontalLayout) newItem.getItemProperty(FILE_NAME_LAYOUT).getValue(); - final Label icon = (Label) layout.getComponent(1); - duplicateCount++; - if (icon.isVisible()) { - if (!icon.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL)) { - warningLabel = icon; - break; - } - errorLabel = icon; - errorLabelCount++; - } - } - } - hideErrorIcon(warningLabel, errorLabelCount, duplicateCount, errorLabel, oldFileName, currentSwId); - } - - private void hideErrorIcon(final Label warningLabel, final int errorLabelCount, final int duplicateCount, - final Label errorLabel, final String oldFileName, final Long currentSwId) { - if (warningLabel == null && (errorLabelCount > 1 || (duplicateCount == 1 && errorLabelCount == 1))) { - - final Optional artifactList = artifactManagement.getByFilenameAndSoftwareModule(oldFileName, - currentSwId); - if (errorLabel == null) { - return; - } - errorLabel.removeStyleName(SPUIStyleDefinitions.ERROR_LABEL); - errorLabel.setDescription(i18n.getMessage(ALREADY_EXISTS_MSG)); - if (!artifactList.isPresent()) { - errorLabel.setVisible(false); - } - redErrorLabelCount--; - } - } - - private void checkDuplicateEntry(final Object itemId, final Long currentSwId, final String newChangedText, - final String oldFileName) { - /** - * Check if newly entered file name is a duplicate. - */ - newFileNameIsDuplicate(itemId, currentSwId, newChangedText); - /** - * After the current changed file name is validated ,other files of same - * software module as has be revalidated. And icons are updated - * accordingly. - */ - reValidateOtherFileNamesOfSameBaseSw(itemId, currentSwId, oldFileName); - - } - - private void setTableContainer() { - tableContainer = new IndexedContainer(); - tableContainer.addContainerProperty(FILE_NAME_LAYOUT, HorizontalLayout.class, null); - tableContainer.addContainerProperty(SW_MODULE_NAME, Label.class, null); - tableContainer.addContainerProperty(SHA1_CHECKSUM, TextField.class, null); - tableContainer.addContainerProperty(MD5_CHECKSUM, TextField.class, null); - tableContainer.addContainerProperty(SIZE, Long.class, null); - tableContainer.addContainerProperty(ACTION, Button.class, ""); - tableContainer.addContainerProperty(FILE_NAME, String.class, null); - tableContainer.addContainerProperty(BASE_SOFTWARE_ID, Long.class, null); - tableContainer.addContainerProperty(WARNING_ICON, Label.class, null); - tableContainer.addContainerProperty(CUSTOM_FILE, CustomFile.class, null); - - uploadDetailsTable.setContainerDataSource(tableContainer); - uploadDetailsTable.setPageLength(10); - uploadDetailsTable.setColumnHeader(FILE_NAME_LAYOUT, i18n.getMessage("upload.file.name")); - uploadDetailsTable.setColumnHeader(SW_MODULE_NAME, i18n.getMessage("upload.swModuleTable.header")); - uploadDetailsTable.setColumnHeader(SHA1_CHECKSUM, i18n.getMessage("upload.sha1")); - uploadDetailsTable.setColumnHeader(MD5_CHECKSUM, i18n.getMessage("upload.md5")); - uploadDetailsTable.setColumnHeader(SIZE, i18n.getMessage("upload.size")); - uploadDetailsTable.setColumnHeader(ACTION, i18n.getMessage("upload.action")); - - uploadDetailsTable.setColumnExpandRatio(FILE_NAME_LAYOUT, 0.25F); - uploadDetailsTable.setColumnExpandRatio(SW_MODULE_NAME, 0.17F); - uploadDetailsTable.setColumnExpandRatio(SHA1_CHECKSUM, 0.2F); - uploadDetailsTable.setColumnExpandRatio(MD5_CHECKSUM, 0.2F); - uploadDetailsTable.setColumnExpandRatio(SIZE, 0.12F); - uploadDetailsTable.setColumnExpandRatio(ACTION, 0.06F); - - final Object[] visibileColumn = { FILE_NAME_LAYOUT, SW_MODULE_NAME, SHA1_CHECKSUM, MD5_CHECKSUM, SIZE, ACTION }; - uploadDetailsTable.setVisibleColumns(visibileColumn); - } - - private void buildLayout() { - final HorizontalLayout footer = getFooterLayout(); - - uploadArtifactDetails = new VerticalLayout(); - uploadArtifactDetails.setWidth(SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH + "px"); - uploadArtifactDetails.addStyleName("confirmation-popup"); - uploadArtifactDetails.addComponent(uploadDetailsTable); - uploadArtifactDetails.setComponentAlignment(uploadDetailsTable, Alignment.MIDDLE_CENTER); - uploadArtifactDetails.addComponent(footer); - uploadArtifactDetails.setComponentAlignment(footer, Alignment.MIDDLE_CENTER); - - window = new Window(); - window.setContent(uploadArtifactDetails); - window.setResizable(Boolean.FALSE); - window.setClosable(Boolean.TRUE); - window.setDraggable(Boolean.TRUE); - window.setModal(true); - window.addCloseListener(event -> onPopupClose()); - window.setCaption(i18n.getMessage("header.caption.upload.details")); - window.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); - } - - private void onPopupClose() { - uploadLayout.setCurrentUploadConfirmationwindow(null); - } - - private HorizontalLayout getFooterLayout() { - final HorizontalLayout footer = new HorizontalLayout(); - footer.setSizeUndefined(); - footer.addStyleName("confirmation-window-footer"); - footer.setSpacing(true); - footer.setMargin(false); - footer.addComponents(uploadBtn, cancelBtn); - footer.setComponentAlignment(uploadBtn, Alignment.TOP_LEFT); - footer.setComponentAlignment(cancelBtn, Alignment.TOP_RIGHT); - return footer; - } - - public Window getUploadConfirmationWindow() { - return window; - } - - @Override - public void buttonClick(final ClickEvent event) { - if (event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_ARTIFACT_DETAILS_CLOSE)) { - window.close(); - } else if (event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_DISCARD_DETAILS_BUTTON)) { - uploadLayout.clearUploadedFileDetails(); - window.close(); - } else if (event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_BUTTON)) { - processArtifactUpload(); - } else if (event.getComponent().getId().startsWith(UIComponentIdProvider.UPLOAD_DELETE_ICON)) { - final String itemId = ((Button) event.getComponent()).getData().toString(); - final Item item = uploadDetailsTable.getItem(((Button) event.getComponent()).getData()); - final Long swId = (Long) item.getItemProperty(BASE_SOFTWARE_ID).getValue(); - final CustomFile customFile = (CustomFile) item.getItemProperty(CUSTOM_FILE).getValue(); - final String fileName = (String) item.getItemProperty(FILE_NAME).getValue(); - final Label warningIconLabel = (Label) item.getItemProperty(WARNING_ICON).getValue(); - final Boolean isWarningIconDisplayed = isWarningIcon(warningIconLabel); - if (isWarningIconDisplayed) { - modifyIconOfSameSwId(itemId, swId, fileName); - } else if (isErrorIcon(warningIconLabel)) { - redErrorLabelCount--; - } - reValidateOtherFileNamesOfSameBaseSw(((Button) event.getComponent()).getData(), swId, fileName); - enableOrDisableUploadBtn(); - - uploadDetailsTable.removeItem(((Button) event.getComponent()).getData()); - uploadLayout.getFileSelected().remove(customFile); - uploadLayout.updateUploadCounts(); - if (uploadDetailsTable.getItemIds().isEmpty()) { - window.close(); - uploadLayout.clearUploadedFileDetails(); - } - } - } - - // Exception squid:S3655 - Optional access is checked in - // checkIfArtifactDetailsDispalyed subroutine - @SuppressWarnings("squid:S3655") - private void processArtifactUpload() { - final List itemIds = (List) uploadDetailsTable.getItemIds(); - if (preUploadValidation(itemIds)) { - Boolean refreshArtifactDetailsLayout = false; - for (final String itemId : itemIds) { - final String[] itemDet = itemId.split("/"); - final String baseSoftwareModuleNameVersion = itemDet[0]; - final String fileName = itemDet[1]; - final SoftwareModule bSoftwareModule = artifactUploadState.getBaseSwModuleList() - .get(baseSoftwareModuleNameVersion); - for (final CustomFile customFile : uploadLayout.getFileSelected()) { - final String baseSwModuleNameVersion = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(fileName) - && baseSwModuleNameVersion.equals(baseSoftwareModuleNameVersion)) { - createArtifact(itemId, customFile.getFilePath(), customFile.getFileSize(), artifactManagement, - bSoftwareModule); - } - } - refreshArtifactDetailsLayout = checkIfArtifactDetailsDisplayed(bSoftwareModule.getId()); - } - - if (refreshArtifactDetailsLayout) { - uploadLayout.refreshArtifactDetailsLayout(artifactUploadState.getSelectedBaseSwModuleId().get()); - } - uploadLayout.clearFileList(); - window.close(); - // call upload result window - currentUploadResultWindow = new UploadResultWindow(uploadResultList, i18n, eventBus); - UI.getCurrent().addWindow(currentUploadResultWindow.getUploadResultsWindow()); - currentUploadResultWindow.getUploadResultsWindow().addCloseListener(event -> onResultDetailsPopupClose()); - uploadLayout.setResultPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), - Page.getCurrent().getBrowserWindowHeight()); - } else { - uploadLayout.getUINotification() - .displayValidationError(uploadLayout.getI18n().getMessage("message.error.noProvidedName")); - } - } - - private void onResultDetailsPopupClose() { - currentUploadResultWindow = null; - } - - private void createArtifact(final String itemId, final String filePath, final long fileSize, - final ArtifactManagement artifactManagement, final SoftwareModule baseSw) { - - final File newFile = new File(filePath); - final Item item = tableContainer.getItem(itemId); - // We have to make sure that null is assigned to sha1Checksum and - // md5Checksum if no alphanumeric value is provided. Empty String will - // fail - final String sha1Checksum = HawkbitCommonUtil - .trimAndNullIfEmpty(((TextField) item.getItemProperty(SHA1_CHECKSUM).getValue()).getValue()); - final String md5Checksum = HawkbitCommonUtil - .trimAndNullIfEmpty(((TextField) item.getItemProperty(MD5_CHECKSUM).getValue()).getValue()); - final String providedFileName = (String) item.getItemProperty(FILE_NAME).getValue(); - final CustomFile customFile = (CustomFile) item.getItemProperty(CUSTOM_FILE).getValue(); - final String[] itemDet = itemId.split("/"); - final String swModuleNameVersion = itemDet[0]; - - try (FileInputStream fis = new FileInputStream(newFile)) { - - artifactManagement.create(fis, baseSw.getId(), providedFileName, md5Checksum, sha1Checksum, true, - customFile.getMimeType(), fileSize); - saveUploadStatus(providedFileName, swModuleNameVersion, SPUILabelDefinitions.SUCCESS, ""); - - } catch (final ArtifactUploadFailedException | InvalidSHA1HashException | InvalidMD5HashException - | FileNotFoundException | QuotaExceededException e) { - - saveUploadStatus(providedFileName, swModuleNameVersion, SPUILabelDefinitions.FAILED, e.getMessage()); - LOG.error(ARTIFACT_UPLOAD_EXCEPTION, e); - - } catch (final IOException ex) { - LOG.error(ARTIFACT_UPLOAD_EXCEPTION, ex); - } finally { - if (newFile.exists() && !newFile.delete()) { - LOG.error("Could not delete temporary file: {}", newFile); - } - } - } - - private void saveUploadStatus(final String fileName, final String baseSwModuleName, final String status, - final String message) { - final UploadStatus result = new UploadStatus(); - result.setFileName(fileName); - result.setBaseSwModuleName(baseSwModuleName); - result.setUploadResult(status); - result.setReason(message); - uploadResultList.add(result); - } - - public Table getUploadDetailsTable() { - return uploadDetailsTable; - } - - public VerticalLayout getUploadArtifactDetails() { - return uploadArtifactDetails; - } - - public UploadResultWindow getCurrentUploadResultWindow() { - return currentUploadResultWindow; - } - - public void setCurrentUploadResultWindow(final UploadResultWindow currentUploadResultWindow) { - this.currentUploadResultWindow = currentUploadResultWindow; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java new file mode 100644 index 000000000..9bc558aa7 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadDropAreaLayout.java @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import javax.servlet.MultipartConfigElement; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.dd.criteria.ServerItemIdClientCriterion; +import org.eclipse.hawkbit.ui.dd.criteria.ServerItemIdClientCriterion.Mode; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.event.dd.acceptcriteria.Not; +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; +import com.vaadin.ui.Html5File; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * Container for drag and drop area in the upload view. + */ +public class UploadDropAreaLayout extends AbstractComponent { + + private static final long serialVersionUID = 1L; + + private static AcceptCriterion acceptAllExceptBlacklisted = new Not(new ServerItemIdClientCriterion(Mode.PREFIX, + UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)); + + private DragAndDropWrapper dropAreaWrapper; + + private final VaadinMessageSource i18n; + + private final UINotification uiNotification; + + private final ArtifactUploadState artifactUploadState; + + private final transient MultipartConfigElement multipartConfigElement; + + private final transient SoftwareModuleManagement softwareManagement; + + private final transient ArtifactManagement artifactManagement; + + private final UploadProgressButtonLayout uploadButtonLayout; + + /** + * Creates a new {@link UploadDropAreaLayout} instance. + * + * @param i18n + * the {@link VaadinMessageSource} + * @param eventBus + * the {@link EventBus} used to send/retrieve events + * @param uiNotification + * {@link UINotification} for showing notifications + * @param artifactUploadState + * the {@link ArtifactUploadState} for state information + * @param multipartConfigElement + * the {@link MultipartConfigElement} + * @param softwareManagement + * the {@link SoftwareModuleManagement} for retrieving the + * {@link SoftwareModule} + * @param artifactManagement + * the {@link ArtifactManagement} for storing the uploaded + * artifacts + */ + public UploadDropAreaLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, + final UINotification uiNotification, final ArtifactUploadState artifactUploadState, + final MultipartConfigElement multipartConfigElement, final SoftwareModuleManagement softwareManagement, + final ArtifactManagement artifactManagement) { + this.i18n = i18n; + this.uiNotification = uiNotification; + this.artifactUploadState = artifactUploadState; + this.multipartConfigElement = multipartConfigElement; + this.softwareManagement = softwareManagement; + this.artifactManagement = artifactManagement; + this.uploadButtonLayout = new UploadProgressButtonLayout(i18n, eventBus, artifactUploadState, + multipartConfigElement, artifactManagement, softwareManagement); + + buildLayout(); + + eventBus.subscribe(this); + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final SoftwareModuleEvent event) { + final BaseEntityEventType eventType = event.getEventType(); + if (eventType == BaseEntityEventType.SELECTED_ENTITY) { + UI.getCurrent().access(() -> { + if (artifactUploadState.isNoSoftwareModuleSelected() + || artifactUploadState.isMoreThanOneSoftwareModulesSelected()) { + dropAreaWrapper.setEnabled(false); + } else if (artifactUploadState.areAllUploadsFinished()) { + dropAreaWrapper.setEnabled(true); + } + }); + } + } + + private void buildLayout() { + dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); + dropAreaWrapper.setDropHandler(new DropAreaHandler()); + } + + private VerticalLayout createDropAreaLayout() { + final VerticalLayout dropAreaLayout = new VerticalLayout(); + final Label dropHereLabel = new Label("Drop Files to upload"); + dropHereLabel.setWidth(null); + + final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); + dropIcon.addStyleName("drop-icon"); + dropIcon.setWidth(null); + + dropAreaLayout.addComponent(dropIcon); + dropAreaLayout.setComponentAlignment(dropIcon, Alignment.TOP_CENTER); + dropAreaLayout.addComponent(dropHereLabel); + dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); + + uploadButtonLayout.setWidth(null); + uploadButtonLayout.addStyleName("upload-button"); + dropAreaLayout.addComponent(uploadButtonLayout); + dropAreaLayout.setComponentAlignment(uploadButtonLayout, Alignment.BOTTOM_CENTER); + + dropAreaLayout.setSizeFull(); + dropAreaLayout.setStyleName("upload-drop-area-layout-info"); + dropAreaLayout.setSpacing(false); + return dropAreaLayout; + } + + public DragAndDropWrapper getDropAreaWrapper() { + return dropAreaWrapper; + } + + private class DropAreaHandler implements DropHandler { + + private static final long serialVersionUID = 1L; + + @Override + public AcceptCriterion getAcceptCriterion() { + return acceptAllExceptBlacklisted; + } + + @Override + public void drop(final DragAndDropEvent event) { + if (validate(event)) { + final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + // selected software module at the time of file drop is + // considered for upload + artifactUploadState.getSelectedBaseSwModuleId() + .ifPresent(selectedSwId -> uploadFilesForSoftwareModule(files, selectedSwId)); + } + } + + private void uploadFilesForSoftwareModule(final Html5File[] files, final Long softwareModuleId) { + final SoftwareModule softwareModule = softwareManagement.get(softwareModuleId).orElse(null); + + boolean isDirectory = false; + boolean isDuplicate = false; + + for (final Html5File file : files) { + + isDirectory = isDirectory(file); + isDuplicate = artifactUploadState.isFileInUploadState(file.getFileName(), softwareModule); + + if (!isDirectory && !isDuplicate) { + file.setStreamVariable(new FileTransferHandlerStreamVariable(file.getFileName(), file.getFileSize(), + multipartConfigElement.getMaxFileSize(), file.getType(), softwareModule, artifactManagement, + i18n)); + } + } + if (isDirectory && isDuplicate) { + uiNotification.displayValidationError(i18n.getMessage("message.no.duplicateFiles") + "
" + + i18n.getMessage("message.no.directory.upload")); + } else if (isDirectory) { + uiNotification.displayValidationError(i18n.getMessage("message.no.directory.upload")); + } else if (isDuplicate) { + uiNotification.displayValidationError(i18n.getMessage("message.no.duplicateFiles")); + } + } + + private boolean isDirectory(final Html5File file) { + return StringUtils.isBlank(file.getType()) && file.getFileSize() % 4096 == 0; + } + + private boolean validate(final DragAndDropEvent event) { + // check if drop is valid.If valid ,check if software module is + // selected. + if (!isFilesDropped(event)) { + uiNotification.displayValidationError(i18n.getMessage("message.action.not.allowed")); + return false; + } + return validateSoftwareModuleSelection(); + } + + private boolean isFilesDropped(final DragAndDropEvent event) { + if (event.getTransferable() instanceof WrapperTransferable) { + final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); + return files != null; + } + return false; + } + + private boolean validateSoftwareModuleSelection() { + if (artifactUploadState.isNoSoftwareModuleSelected()) { + uiNotification.displayValidationError(i18n.getMessage("message.error.noSwModuleSelected")); + return false; + } + if (artifactUploadState.isMoreThanOneSoftwareModulesSelected()) { + uiNotification.displayValidationError(i18n.getMessage("message.error.multiSwModuleSelected")); + return false; + } + return true; + } + } + + public UploadProgressButtonLayout getUploadButtonLayout() { + return uploadButtonLayout; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java new file mode 100644 index 000000000..59b866d83 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadFixed.java @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import java.io.OutputStream; + +import com.vaadin.server.StreamVariable; +import com.vaadin.ui.Upload; + +/** + * The {@link Upload} class has a bug.The lifecycle methods of the registered + * handler + * com.vaadin.ui.Upload.StartedListener#uploadStarted(com.vaadin.ui.Upload.StartedEvent) + * etc are called even the upload was interrupted. This bug is fixed in this + * class. + * + */ +public class UploadFixed extends Upload { + + private static final long serialVersionUID = 1L; + + private boolean uploadInterrupted; + + + @Override + public void interruptUpload() { + super.interruptUpload(); + uploadInterrupted = true; + } + + @Override + protected StreamVariable getStreamVariable() { + return new StreamVariableFixed(super.getStreamVariable()); + } + + private class StreamVariableFixed implements StreamVariable { + private static final long serialVersionUID = 1L; + private final StreamVariable originalStreamVariable; + + public StreamVariableFixed(final StreamVariable originalStreamVariable) { + this.originalStreamVariable = originalStreamVariable; + } + + @Override + public boolean listenProgress() { + // this fixes the vaadin bug + return originalStreamVariable.listenProgress() && !uploadInterrupted; + } + + @Override + public void onProgress(final StreamingProgressEvent event) { + originalStreamVariable.onProgress(event); + } + + @Override + public boolean isInterrupted() { + return uploadInterrupted; + } + + @Override + public OutputStream getOutputStream() { + return originalStreamVariable.getOutputStream(); + } + + @Override + public void streamingStarted(final StreamingStartEvent event) { + originalStreamVariable.streamingStarted(event); + } + + @Override + public void streamingFinished(final StreamingEndEvent event) { + originalStreamVariable.streamingFinished(event); + } + + @Override + public void streamingFailed(final StreamingErrorEvent event) { + originalStreamVariable.streamingFailed(event); + uploadInterrupted = false; + } + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java deleted file mode 100644 index 99de3a57d..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java +++ /dev/null @@ -1,403 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Optional; - -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.event.UploadFileStatus; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent.UploadStatusEventType; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.utils.SpringContextHelper; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.server.StreamVariable; -import com.vaadin.ui.Upload; -import com.vaadin.ui.Upload.FailedEvent; -import com.vaadin.ui.Upload.FailedListener; -import com.vaadin.ui.Upload.FinishedEvent; -import com.vaadin.ui.Upload.FinishedListener; -import com.vaadin.ui.Upload.ProgressListener; -import com.vaadin.ui.Upload.Receiver; -import com.vaadin.ui.Upload.StartedEvent; -import com.vaadin.ui.Upload.StartedListener; -import com.vaadin.ui.Upload.SucceededEvent; -import com.vaadin.ui.Upload.SucceededListener; - -/** - * Implementation to read file selected for upload. both for {@link Upload} and - * {@link StreamVariable} upload variants. - * - * The handler manages the output to the user and at the same time ensures that - * the upload does not exceed the configured max file size. - * - */ -public class UploadHandler implements StreamVariable, Receiver, SucceededListener, FailedListener, FinishedListener, - ProgressListener, StartedListener { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(UploadHandler.class); - - private final long fileSize; - private final UploadLayout view; - private final long maxSize; - private final Upload upload; - - private volatile String fileName; - private volatile String mimeType; - private volatile boolean streamingInterrupted; - private volatile boolean uploadInterrupted; - private volatile boolean aborted; - - private String failureReason; - private final VaadinMessageSource i18n; - private transient EventBus.UIEventBus eventBus; - private final SoftwareModule selectedSw; - private SoftwareModule selectedSwForUpload; - private final ArtifactUploadState artifactUploadState; - - private final transient SoftwareModuleManagement softwareModuleManagement; - - UploadHandler(final String fileName, final long fileSize, final UploadLayout view, final long maxSize, - final Upload upload, final String mimeType, final SoftwareModule selectedSw, - final SoftwareModuleManagement softwareManagement) { - this.aborted = false; - this.fileName = fileName; - this.fileSize = fileSize; - this.view = view; - this.maxSize = maxSize; - this.upload = upload; - this.mimeType = mimeType; - this.selectedSw = selectedSw; - this.i18n = SpringContextHelper.getBean(VaadinMessageSource.class); - this.eventBus = SpringContextHelper.getBean(EventBus.UIEventBus.class); - this.artifactUploadState = SpringContextHelper.getBean(ArtifactUploadState.class); - this.softwareModuleManagement = softwareManagement; - eventBus.subscribe(this); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadStatusEventType event) { - if (event == UploadStatusEventType.ABORT_UPLOAD) { - aborted = true; - } - } - - /** - * Create stream for {@link StreamVariable} variant. - * - * @see com.vaadin.server.StreamVariable#getOutputStream() - */ - @Override - public final OutputStream getOutputStream() { - try { - streamingInterrupted = false; - failureReason = null; - return view.saveUploadedFileDetails(fileName, fileSize, mimeType, selectedSw); - } catch (final ArtifactUploadFailedException e) { - LOG.error("Atifact upload failed {} ", e); - failureReason = e.getMessage(); - streamingInterrupted = true; - return new NullOutputStream(); - } - } - - /** - * Create stream for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.Receiver#receiveUpload(java.lang.String, - * java.lang.String) - */ - @Override - public OutputStream receiveUpload(final String fileName, final String mimeType) { - aborted = false; - failureReason = null; - this.fileName = fileName; - this.mimeType = mimeType; - // reset has directory flag before upload - view.setHasDirectory(false); - try { - if (view.checkIfSoftwareModuleIsSelected() && !view.checkForDuplicate(fileName, selectedSwForUpload)) { - view.increaseNumberOfFileUploadsExpected(); - final OutputStream saveUploadedFileDetails = view.saveUploadedFileDetails(fileName, 0, mimeType, - selectedSwForUpload); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.RECEIVE_UPLOAD, - new UploadFileStatus(fileName, 0, -1, selectedSwForUpload))); - return saveUploadedFileDetails; - } - } catch (final ArtifactUploadFailedException e) { - LOG.error("Atifact upload failed {} ", e); - failureReason = e.getMessage(); - upload.interruptUpload(); - uploadInterrupted = true; - } - // if final validation fails ,final no upload ,return NullOutputStream - return new NullOutputStream(); - } - - /** - * - * Upload sucessfull for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.SucceededListener#uploadSucceeded(com.vaadin.ui.Upload.SucceededEvent) - */ - @Override - public void uploadSucceeded(final SucceededEvent event) { - LOG.debug("Streaming finished for file :{}", event.getFilename()); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_SUCCESSFUL, - new UploadFileStatus(event.getFilename(), 0, event.getLength(), selectedSwForUpload))); - } - - /** - * Upload finished for {@link StreamVariable} variant. Called only in good - * case. So a combination of {@link #uploadSucceeded(SucceededEvent)} and - * {@link #uploadFinished(FinishedEvent)}. - * - * @see com.vaadin.server.StreamVariable#streamingFinished(com.vaadin.server.StreamVariable.StreamingEndEvent) - */ - @Override - public void streamingFinished(final StreamingEndEvent event) { - LOG.debug("Streaming finished for file :{}", event.getFileName()); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FINISHED, - new UploadFileStatus(event.getFileName(), 0, event.getContentLength(), selectedSw))); - } - - /** - * Upload finished for {@link Upload} variant. Both for good and error - * variant. - * - * @see com.vaadin.ui.Upload.FinishedListener#uploadFinished(com.vaadin.ui.Upload.FinishedEvent) - */ - @Override - public void uploadFinished(final FinishedEvent event) { - LOG.debug("Upload finished for file :{}", event.getFilename()); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FINISHED, - new UploadFileStatus(event.getFilename()))); - } - - /** - * Upload started for {@link StreamVariable} variant. - * - * @see com.vaadin.server.StreamVariable#streamingStarted(com.vaadin.server.StreamVariable.StreamingStartEvent) - */ - @Override - public void streamingStarted(final StreamingStartEvent event) { - LOG.debug("Streaming started for file :{}", fileName); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, - new UploadFileStatus(fileName, 0, 0, selectedSw))); - } - - /** - * Upload started for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.StartedListener#uploadStarted(com.vaadin.ui.Upload.StartedEvent) - */ - @Override - public void uploadStarted(final StartedEvent event) { - uploadInterrupted = false; - selectedSwForUpload = null; - - final Optional selectedBaseSwModuleId = artifactUploadState.getSelectedBaseSwModuleId(); - if (selectedBaseSwModuleId.isPresent()) { - selectedSwForUpload = softwareModuleManagement.get(selectedBaseSwModuleId.get()).orElse(null); - } - - if (selectedSwForUpload != null && view.checkIfSoftwareModuleIsSelected() - && !view.checkIfFileIsDuplicate(event.getFilename(), selectedSwForUpload)) { - LOG.debug("Upload started for file :{}", event.getFilename()); - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STARTED, - new UploadFileStatus(event.getFilename(), 0, 0, selectedSwForUpload))); - } else { - failureReason = i18n.getMessage("message.upload.failed"); - upload.interruptUpload(); - // actual interrupt will happen a bit late so setting the below - // flag - uploadInterrupted = true; - } - } - - /** - * listen progress. - * - * @return boolean - */ - @Override - public boolean listenProgress() { - return true; - } - - /** - * Reports progress in {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.ProgressListener#updateProgress(long, long) - */ - @Override - public void updateProgress(final long readBytes, final long contentLength) { - // Update progress is called event after upload interrupted in - // uploadStarted method - if (!uploadInterrupted) { - if (aborted) { - LOG.info("User aborted file upload for file : {}", fileName); - failureReason = i18n.getMessage("message.uploadedfile.aborted"); - interruptFileUpload(); - return; - } - if (readBytes > maxSize || contentLength > maxSize) { - LOG.error("User tried to upload more than was allowed ({}).", maxSize); - failureReason = i18n.getMessage("message.uploadedfile.size.exceeded", maxSize); - interruptFileUpload(); - return; - } - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, - new UploadFileStatus(fileName, readBytes, contentLength, selectedSwForUpload))); - LOG.info("Update progress - {} : {}", fileName, (double) readBytes / (double) contentLength); - } - } - - /** - * Reports progress in {@link StreamVariable} variant. Interrupts - * - * @see com.vaadin.server.StreamVariable#onProgress(com.vaadin.server.StreamVariable.StreamingProgressEvent) - */ - @Override - public void onProgress(final StreamingProgressEvent event) { - if (aborted) { - LOG.info("User aborted the upload for file : {}", event.getFileName()); - failureReason = i18n.getMessage("message.uploadedfile.aborted"); - interruptFileStreaming(); - return; - } - if (event.getBytesReceived() > maxSize || event.getContentLength() > maxSize) { - LOG.error("User tried to upload more than was allowed ({}).", maxSize); - failureReason = i18n.getMessage("message.uploadedfile.size.exceeded", maxSize); - interruptFileStreaming(); - return; - } - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_IN_PROGRESS, - new UploadFileStatus(fileName, event.getBytesReceived(), event.getContentLength(), selectedSw))); - // Logging to solve sonar issue - LOG.trace("Streaming in progress for file :{}", event.getFileName()); - } - - /** - * Upload failed for{@link StreamVariable} variant. - * - * @param event - * StreamingEndEvent - */ - @Override - public void streamingFailed(final StreamingErrorEvent event) { - if (failureReason == null) { - failureReason = event.getException().getMessage(); - } - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_STREAMING_FAILED, - new UploadFileStatus(fileName, failureReason, selectedSw))); - - if (!aborted) { - LOG.info("Streaming failed for file :{}", event.getFileName()); - LOG.info("Streaming failed due to :{}", event.getException()); - } - } - - /** - * Upload failed for {@link Upload} variant. - * - * @see com.vaadin.ui.Upload.FailedListener#uploadFailed(com.vaadin.ui.Upload.FailedEvent) - */ - @Override - public void uploadFailed(final FailedEvent event) { - /** - * If upload failed due to no selected software UPLOAD_FAILED event need - * not be published. - */ - if (selectedSwForUpload != null) { - if (failureReason == null) { - failureReason = event.getReason().getMessage(); - } - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.UPLOAD_FAILED, - new UploadFileStatus(fileName, failureReason, selectedSwForUpload))); - if (!aborted) { - LOG.info("Upload failed for file :{}", event.getFilename()); - LOG.info("Upload failed for file :{}", event.getReason()); - } - } - } - - /** - * to check if upload is interrupted. - */ - @Override - public boolean isInterrupted() { - return streamingInterrupted; - } - - private static class NullOutputStream extends OutputStream { - /** - * null output stream. - * - * @param i - * byte - */ - @Override - public void write(final int i) throws IOException { - // do nothing - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((fileName == null) ? 0 : fileName.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final UploadHandler other = (UploadHandler) obj; - if (fileName == null) { - if (other.fileName != null) { - return false; - } - } else if (!fileName.equals(other.fileName)) { - return false; - } - return true; - } - - private void interruptFileStreaming() { - streamingInterrupted = true; - } - - private void interruptFileUpload() { - upload.interruptUpload(); - uploadInterrupted = true; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java deleted file mode 100644 index b750af715..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ /dev/null @@ -1,824 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import javax.servlet.MultipartConfigElement; - -import org.apache.commons.io.FileUtils; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.exception.ArtifactUploadFailedException; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadFileStatus; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent.UploadStatusEventType; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.artifacts.state.CustomFile; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.dd.criteria.ServerItemIdClientCriterion; -import org.eclipse.hawkbit.ui.dd.criteria.ServerItemIdClientCriterion.Mode; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.StringUtils; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.event.dd.acceptcriteria.Not; -import com.vaadin.server.FontAwesome; -import com.vaadin.server.Page; -import com.vaadin.server.StreamVariable; -import com.vaadin.shared.ui.label.ContentMode; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.DragAndDropWrapper; -import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Html5File; -import com.vaadin.ui.Label; -import com.vaadin.ui.UI; -import com.vaadin.ui.Upload; -import com.vaadin.ui.VerticalLayout; - -/** - * Upload files layout. - */ -public class UploadLayout extends VerticalLayout { - - private static final long serialVersionUID = 1L; - - private static final String HTML_DIV = ""; - - private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); - - private final UploadStatusInfoWindow uploadInfoWindow; - - private final VaadinMessageSource i18n; - - private final UINotification uiNotification; - - private final transient EventBus.UIEventBus eventBus; - - private final ArtifactUploadState artifactUploadState; - - private final transient MultipartConfigElement multipartConfigElement; - - private final List duplicateFileNamesList = new ArrayList<>(); - - private Button processBtn; - - private Button discardBtn; - - private UploadConfirmationWindow currentUploadConfirmationwindow; - - private final UI ui; - - private HorizontalLayout fileUploadLayout; - - private DragAndDropWrapper dropAreaWrapper; - - private boolean hasDirectory; - - private Button uploadStatusButton; - - private final transient SoftwareModuleManagement softwareModuleManagement; - - private static AcceptCriterion acceptAllExceptBlacklisted = new Not(new ServerItemIdClientCriterion(Mode.PREFIX, - UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)); - - private final transient ArtifactManagement artifactManagement; - - public UploadLayout(final VaadinMessageSource i18n, final UINotification uiNotification, final UIEventBus eventBus, - final ArtifactUploadState artifactUploadState, final MultipartConfigElement multipartConfigElement, - final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement) { - this.uploadInfoWindow = new UploadStatusInfoWindow(eventBus, artifactUploadState, i18n); - this.i18n = i18n; - this.uiNotification = uiNotification; - this.eventBus = eventBus; - this.artifactUploadState = artifactUploadState; - this.multipartConfigElement = multipartConfigElement; - this.artifactManagement = artifactManagement; - this.softwareModuleManagement = softwareManagement; - - createComponents(); - buildLayout(); - restoreState(); - eventBus.subscribe(this); - ui = UI.getCurrent(); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadArtifactUIEvent event) { - if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) { - ui.access(this::updateActionCount); - } else if (event == UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP) { - ui.access(this::showUploadStatusButton); - } else if (event == UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP) { - ui.access(this::maximizeStatusPopup); - } else if (event == UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED) { - ui.access(this::closeUploadStatusPopup); - } - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadStatusEvent event) { - if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STARTED) { - ui.access(this::onStartOfUpload); - } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FAILED) { - ui.access(() -> onUploadFailure(event)); - } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_FINISHED) { - ui.access(this::onUploadCompletion); - } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_SUCCESSFUL) { - ui.access(() -> onUploadSuccess(event)); - } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FAILED) { - ui.access(() -> onUploadStreamingFailure(event)); - } else if (event.getUploadProgressEventType() == UploadStatusEventType.UPLOAD_STREAMING_FINISHED) { - ui.access(this::onUploadStreamingSuccess); - } - } - - private void createComponents() { - createUploadStatusButton(); - createProcessButton(); - createDiscardBtn(); - } - - private void buildLayout() { - - final Upload upload = new Upload(); - final UploadHandler uploadHandler = new UploadHandler(null, 0, this, multipartConfigElement.getMaxFileSize(), - upload, null, null, softwareModuleManagement); - upload.setButtonCaption(i18n.getMessage("upload.file")); - upload.setImmediate(true); - upload.setReceiver(uploadHandler); - upload.addSucceededListener(uploadHandler); - upload.addFailedListener(uploadHandler); - upload.addFinishedListener(uploadHandler); - upload.addProgressListener(uploadHandler); - upload.addStartedListener(uploadHandler); - upload.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - upload.addStyleName("no-border"); - - fileUploadLayout = new HorizontalLayout(); - fileUploadLayout.setSpacing(true); - fileUploadLayout.addStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); - fileUploadLayout.addComponent(upload); - fileUploadLayout.setComponentAlignment(upload, Alignment.MIDDLE_LEFT); - fileUploadLayout.addComponent(processBtn); - fileUploadLayout.setComponentAlignment(processBtn, Alignment.MIDDLE_RIGHT); - fileUploadLayout.addComponent(discardBtn); - fileUploadLayout.setComponentAlignment(discardBtn, Alignment.MIDDLE_RIGHT); - fileUploadLayout.addComponent(uploadStatusButton); - fileUploadLayout.setComponentAlignment(uploadStatusButton, Alignment.MIDDLE_RIGHT); - setMargin(false); - - /* create drag-drop wrapper for drop area */ - dropAreaWrapper = new DragAndDropWrapper(createDropAreaLayout()); - dropAreaWrapper.setDropHandler(new DropAreahandler()); - setSizeFull(); - setSpacing(true); - } - - private void restoreState() { - updateActionCount(); - - if (!artifactUploadState.getFileSelected().isEmpty() && artifactUploadState.isUploadCompleted()) { - processBtn.setEnabled(true); - } - if (artifactUploadState.isStatusPopupMinimized()) { - showUploadStatusButton(); - if (artifactUploadState.isUploadCompleted()) { - setUploadStatusButtonIconToFinished(); - } - } - if (artifactUploadState.isUploadCompleted()) { - artifactUploadState.getNumberOfFilesActuallyUpload().set(0); - artifactUploadState.getNumberOfFileUploadsExpected().set(0); - artifactUploadState.getNumberOfFileUploadsFailed().set(0); - } - } - - public DragAndDropWrapper getDropAreaWrapper() { - return dropAreaWrapper; - } - - private class DropAreahandler implements DropHandler { - - private static final long serialVersionUID = 1L; - - @Override - public AcceptCriterion getAcceptCriterion() { - return acceptAllExceptBlacklisted; - } - - @Override - public void drop(final DragAndDropEvent event) { - if (validate(event)) { - final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - // selected software module at the time of file drop is - // considered for upload - - artifactUploadState.getSelectedBaseSwModuleId().ifPresent(selectedSwId -> { - // reset the flag - hasDirectory = false; - final SoftwareModule softwareModule = softwareModuleManagement.get(selectedSwId) - .orElse(null); - for (final Html5File file : files) { - processFile(file, softwareModule); - } - if (artifactUploadState.getNumberOfFileUploadsExpected().get() > 0) { - processBtn.setEnabled(false); - } else { - // If the upload is not started, it signifies all - // dropped files as either duplicate or directory.So - // display message accordingly - displayCompositeMessage(); - } - }); - } - } - - private boolean validate(final DragAndDropEvent event) { - // check if drop is valid.If valid ,check if software module is - // selected. - if (!isFilesDropped(event)) { - uiNotification.displayValidationError(i18n.getMessage("message.action.not.allowed")); - return false; - } - return checkIfSoftwareModuleIsSelected(); - } - - private boolean isFilesDropped(final DragAndDropEvent event) { - if (event.getTransferable() instanceof WrapperTransferable) { - final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - return files != null; - } - return false; - } - - private void processFile(final Html5File file, final SoftwareModule selectedSw) { - if (!isDirectory(file)) { - if (!checkForDuplicate(file.getFileName(), selectedSw)) { - - eventBus.publish(this, new UploadStatusEvent(UploadStatusEventType.RECEIVE_UPLOAD, - new UploadFileStatus(file.getFileName(), 0, -1, selectedSw))); - - artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); - file.setStreamVariable(createStreamVariable(file, selectedSw)); - } - } else { - hasDirectory = Boolean.TRUE; - } - } - - private StreamVariable createStreamVariable(final Html5File file, final SoftwareModule selectedSw) { - return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, - multipartConfigElement.getMaxFileSize(), null, file.getType(), selectedSw, softwareModuleManagement); - } - - private boolean isDirectory(final Html5File file) { - return StringUtils.isEmpty(file.getType()) && file.getFileSize() % 4096 == 0; - } - } - - private void displayCompositeMessage() { - final String duplicateMessage = getDuplicateFileValidationMessage(); - final StringBuilder compositeMessage = new StringBuilder(); - if (!StringUtils.isEmpty(duplicateMessage)) { - compositeMessage.append(duplicateMessage); - } - if (hasDirectory) { - if (compositeMessage.length() > 0) { - compositeMessage.append("
"); - } - compositeMessage.append(i18n.getMessage("message.no.directory.upload")); - } - if (!compositeMessage.toString().isEmpty()) { - uiNotification.displayValidationError(compositeMessage.toString()); - } - } - - private static VerticalLayout createDropAreaLayout() { - final VerticalLayout dropAreaLayout = new VerticalLayout(); - final Label dropHereLabel = new Label("Drop files to upload"); - dropHereLabel.setWidth(null); - - final Label dropIcon = new Label(FontAwesome.ARROW_DOWN.getHtml(), ContentMode.HTML); - dropIcon.addStyleName("drop-icon"); - dropIcon.setWidth(null); - - dropAreaLayout.addComponent(dropIcon); - dropAreaLayout.setComponentAlignment(dropIcon, Alignment.BOTTOM_CENTER); - dropAreaLayout.addComponent(dropHereLabel); - dropAreaLayout.setComponentAlignment(dropHereLabel, Alignment.TOP_CENTER); - dropAreaLayout.setSizeFull(); - dropAreaLayout.setStyleName("upload-drop-area-layout-info"); - dropAreaLayout.setSpacing(false); - return dropAreaLayout; - } - - private void createProcessButton() { - processBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_PROCESS_BUTTON, - SPUILabelDefinitions.PROCESS, SPUILabelDefinitions.PROCESS, null, false, null, - SPUIButtonStyleSmall.class); - processBtn.setIcon(FontAwesome.BELL); - processBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - processBtn.addClickListener(this::displayConfirmWindow); - processBtn.setHtmlContentAllowed(true); - processBtn.setEnabled(false); - } - - private void createDiscardBtn() { - discardBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_DISCARD_BUTTON, - SPUILabelDefinitions.DISCARD, SPUILabelDefinitions.DISCARD, null, false, null, - SPUIButtonStyleSmall.class); - discardBtn.setIcon(FontAwesome.TRASH_O); - discardBtn.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - discardBtn.addClickListener(this::discardUploadData); - } - - boolean checkForDuplicate(final String filename, final SoftwareModule selectedSw) { - final Boolean isDuplicate = checkIfFileIsDuplicate(filename, selectedSw); - if (isDuplicate) { - getDuplicateFileNamesList().add(filename); - } - return isDuplicate; - } - - /** - * Save uploaded file details. - * - * @param stream - * read from uploaded file - * @param name - * file name - * @param size - * file size - * @param mimeType - * the mimeType of the file - * @param selectedSw - * @throws IOException - * in case of upload errors - */ - OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType, - final SoftwareModule selectedSw) { - File tempFile = null; - try { - tempFile = File.createTempFile("spUiArtifactUpload", null); - - // we return the outputstream so we cannot close it here - @SuppressWarnings("squid:S2095") - final OutputStream out = new FileOutputStream(tempFile); - - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion(selectedSw.getName(), - selectedSw.getVersion()); - - final CustomFile customFile = new CustomFile(name, size, tempFile.getAbsolutePath(), selectedSw.getName(), - selectedSw.getVersion(), mimeType); - - artifactUploadState.getFileSelected().add(customFile); - processBtn.setEnabled(false); - - if (!artifactUploadState.getBaseSwModuleList().keySet().contains(currentBaseSoftwareModuleKey)) { - artifactUploadState.getBaseSwModuleList().put(currentBaseSoftwareModuleKey, selectedSw); - } - return out; - } catch (final FileNotFoundException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.getMessage("message.file.not.found")); - } catch (final IOException e) { - LOG.error("Upload failed {}", e); - throw new ArtifactUploadFailedException(i18n.getMessage("message.upload.failed")); - } - } - - boolean checkIfSoftwareModuleIsSelected() { - if (!artifactUploadState.getSelectedBaseSwModuleId().isPresent()) { - uiNotification.displayValidationError(i18n.getMessage("message.error.noSwModuleSelected")); - return false; - } - return true; - } - - /** - * Check if the selected file is duplicate. i.e. already selected for upload - * for same software module. - * - * @param name - * file name - * @param selectedSoftwareModule - * the current selected software module - * @return Boolean - */ - Boolean checkIfFileIsDuplicate(final String name, final SoftwareModule selectedSoftwareModule) { - Boolean isDuplicate = false; - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - isDuplicate = true; - break; - } - } - return isDuplicate; - } - - private void decreaseNumberOfFileUploadsExpected() { - artifactUploadState.getNumberOfFileUploadsExpected().decrementAndGet(); - } - - private List getDuplicateFileNamesList() { - return duplicateFileNamesList; - } - - /** - * Update pending action count. - */ - private void updateActionCount() { - if (!artifactUploadState.getFileSelected().isEmpty()) { - processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" - + artifactUploadState.getFileSelected().size() + HTML_DIV); - } else { - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - } - } - - private void displayDuplicateValidationMessage() { - // check if streaming of all dropped files are completed - if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == artifactUploadState - .getNumberOfFileUploadsExpected().intValue()) { - displayCompositeMessage(); - duplicateFileNamesList.clear(); - } - } - - private String getDuplicateFileValidationMessage() { - final StringBuilder message = new StringBuilder(); - if (!duplicateFileNamesList.isEmpty()) { - final String fileNames = StringUtils.collectionToCommaDelimitedString(duplicateFileNamesList); - if (duplicateFileNamesList.size() == 1) { - message.append(i18n.getMessage("message.no.duplicateFile") + fileNames); - - } else if (duplicateFileNamesList.size() > 1) { - message.append(i18n.getMessage("message.no.duplicateFiles")); - } - } - return message.toString(); - } - - void increaseNumberOfFileUploadsExpected() { - artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); - } - - private void updateFileSize(final String name, final long size, final SoftwareModule selectedSoftwareModule) { - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil - .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); - - for (final CustomFile customFile : artifactUploadState.getFileSelected()) { - final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - customFile.getBaseSoftwareModuleName(), customFile.getBaseSoftwareModuleVersion()); - if (customFile.getFileName().equals(name) && currentBaseSoftwareModuleKey.equals(fileSoftwareModuleKey)) { - customFile.setFileSize(size); - break; - } - } - } - - private void increaseNumberOfFilesActuallyUpload() { - artifactUploadState.getNumberOfFilesActuallyUpload().incrementAndGet(); - } - - private void increaseNumberOfFileUploadsFailed() { - artifactUploadState.getNumberOfFileUploadsFailed().incrementAndGet(); - } - - /** - * Enable process button once upload is completed. - */ - private boolean enableProcessBtn() { - if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() >= artifactUploadState - .getNumberOfFileUploadsExpected().intValue() && !getFileSelected().isEmpty()) { - processBtn.setEnabled(true); - artifactUploadState.getNumberOfFilesActuallyUpload().set(0); - artifactUploadState.getNumberOfFileUploadsExpected().set(0); - return true; - } - return false; - } - - Set getFileSelected() { - return artifactUploadState.getFileSelected(); - } - - private void discardUploadData(final Button.ClickEvent event) { - if (event.getButton().equals(discardBtn)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.getMessage("message.error.noFileSelected")); - } else { - clearUploadedFileDetails(); - } - } - } - - protected void clearUploadedFileDetails() { - clearFileList(); - closeUploadStatusPopup(); - } - - private void closeUploadStatusPopup() { - uploadInfoWindow.clearWindow(); - hideUploadStatusButton(); - artifactUploadState.setStatusPopupMinimized(false); - } - - /** - * Clear details. - */ - void clearFileList() { - // delete file system zombies - artifactUploadState.getFileSelected() - .forEach(customFile -> FileUtils.deleteQuietly(new File(customFile.getFilePath()))); - - artifactUploadState.getFileSelected().clear(); - artifactUploadState.getBaseSwModuleList().clear(); - processBtn.setCaption(SPUILabelDefinitions.PROCESS); - /* disable when there is no files to upload. */ - processBtn.setEnabled(false); - artifactUploadState.getNumberOfFilesActuallyUpload().set(0); - artifactUploadState.getNumberOfFileUploadsExpected().set(0); - artifactUploadState.getNumberOfFileUploadsFailed().set(0); - duplicateFileNamesList.clear(); - } - - private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null) { - currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil - .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), - Unit.PIXELS); - currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil - .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), - Unit.PIXELS); - } - } - - /** - * Set artifact upload result pop up size changes. - * - * @param newWidth - * new width of result pop up - * @param newHeight - * new height of result pop up - */ - void setResultPopupHeightWidth(final float newWidth, final float newHeight) { - if (currentUploadConfirmationwindow != null - && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { - final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow - .getCurrentUploadResultWindow(); - uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( - newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); - } - } - - private void displayConfirmWindow(final Button.ClickEvent event) { - if (event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_PROCESS_BUTTON)) { - if (artifactUploadState.getFileSelected().isEmpty()) { - uiNotification.displayValidationError(i18n.getMessage("message.error.noFileSelected")); - } else { - currentUploadConfirmationwindow = new UploadConfirmationWindow(this, artifactUploadState, eventBus, - artifactManagement); - UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfirmationWindow()); - setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), - Page.getCurrent().getBrowserWindowHeight()); - } - } - } - - VaadinMessageSource getI18n() { - return i18n; - } - - void setCurrentUploadConfirmationwindow(final UploadConfirmationWindow currentUploadConfirmationwindow) { - this.currentUploadConfirmationwindow = currentUploadConfirmationwindow; - } - - private void onStartOfUpload() { - setUploadStatusButtonIconToInProgress(); - if (artifactUploadState.isStatusPopupMinimized()) { - updateStatusButtonCount(); - } - } - - private void onUploadStreamingSuccess() { - increaseNumberOfFilesActuallyUpload(); - updateUploadCounts(); - enableProcessBtn(); - if (isUploadComplete()) { - uploadInfoWindow.uploadSessionFinished(); - setUploadStatusButtonIconToFinished(); - } - // display the duplicate message after streaming all files - displayDuplicateValidationMessage(); - } - - private void onUploadStreamingFailure(final UploadStatusEvent event) { - /** - * If upload interrupted because of duplicate file, do not remove the - * file already in upload list - **/ - if (getDuplicateFileNamesList().isEmpty() - || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { - final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); - if (sw != null) { - getFileSelected() - .remove(new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); - } - // failed reason to be updated only if there is error other than - // duplicate file error - uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), - event.getUploadStatus().getFailureReason(), event.getUploadStatus().getSoftwareModule()); - increaseNumberOfFileUploadsFailed(); - } - decreaseNumberOfFileUploadsExpected(); - updateUploadCounts(); - enableProcessBtn(); - // check if we are finished - if (isUploadComplete()) { - uploadInfoWindow.uploadSessionFinished(); - setUploadStatusButtonIconToFinished(); - } - displayDuplicateValidationMessage(); - } - - private void onUploadSuccess(final UploadStatusEvent event) { - updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength(), - event.getUploadStatus().getSoftwareModule()); - // recorded that we now one more uploaded - increaseNumberOfFilesActuallyUpload(); - } - - private void onUploadCompletion() { - // check if we are finished - if (isUploadComplete()) { - uploadInfoWindow.uploadSessionFinished(); - setUploadStatusButtonIconToFinished(); - displayDuplicateValidationMessage(); - } - updateUploadCounts(); - enableProcessBtn(); - } - - private boolean isUploadComplete() { - final int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); - final int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); - return uploadedCount == expectedUploadsCount; - } - - private void onUploadFailure(final UploadStatusEvent event) { - /** - * If upload interrupted because of duplicate file, do not remove the - * file already in upload list - **/ - if (getDuplicateFileNamesList().isEmpty() - || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { - final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); - if (sw != null) { - getFileSelected() - .remove(new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); - } - // failed reason to be updated only if there is error other than - // duplicate file error - uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), - event.getUploadStatus().getFailureReason(), event.getUploadStatus().getSoftwareModule()); - increaseNumberOfFileUploadsFailed(); - decreaseNumberOfFileUploadsExpected(); - } - } - - void refreshArtifactDetailsLayout(final Long selectedBaseSoftwareModuleId) { - final SoftwareModule softwareModule = softwareModuleManagement.get(selectedBaseSoftwareModuleId) - .orElse(null); - eventBus.publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, softwareModule)); - } - - public HorizontalLayout getFileUploadLayout() { - return fileUploadLayout; - } - - public UINotification getUINotification() { - return uiNotification; - } - - public void setHasDirectory(final Boolean hasDirectory) { - this.hasDirectory = hasDirectory; - } - - private void createUploadStatusButton() { - uploadStatusButton = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", - false, null, SPUIButtonStyleSmall.class); - uploadStatusButton.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - uploadStatusButton.setWidth("100px"); - uploadStatusButton.setHtmlContentAllowed(true); - uploadStatusButton.addClickListener(event -> onClickOfUploadStatusButton()); - uploadStatusButton.setVisible(false); - } - - private void updateStatusButtonCount() { - final int uploadsPending = artifactUploadState.getNumberOfFileUploadsExpected().get() - - artifactUploadState.getNumberOfFilesActuallyUpload().get(); - final int uploadsFailed = artifactUploadState.getNumberOfFileUploadsFailed().get(); - final StringBuilder builder = new StringBuilder(""); - if (uploadsFailed != 0) { - if (uploadsPending != 0) { - builder.append("
" + uploadsFailed + HTML_DIV); - } else { - builder.append("
" + uploadsFailed + HTML_DIV); - } - } - if (uploadsPending != 0) { - builder.append("
" + uploadsPending + HTML_DIV); - } - uploadStatusButton.setCaption(builder.toString()); - } - - private void onClickOfUploadStatusButton() { - artifactUploadState.setStatusPopupMinimized(false); - eventBus.publish(this, UploadArtifactUIEvent.MAXIMIZED_STATUS_POPUP); - } - - private void showUploadStatusButton() { - if (uploadStatusButton == null) { - return; - } - uploadStatusButton.setVisible(true); - updateStatusButtonCount(); - } - - private void hideUploadStatusButton() { - if (uploadStatusButton == null) { - return; - } - uploadStatusButton.setVisible(false); - } - - private void maximizeStatusPopup() { - hideUploadStatusButton(); - uploadInfoWindow.maximizeStatusPopup(); - } - - private void setUploadStatusButtonIconToFinished() { - if (uploadStatusButton == null) { - return; - } - uploadStatusButton.removeStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - uploadStatusButton.setIcon(FontAwesome.UPLOAD); - } - - private void setUploadStatusButtonIconToInProgress() { - if (uploadStatusButton == null) { - return; - } - uploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - uploadStatusButton.setIcon(null); - } - - protected void updateUploadCounts() { - updateActionCount(); - updateStatusButtonCount(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java new file mode 100644 index 000000000..0eae30f84 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressButtonLayout.java @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import javax.servlet.MultipartConfigElement; + +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.ui.Button; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * Container for upload and progress button. + */ +public class UploadProgressButtonLayout extends VerticalLayout { + + private static final long serialVersionUID = 1L; + + private final UploadProgressInfoWindow uploadInfoWindow; + + private final VaadinMessageSource i18n; + + private final transient MultipartConfigElement multipartConfigElement; + + private final UI ui; + + private Button uploadProgressButton; + + private final transient SoftwareModuleManagement softwareModuleManagement; + + private final UploadFixed upload; + + private final transient ArtifactManagement artifactManagement; + + private final ArtifactUploadState artifactUploadState; + + /** + * Creates a new {@link UploadProgressButtonLayout} instance. + * + * @param i18n + * the {@link VaadinMessageSource} + * @param eventBus + * the {@link UIEventBus} for listening to ui events + * @param artifactUploadState + * the {@link ArtifactUploadState} for state information + * @param multipartConfigElement + * the {@link MultipartConfigElement} + * @param softwareManagement + * the {@link SoftwareModuleManagement} for retrieving the + * {@link SoftwareModule} + * @param artifactManagement + * the {@link ArtifactManagement} for storing the uploaded + * artifacts + */ + public UploadProgressButtonLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, + final ArtifactUploadState artifactUploadState, final MultipartConfigElement multipartConfigElement, + final ArtifactManagement artifactManagement, final SoftwareModuleManagement softwareManagement) { + this.artifactUploadState = artifactUploadState; + this.artifactManagement = artifactManagement; + this.uploadInfoWindow = new UploadProgressInfoWindow(eventBus, artifactUploadState, i18n); + this.uploadInfoWindow.addCloseListener(event -> { + // ensure that the progress button is hidden when the progress + // window is closed and no more uploads running + if (artifactUploadState.areAllUploadsFinished()) { + hideUploadProgressButton(); + } + }); + this.i18n = i18n; + this.multipartConfigElement = multipartConfigElement; + this.softwareModuleManagement = softwareManagement; + this.upload = new UploadFixed(); + + createComponents(); + buildLayout(); + restoreState(); + ui = UI.getCurrent(); + + eventBus.subscribe(this); + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final FileUploadProgress fileUploadProgress) { + final FileUploadProgress.FileUploadStatus uploadProgressEventType = fileUploadProgress.getFileUploadStatus(); + switch (uploadProgressEventType) { + case UPLOAD_STARTED: + ui.access(this::onStartOfUpload); + break; + case UPLOAD_FAILED: + case UPLOAD_SUCCESSFUL: + case UPLOAD_IN_PROGRESS: + break; + case UPLOAD_FINISHED: + ui.access(this::onUploadFinished); + break; + default: + throw new IllegalArgumentException("Enum " + FileUploadProgress.FileUploadStatus.class.getSimpleName() + + " doesn't contain value " + uploadProgressEventType); + } + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final SoftwareModuleEvent event) { + final BaseEntityEventType eventType = event.getEventType(); + if (eventType == BaseEntityEventType.SELECTED_ENTITY) { + ui.access(() -> { + if (artifactUploadState.isNoSoftwareModuleSelected() + || artifactUploadState.isMoreThanOneSoftwareModulesSelected()) { + upload.setEnabled(false); + } else if (artifactUploadState.areAllUploadsFinished()) { + upload.setEnabled(true); + } + }); + } + } + + private void createComponents() { + uploadProgressButton = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_STATUS_BUTTON, "", "", "", + false, null, SPUIButtonStyleNoBorder.class); + uploadProgressButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); + uploadProgressButton.setIcon(null); + uploadProgressButton.setHtmlContentAllowed(true); + uploadProgressButton.addClickListener(event -> onClickOfUploadProgressButton()); + } + + private void buildLayout() { + final FileTransferHandlerVaadinUpload uploadHandler = new FileTransferHandlerVaadinUpload( + multipartConfigElement.getMaxFileSize(), softwareModuleManagement, artifactManagement, i18n); + upload.setButtonCaption(i18n.getMessage("upload.file")); + upload.setImmediate(true); + upload.setReceiver(uploadHandler); + upload.addSucceededListener(uploadHandler); + upload.addFailedListener(uploadHandler); + upload.addFinishedListener(uploadHandler); + upload.addProgressListener(uploadHandler); + upload.addStartedListener(uploadHandler); + upload.setId(UIComponentIdProvider.UPLOAD_BUTTON); + + addComponent(upload); + setSpacing(true); + } + + /** + * Is called when view is shown to the user + */ + public void restoreState() { + if (artifactUploadState.areAllUploadsFinished()) { + artifactUploadState.clearUploadTempData(); + hideUploadProgressButton(); + upload.setEnabled(true); + } else if (artifactUploadState.isAtLeastOneUploadInProgress()) { + showUploadProgressButton(); + } + } + + private void onStartOfUpload() { + showUploadProgressButton(); + } + + /** + * Called for every finished (succeeded or failed) upload. + */ + private void onUploadFinished() { + if (artifactUploadState.areAllUploadsFinished()) { + hideUploadProgressButton(); + upload.setEnabled(true); + artifactUploadState.clearUploadTempData(); + } + } + + private void onClickOfUploadProgressButton() { + uploadInfoWindow.maximizeWindow(); + } + + private void showUploadProgressButton() { + removeComponent(upload); + addComponent(uploadProgressButton); + } + + private void hideUploadProgressButton() { + removeComponent(uploadProgressButton); + addComponent(upload); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java new file mode 100644 index 000000000..f590b6d30 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadProgressInfoWindow.java @@ -0,0 +1,343 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.upload; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.data.Container.Indexed; +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.window.WindowMode; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; +import com.vaadin.ui.renderers.HtmlRenderer; +import com.vaadin.ui.renderers.ProgressBarRenderer; +import com.vaadin.ui.themes.ValoTheme; + +import elemental.json.JsonValue; + +/** + * Window that shows the progress of all uploads. + */ +public class UploadProgressInfoWindow extends Window { + + private static final long serialVersionUID = 1L; + + private static final String COLUMN_PROGRESS = "Progress"; + + private static final String COLUMN_FILE_NAME = "File name"; + + private static final String COLUMN_STATUS = "Status"; + + private static final String COLUMN_REASON = "Reason"; + + private static final String STATUS_INPROGRESS = "InProgress"; + + private static final String STATUS_FINISHED = "Finished"; + + private static final String STATUS_FAILED = "Failed"; + + private final ArtifactUploadState artifactUploadState; + + private final VaadinMessageSource i18n; + + private final Grid grid; + + private final IndexedContainer uploads; + + private final VerticalLayout mainLayout; + + private final UI ui; + + private Label windowCaption; + + private Button closeButton; + + UploadProgressInfoWindow(final UIEventBus eventBus, final ArtifactUploadState artifactUploadState, + final VaadinMessageSource i18n) { + this.artifactUploadState = artifactUploadState; + this.i18n = i18n; + + setPopupProperties(); + createStatusPopupHeaderComponents(); + + mainLayout = new VerticalLayout(); + mainLayout.setSpacing(Boolean.TRUE); + mainLayout.setSizeUndefined(); + setPopupSizeInMinMode(); + + uploads = getGridContainer(); + grid = createGrid(); + setGridColumnProperties(); + + mainLayout.addComponents(getCaptionLayout(), grid); + mainLayout.setExpandRatio(grid, 1.0F); + setContent(mainLayout); + eventBus.subscribe(this); + ui = UI.getCurrent(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final FileUploadProgress fileUploadProgress) { + switch (fileUploadProgress.getFileUploadStatus()) { + case UPLOAD_STARTED: + ui.access(() -> onUploadStarted(fileUploadProgress)); + break; + case UPLOAD_IN_PROGRESS: + case UPLOAD_FAILED: + case UPLOAD_SUCCESSFUL: + ui.access(() -> updateUploadProgressInfoRowObject(fileUploadProgress)); + break; + case UPLOAD_FINISHED: + ui.access(this::onUploadFinished); + break; + default: + break; + } + } + + private void onUploadStarted(final FileUploadProgress fileUploadProgress) { + updateUploadProgressInfoRowObject(fileUploadProgress); + + if (isWindowNotAlreadyAttached()) { + maximizeWindow(); + } + + grid.scrollTo(fileUploadProgress.getFileUploadId()); + } + + private boolean isWindowNotAlreadyAttached() { + return !UI.getCurrent().getWindows().contains(this); + } + + private void restoreState() { + final Indexed container = grid.getContainerDataSource(); + container.removeAllItems(); + for (final FileUploadProgress fileUploadProgress : artifactUploadState + .getAllFileUploadProgressValuesFromOverallUploadProcessList()) { + updateUploadProgressInfoRowObject(fileUploadProgress); + } + } + + private void setPopupProperties() { + setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_ID); + addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); + setImmediate(true); + setResizable(false); + setDraggable(true); + setClosable(false); + setModal(true); + } + + private void setGridColumnProperties() { + grid.getColumn(COLUMN_STATUS).setRenderer(new StatusRenderer()); + grid.getColumn(COLUMN_PROGRESS).setRenderer(new ProgressBarRenderer()); + grid.setColumnOrder(COLUMN_STATUS, COLUMN_PROGRESS, COLUMN_FILE_NAME, SPUILabelDefinitions.NAME_VERSION, + COLUMN_REASON); + setColumnWidth(); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION) + .setHeaderCaption(i18n.getMessage("upload.swModuleTable.header")); + grid.setFrozenColumnCount(5); + } + + private Grid createGrid() { + final Grid statusGrid = new Grid(uploads); + statusGrid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); + statusGrid.setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_GRID); + statusGrid.setSelectionMode(SelectionMode.NONE); + statusGrid.setHeaderVisible(true); + statusGrid.setImmediate(true); + statusGrid.setSizeFull(); + return statusGrid; + } + + private static IndexedContainer getGridContainer() { + final IndexedContainer uploadContainer = new IndexedContainer(); + uploadContainer.addContainerProperty(COLUMN_STATUS, String.class, "Active"); + uploadContainer.addContainerProperty(COLUMN_FILE_NAME, String.class, null); + uploadContainer.addContainerProperty(COLUMN_PROGRESS, Double.class, 0D); + uploadContainer.addContainerProperty(COLUMN_REASON, String.class, ""); + uploadContainer.addContainerProperty(SPUILabelDefinitions.NAME_VERSION, String.class, ""); + return uploadContainer; + } + + private HorizontalLayout getCaptionLayout() { + final HorizontalLayout captionLayout = new HorizontalLayout(); + captionLayout.setSizeFull(); + captionLayout.setHeight("36px"); + captionLayout.addComponents(windowCaption, closeButton); + captionLayout.setExpandRatio(windowCaption, 1.0F); + captionLayout.addStyleName("v-window-header"); + return captionLayout; + } + + private void createStatusPopupHeaderComponents() { + windowCaption = new Label("Upload status"); + closeButton = getCloseButton(); + } + + private void setColumnWidth() { + grid.getColumn(COLUMN_STATUS).setWidth(60); + grid.getColumn(COLUMN_PROGRESS).setWidth(150); + grid.getColumn(COLUMN_FILE_NAME).setWidth(200); + grid.getColumn(COLUMN_REASON).setWidth(290); + grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setWidth(200); + } + + private static class StatusRenderer extends HtmlRenderer { + + private static final long serialVersionUID = 1L; + + @Override + public JsonValue encode(final String value) { + if (value == null) { + return super.encode(getNullRepresentation()); + } + + final String result; + switch (value) { + case STATUS_FINISHED: + result = "
" + FontAwesome.CHECK_CIRCLE.getHtml() + "
"; + break; + case STATUS_FAILED: + result = "
" + FontAwesome.EXCLAMATION_CIRCLE.getHtml() + "
"; + break; + case STATUS_INPROGRESS: + result = "
"; + break; + default: + throw new IllegalArgumentException("Argument " + value + " wasn't expected."); + } + + return super.encode(result); + } + } + + private void openWindow() { + UI.getCurrent().addWindow(this); + center(); + } + + protected void maximizeWindow() { + openWindow(); + restoreState(); + artifactUploadState.setStatusPopupMinimized(false); + } + + private void minimizeWindow() { + artifactUploadState.setStatusPopupMinimized(true); + closeWindow(); + + if (artifactUploadState.areAllUploadsFinished()) { + cleanupStates(); + } + } + + /** + * Called for every finished (succeeded or failed) upload. + */ + private void onUploadFinished() { + if (artifactUploadState.areAllUploadsFinished() && artifactUploadState.isStatusPopupMinimized()) { + if (artifactUploadState.getFilesInFailedState().isEmpty()) { + cleanupStates(); + closeWindow(); + } else { + maximizeWindow(); + } + } + } + + private void cleanupStates() { + uploads.removeAllItems(); + artifactUploadState.clearUploadTempData(); + } + + private void setPopupSizeInMinMode() { + mainLayout.setWidth(900, Unit.PIXELS); + mainLayout.setHeight(510, Unit.PIXELS); + } + + private Button getCloseButton() { + final Button closeBtn = SPUIComponentProvider.getButton( + UIComponentIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, + SPUIButtonStyleNoBorder.class); + closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); + closeBtn.addClickListener(event -> onClose()); + return closeBtn; + } + + private void onClose() { + if (artifactUploadState.areAllUploadsFinished()) { + cleanupStates(); + closeWindow(); + } else { + minimizeWindow(); + } + } + + private void closeWindow() { + setWindowMode(WindowMode.NORMAL); + setColumnWidth(); + setPopupSizeInMinMode(); + this.close(); + } + + @SuppressWarnings("unchecked") + private void updateUploadProgressInfoRowObject(final FileUploadProgress fileUploadProgress) { + final FileUploadId fileUploadId = fileUploadProgress.getFileUploadId(); + Item item = uploads.getItem(fileUploadId); + if (item == null) { + item = grid.getContainerDataSource().addItem(fileUploadId); + item.getItemProperty(COLUMN_FILE_NAME).setValue(fileUploadId.getFilename()); + item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(HawkbitCommonUtil.getFormattedNameVersion( + fileUploadId.getSoftwareModuleName(), fileUploadId.getSoftwareModuleVersion())); + } + + final String status; + final FileUploadStatus uploadStatus = fileUploadProgress.getFileUploadStatus(); + if (uploadStatus == FileUploadStatus.UPLOAD_FAILED) { + status = STATUS_FAILED; + } else if (uploadStatus == FileUploadStatus.UPLOAD_SUCCESSFUL) { + status = STATUS_FINISHED; + } else { + status = STATUS_INPROGRESS; + } + item.getItemProperty(COLUMN_STATUS).setValue(status); + + final String failureReason = artifactUploadState.getFileUploadProgress(fileUploadId).getFailureReason(); + if (StringUtils.isNotBlank(failureReason)) { + item.getItemProperty(COLUMN_REASON).setValue(failureReason); + } + + final long bytesRead = fileUploadProgress.getBytesRead(); + final long fileSize = fileUploadProgress.getContentLength(); + if (bytesRead > 0 && fileSize > 0) { + item.getItemProperty(COLUMN_PROGRESS).setValue((double) bytesRead / (double) fileSize); + } + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java deleted file mode 100644 index ceba51cda..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadResultWindow.java +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus; - -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Table; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Upload status popup. - */ -public class UploadResultWindow implements Button.ClickListener { - - private static final long serialVersionUID = 5205927189362269027L; - - private List uploadResultList = new ArrayList<>(); - - private Button closeBtn; - - private Table uploadResultTable; - - private Window uploadResultsWindow; - - private IndexedContainer tabelContainer; - - private final VaadinMessageSource i18n; - - private static final String FILE_NAME = "fileName"; - - private static final String BASE_SW_MODULE = "baseSwModuleName"; - - private static final String UPLOAD_RESULT = "uploadResult"; - - private static final String REASON = "reason"; - - private transient EventBus.UIEventBus eventBus; - - /** - * Initialize upload status popup. - * - * @param uploadResultList - * upload status details - * @param i18n - * I18N - */ - UploadResultWindow(final List uploadResultList, final VaadinMessageSource i18n, final EventBus.UIEventBus eventBus) { - this.uploadResultList = uploadResultList; - this.i18n = i18n; - this.eventBus = eventBus; - createComponents(); - createLayout(); - } - - private void createComponents() { - closeBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_ARTIFACT_RESULT_CLOSE, - SPUILabelDefinitions.CLOSE, SPUILabelDefinitions.CLOSE, ValoTheme.BUTTON_PRIMARY, false, null, - SPUIButtonStyleTiny.class); - closeBtn.addClickListener(this); - - uploadResultTable = new Table(); - uploadResultTable.addStyleName("artifact-table"); - uploadResultTable.setSizeFull(); - uploadResultTable.setImmediate(true); - uploadResultTable.setId(UIComponentIdProvider.UPLOAD_RESULT_TABLE); - uploadResultTable.addStyleName(ValoTheme.TABLE_BORDERLESS); - uploadResultTable.addStyleName(ValoTheme.TABLE_SMALL); - uploadResultTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); - uploadResultTable.addStyleName("accordion-tab-table-style"); - - populateUploadResultTable(); - } - - private void populateUploadResultTable() { - setTableContainer(); - Label statusLabel; - Label reasonLabel; - for (final UploadStatus uploadResult : uploadResultList) { - final Item newItem = tabelContainer - .addItem(uploadResult.getBaseSwModuleName() + "/" + uploadResult.getFileName()); - newItem.getItemProperty(FILE_NAME).setValue(HawkbitCommonUtil.getFormatedLabel(uploadResult.getFileName())); - newItem.getItemProperty(BASE_SW_MODULE) - .setValue(HawkbitCommonUtil.getFormatedLabel(uploadResult.getBaseSwModuleName())); - - if (uploadResult.getUploadResult().equals(SPUILabelDefinitions.SUCCESS)) { - statusLabel = new Label(HawkbitCommonUtil.getFormatedLabel(i18n.getMessage("upload.success"))); - statusLabel.addStyleName("validation-success"); - newItem.getItemProperty(UPLOAD_RESULT).setValue(statusLabel); - } else { - statusLabel = new Label(HawkbitCommonUtil.getFormatedLabel(i18n.getMessage("upload.failed"))); - statusLabel.addStyleName("validation-failed"); - newItem.getItemProperty(UPLOAD_RESULT).setValue(statusLabel); - } - - reasonLabel = HawkbitCommonUtil.getFormatedLabel(uploadResult.getReason()); - reasonLabel.setDescription(uploadResult.getReason()); - final String idStr = UIComponentIdProvider.UPLOAD_ERROR_REASON + uploadResult.getBaseSwModuleName() + "/" - + uploadResult.getFileName(); - reasonLabel.setId(idStr); - newItem.getItemProperty(REASON).setValue(reasonLabel); - } - } - - private void setTableContainer() { - tabelContainer = new IndexedContainer(); - - tabelContainer.addContainerProperty(FILE_NAME, Label.class, null); - tabelContainer.addContainerProperty(BASE_SW_MODULE, Label.class, null); - tabelContainer.addContainerProperty(UPLOAD_RESULT, Label.class, null); - tabelContainer.addContainerProperty(REASON, Label.class, null); - - uploadResultTable.setContainerDataSource(tabelContainer); - uploadResultTable.setPageLength(10); - uploadResultTable.setColumnHeader(FILE_NAME, i18n.getMessage("upload.file.name")); - uploadResultTable.setColumnHeader(BASE_SW_MODULE, i18n.getMessage("upload.swModuleTable.header")); - uploadResultTable.setColumnHeader(UPLOAD_RESULT, i18n.getMessage("upload.result.status")); - uploadResultTable.setColumnHeader(REASON, i18n.getMessage("upload.reason")); - - uploadResultTable.setColumnExpandRatio(FILE_NAME, 0.2f); - uploadResultTable.setColumnExpandRatio(BASE_SW_MODULE, 0.2f); - uploadResultTable.setColumnExpandRatio(UPLOAD_RESULT, 0.12f); - uploadResultTable.setColumnExpandRatio(REASON, 0.48f); - final Object[] visibileColumn = { FILE_NAME, BASE_SW_MODULE, UPLOAD_RESULT, REASON }; - uploadResultTable.setVisibleColumns(visibileColumn); - } - - private void createLayout() { - final HorizontalLayout footer = new HorizontalLayout(); - footer.setSizeUndefined(); - footer.addStyleName("confirmation-window-footer"); - footer.setSpacing(true); - footer.setMargin(false); - footer.addComponents(closeBtn); - footer.setComponentAlignment(closeBtn, Alignment.TOP_CENTER); - - final VerticalLayout uploadResultDetails = new VerticalLayout(); - uploadResultDetails.setWidth(SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH + "px"); - uploadResultDetails.addStyleName("confirmation-popup"); - uploadResultDetails.addComponent(uploadResultTable); - uploadResultDetails.setComponentAlignment(uploadResultTable, Alignment.MIDDLE_CENTER); - uploadResultDetails.addComponent(footer); - uploadResultDetails.setComponentAlignment(footer, Alignment.MIDDLE_CENTER); - - uploadResultsWindow = new Window(); - uploadResultsWindow.setContent(uploadResultDetails); - uploadResultsWindow.setResizable(Boolean.FALSE); - uploadResultsWindow.setClosable(Boolean.FALSE); - uploadResultsWindow.setDraggable(Boolean.TRUE); - uploadResultsWindow.setModal(true); - uploadResultsWindow.setCaption(SPUILabelDefinitions.UPLOAD_RESULT); - uploadResultsWindow.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); - } - - @Override - public void buttonClick(final ClickEvent event) { - if (event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_ARTIFACT_RESULT_CLOSE) - || event.getComponent().getId().equals(UIComponentIdProvider.UPLOAD_ARTIFACT_RESULT_POPUP_CLOSE)) { - uploadResultsWindow.close(); - // close upload status popup if open - eventBus.publish(this, UploadArtifactUIEvent.ARTIFACT_RESULT_POPUP_CLOSED); - } - - } - - public Window getUploadResultsWindow() { - return uploadResultsWindow; - } - - public Table getUploadResultTable() { - return uploadResultTable; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatus.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatus.java deleted file mode 100644 index 239475596..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatus.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.Serializable; - -/** - * Artifact upload status. - * - * - * - * - * - */ -public class UploadStatus implements Serializable { - - private static final long serialVersionUID = 8500552533390925782L; - - private String uploadResult; - - private String reason; - - private String fileName; - - private String baseSwModuleName; - - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - - public String getBaseSwModuleName() { - return baseSwModuleName; - } - - public void setBaseSwModuleName(String baseSwModuleName) { - this.baseSwModuleName = baseSwModuleName; - } - - public String getUploadResult() { - return uploadResult; - } - - public void setUploadResult(String uploadResult) { - this.uploadResult = uploadResult; - } - - public String getReason() { - return reason; - } - - public void setReason(String reason) { - this.reason = reason; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java deleted file mode 100644 index 7afbcb06b..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusInfoWindow.java +++ /dev/null @@ -1,486 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.util.List; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadFileStatus; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent; -import org.eclipse.hawkbit.ui.artifacts.event.UploadStatusEvent.UploadStatusEventType; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; -import org.eclipse.hawkbit.ui.common.ConfirmationDialog; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.data.Container.Indexed; -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.server.FontAwesome; -import com.vaadin.shared.ui.window.WindowMode; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Grid; -import com.vaadin.ui.Grid.SelectionMode; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -import com.vaadin.ui.renderers.HtmlRenderer; -import com.vaadin.ui.renderers.ProgressBarRenderer; -import com.vaadin.ui.themes.ValoTheme; - -import elemental.json.JsonValue; - -/** - * Shows upload status during upload. - */ -public class UploadStatusInfoWindow extends Window { - - private final transient EventBus.UIEventBus eventBus; - - private final ArtifactUploadState artifactUploadState; - - private final VaadinMessageSource i18n; - - private static final String PROGRESS = "Progress"; - - private static final String FILE_NAME = "File name"; - - private static final String STATUS = "Status"; - - private static final String REASON = "Reason"; - - private static final long serialVersionUID = 1L; - - private final Grid grid; - - private final IndexedContainer uploads; - - private volatile boolean errorOccured; - - private volatile boolean uploadAborted; - - private Button minimizeButton; - - private final VerticalLayout mainLayout; - - private Label windowCaption; - - private Button closeButton; - - private Button resizeButton; - - private final UI ui; - - private ConfirmationDialog confirmDialog; - - UploadStatusInfoWindow(final UIEventBus eventBus, final ArtifactUploadState artifactUploadState, final VaadinMessageSource i18n) { - this.eventBus = eventBus; - this.artifactUploadState = artifactUploadState; - this.i18n = i18n; - - setPopupProperties(); - createStatusPopupHeaderComponents(); - - mainLayout = new VerticalLayout(); - mainLayout.setSpacing(Boolean.TRUE); - mainLayout.setSizeUndefined(); - setPopupSizeInMinMode(); - - uploads = getGridContainer(); - grid = createGrid(); - setGridColumnProperties(); - - mainLayout.addComponents(getCaptionLayout(), grid); - mainLayout.setExpandRatio(grid, 1.0F); - setContent(mainLayout); - eventBus.subscribe(this); - ui = UI.getCurrent(); - - createConfirmDialog(); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final UploadStatusEvent event) { - - final UploadFileStatus uploadStatus = event.getUploadStatus(); - switch (event.getUploadProgressEventType()) { - case UPLOAD_IN_PROGRESS: - ui.access(() -> updateProgress(uploadStatus.getFileName(), uploadStatus.getBytesRead(), - uploadStatus.getContentLength(), uploadStatus.getSoftwareModule())); - break; - case UPLOAD_STARTED: - ui.access(() -> onStartOfUpload(event)); - break; - case UPLOAD_STREAMING_FAILED: - ui.access(() -> uploadFailed(uploadStatus.getFileName(), uploadStatus.getFailureReason(), - uploadStatus.getSoftwareModule())); - break; - case UPLOAD_SUCCESSFUL: - // fall through here - case UPLOAD_STREAMING_FINISHED: - ui.access(() -> uploadSucceeded(uploadStatus.getFileName(), uploadStatus.getSoftwareModule())); - break; - case RECEIVE_UPLOAD: - uploadRecevied(uploadStatus.getFileName(), uploadStatus.getSoftwareModule()); - break; - default: - break; - } - } - - private void onStartOfUpload(final UploadStatusEvent event) { - uploadSessionStarted(); - uploadStarted(event.getUploadStatus().getFileName(), event.getUploadStatus().getSoftwareModule()); - } - - private void restoreState() { - final Indexed container = grid.getContainerDataSource(); - if (container.getItemIds().isEmpty()) { - container.removeAllItems(); - for (final UploadStatusObject statusObject : artifactUploadState.getUploadedFileStatusList()) { - final Item item = container - .addItem(getItemid(statusObject.getFilename(), statusObject.getSelectedSoftwareModule())); - item.getItemProperty(REASON).setValue(statusObject.getReason() != null ? statusObject.getReason() : ""); - if (statusObject.getStatus() != null) { - item.getItemProperty(STATUS).setValue(statusObject.getStatus()); - } - if (statusObject.getProgress() != null) { - item.getItemProperty(PROGRESS).setValue(statusObject.getProgress()); - } - item.getItemProperty(FILE_NAME).setValue(statusObject.getFilename()); - final SoftwareModule sw = statusObject.getSelectedSoftwareModule(); - item.getItemProperty(SPUILabelDefinitions.NAME_VERSION) - .setValue(HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion())); - } - if (artifactUploadState.isUploadCompleted()) { - minimizeButton.setEnabled(false); - } - } - } - - private void setPopupProperties() { - setId(UIComponentIdProvider.UPLOAD_STATUS_POPUP_ID); - addStyleName(SPUIStyleDefinitions.UPLOAD_INFO); - setImmediate(true); - setResizable(false); - setDraggable(true); - setClosable(false); - setModal(true); - } - - private void setGridColumnProperties() { - grid.getColumn(STATUS).setRenderer(new StatusRenderer()); - grid.getColumn(PROGRESS).setRenderer(new ProgressBarRenderer()); - grid.setColumnOrder(STATUS, PROGRESS, FILE_NAME, SPUILabelDefinitions.NAME_VERSION, REASON); - setColumnWidth(); - grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setHeaderCaption(i18n.getMessage("upload.swModuleTable.header")); - grid.setFrozenColumnCount(5); - } - - private Grid createGrid() { - final Grid statusGrid = new Grid(uploads); - statusGrid.addStyleName(SPUIStyleDefinitions.UPLOAD_STATUS_GRID); - statusGrid.setSelectionMode(SelectionMode.NONE); - statusGrid.setHeaderVisible(true); - statusGrid.setImmediate(true); - statusGrid.setSizeFull(); - return statusGrid; - } - - private IndexedContainer getGridContainer() { - final IndexedContainer uploadContainer = new IndexedContainer(); - uploadContainer.addContainerProperty(STATUS, String.class, "Active"); - uploadContainer.addContainerProperty(FILE_NAME, String.class, null); - uploadContainer.addContainerProperty(PROGRESS, Double.class, 0D); - uploadContainer.addContainerProperty(REASON, String.class, ""); - uploadContainer.addContainerProperty(SPUILabelDefinitions.NAME_VERSION, String.class, ""); - return uploadContainer; - } - - private HorizontalLayout getCaptionLayout() { - final HorizontalLayout captionLayout = new HorizontalLayout(); - captionLayout.setSizeFull(); - captionLayout.setHeight("36px"); - captionLayout.addComponents(windowCaption, minimizeButton, resizeButton, closeButton); - captionLayout.setExpandRatio(windowCaption, 1.0F); - captionLayout.addStyleName("v-window-header"); - return captionLayout; - } - - private void createStatusPopupHeaderComponents() { - minimizeButton = getMinimizeButton(); - windowCaption = new Label("Upload status"); - closeButton = getCloseButton(); - resizeButton = getResizeButton(); - } - - private void setColumnWidth() { - grid.getColumn(STATUS).setWidth(60); - grid.getColumn(PROGRESS).setWidth(150); - grid.getColumn(FILE_NAME).setWidth(200); - grid.getColumn(REASON).setWidth(290); - grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setWidth(200); - } - - private void resetColumnWidth() { - grid.getColumn(STATUS).setWidthUndefined(); - grid.getColumn(PROGRESS).setWidthUndefined(); - grid.getColumn(FILE_NAME).setWidthUndefined(); - grid.getColumn(REASON).setWidthUndefined(); - grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setWidthUndefined(); - } - - private static class StatusRenderer extends HtmlRenderer { - - private static final long serialVersionUID = -5365795450234970943L; - - @Override - public JsonValue encode(final String value) { - String result; - switch (value) { - case "Finished": - result = "
" + FontAwesome.CHECK_CIRCLE.getHtml() + "
"; - break; - case "Failed": - result = "
" + FontAwesome.EXCLAMATION_CIRCLE.getHtml() + "
"; - break; - default: - result = "
"; - } - - return super.encode(result); - } - } - - /** - * Automatically close if not error has occured. - */ - void uploadSessionFinished() { - uploadAborted = false; - if (!errorOccured && !artifactUploadState.isStatusPopupMinimized()) { - clearWindow(); - } - artifactUploadState.setUploadCompleted(true); - minimizeButton.setEnabled(false); - closeButton.setEnabled(true); - confirmDialog.getWindow().close(); - UI.getCurrent().removeWindow(confirmDialog.getWindow()); - } - - void uploadSessionStarted() { - if (artifactUploadState.getNumberOfFilesActuallyUpload().intValue() == 0 - && artifactUploadState.getNumberOfFileUploadsFailed().intValue() == 0 - && !artifactUploadState.isStatusPopupMinimized()) { - openWindow(); - } - if (!uploadAborted) { - minimizeButton.setEnabled(true); - closeButton.setEnabled(true); - artifactUploadState.setUploadCompleted(false); - } - } - - void openWindow() { - UI.getCurrent().addWindow(this); - center(); - } - - void maximizeStatusPopup() { - openWindow(); - restoreState(); - } - - @SuppressWarnings("unchecked") - private void uploadRecevied(final String filename, final SoftwareModule softwareModule) { - final Item item = uploads.addItem(getItemid(filename, softwareModule)); - if (item != null) { - item.getItemProperty(FILE_NAME).setValue(filename); - item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue( - HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())); - final UploadStatusObject uploadStatus = new UploadStatusObject(filename, softwareModule); - uploadStatus.setStatus("Active"); - artifactUploadState.getUploadedFileStatusList().add(uploadStatus); - } - } - - void uploadStarted(final String filename, final SoftwareModule softwareModule) { - grid.scrollTo(getItemid(filename, softwareModule)); - } - - void updateProgress(final String filename, final long readBytes, final long contentLength, - final SoftwareModule softwareModule) { - final Item item = uploads.getItem(getItemid(filename, softwareModule)); - final double progress = (double) readBytes / (double) contentLength; - if (item != null) { - item.getItemProperty(PROGRESS).setValue(progress); - } - final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() - .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setProgress(progress); - } - } - - /** - * Called when each file upload is success. - * - * @param filename - * of the uploaded file. - * @param softwareModule - * selected software module - */ - public void uploadSucceeded(final String filename, final SoftwareModule softwareModule) { - final Item item = uploads.getItem(getItemid(filename, softwareModule)); - final String status = "Finished"; - if (item != null) { - item.getItemProperty(STATUS).setValue(status); - } - final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() - .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setStatus(status); - uploadStatusObject.setProgress(1d); - } - } - - void uploadFailed(final String filename, final String errorReason, final SoftwareModule softwareModule) { - errorOccured = true; - final String status = "Failed"; - final Item item = uploads.getItem(getItemid(filename, softwareModule)); - if (item != null) { - item.getItemProperty(REASON).setValue(errorReason); - item.getItemProperty(STATUS).setValue(status); - } - final List uploadStatusObjectList = artifactUploadState.getUploadedFileStatusList().stream() - .filter(e -> e.getFilename().equals(filename)).collect(Collectors.toList()); - if (!uploadStatusObjectList.isEmpty()) { - final UploadStatusObject uploadStatusObject = uploadStatusObjectList.get(0); - uploadStatusObject.setStatus(status); - uploadStatusObject.setReason(errorReason); - } - } - - protected void clearWindow() { - errorOccured = false; - uploads.removeAllItems(); - setWindowMode(WindowMode.NORMAL); - setColumnWidth(); - setPopupSizeInMinMode(); - resizeButton.setIcon(FontAwesome.EXPAND); - this.close(); - artifactUploadState.getUploadedFileStatusList().clear(); - artifactUploadState.getNumberOfFileUploadsFailed().set(0); - } - - private void setPopupSizeInMinMode() { - mainLayout.setWidth(900, Unit.PIXELS); - mainLayout.setHeight(510, Unit.PIXELS); - } - - private Button getMinimizeButton() { - final Button minimizeBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID, "", "", "", true, FontAwesome.MINUS, - SPUIButtonStyleSmallNoBorder.class); - minimizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); - minimizeBtn.addClickListener(event -> minimizeWindow()); - minimizeBtn.setEnabled(true); - return minimizeBtn; - } - - private Button getResizeButton() { - final Button resizeBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID, "", "", "", true, FontAwesome.EXPAND, - SPUIButtonStyleSmallNoBorder.class); - resizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); - resizeBtn.addClickListener(event -> resizeWindow(event)); - return resizeBtn; - } - - private void resizeWindow(final ClickEvent event) { - if (FontAwesome.EXPAND.equals(event.getButton().getIcon())) { - event.getButton().setIcon(FontAwesome.COMPRESS); - setWindowMode(WindowMode.MAXIMIZED); - resetColumnWidth(); - grid.getColumn(STATUS).setExpandRatio(0); - grid.getColumn(PROGRESS).setExpandRatio(1); - grid.getColumn(FILE_NAME).setExpandRatio(2); - grid.getColumn(REASON).setExpandRatio(3); - grid.getColumn(SPUILabelDefinitions.NAME_VERSION).setExpandRatio(4); - mainLayout.setSizeFull(); - } else { - event.getButton().setIcon(FontAwesome.EXPAND); - setWindowMode(WindowMode.NORMAL); - setColumnWidth(); - setPopupSizeInMinMode(); - } - } - - private void minimizeWindow() { - this.close(); - artifactUploadState.setStatusPopupMinimized(true); - eventBus.publish(this, UploadArtifactUIEvent.MINIMIZED_STATUS_POPUP); - } - - private Button getCloseButton() { - final Button closeBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID, "", "", "", true, FontAwesome.TIMES, - SPUIButtonStyleSmallNoBorder.class); - closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); - closeBtn.addClickListener(event -> onClose()); - return closeBtn; - } - - private void onClose() { - if (!artifactUploadState.isUploadCompleted()) { - confirmAbortAction(); - } else { - clearWindow(); - } - } - - private void confirmAbortAction() { - UI.getCurrent().addWindow(confirmDialog.getWindow()); - confirmDialog.getWindow().bringToFront(); - } - - private void createConfirmDialog() { - confirmDialog = new ConfirmationDialog(i18n.getMessage("caption.confirm.abort.action"), - i18n.getMessage("message.abort.upload"), i18n.getMessage("button.ok"), i18n.getMessage("button.cancel"), ok -> { - if (ok) { - eventBus.publish(this, UploadStatusEventType.ABORT_UPLOAD); - uploadAborted = true; - errorOccured = true; - minimizeButton.setEnabled(false); - closeButton.setEnabled(false); - } - }); - } - - private String getItemid(final String filename, final SoftwareModule softwareModule) { - return new StringBuilder(filename).append( - HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion())) - .toString(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java deleted file mode 100644 index 5b925f8c1..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadStatusObject.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.artifacts.upload; - -import java.io.Serializable; - -import org.eclipse.hawkbit.repository.model.SoftwareModule; - -/** - * - * Holds uploaded file status.Used to display the details in upload status - * popup. - * - */ -public class UploadStatusObject implements Serializable { - private static final long serialVersionUID = 1L; - - private String status; - private Double progress; - private String filename; - private String reason; - private final SoftwareModule selectedSoftwareModule; - - UploadStatusObject(final String fileName, final SoftwareModule selectedSoftwareModule) { - this.filename = fileName; - this.selectedSoftwareModule = selectedSoftwareModule; - } - - public SoftwareModule getSelectedSoftwareModule() { - return selectedSoftwareModule; - } - - public String getStatus() { - return status; - } - - public void setStatus(final String status) { - this.status = status; - } - - public Double getProgress() { - return progress; - } - - public void setProgress(final Double progress) { - this.progress = progress; - } - - public String getFilename() { - return filename; - } - - public void setFilename(final String filename) { - this.filename = filename; - } - - public String getReason() { - return reason; - } - - public void setReason(final String reason) { - this.reason = reason; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((filename == null) ? 0 : filename.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final UploadStatusObject other = (UploadStatusObject) obj; - if (filename == null) { - if (other.filename != null) { - return false; - } - } else if (!filename.equals(other.filename)) { - return false; - } - return true; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java index 86a986e3a..546cd04c7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java @@ -17,6 +17,7 @@ import com.vaadin.shared.ui.colorpicker.Color; public final class ColorPickerConstants { public static final String DEFAULT_COLOR = "rgb(44,151,32)"; + public static final Color START_COLOR = new Color(0, 146, 58); private ColorPickerConstants() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java index 29c8c1ff9..b9b67eac1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java @@ -29,19 +29,23 @@ import com.vaadin.ui.components.colorpicker.ColorSelector; */ public class ColorPickerLayout extends GridLayout { - private static final long serialVersionUID = -7025970080613796692L; + private static final long serialVersionUID = 1L; private SpColorPickerPreview selPreview; private ColorPickerGradient colorSelect; + private Set selectors; + private Color selectedColor; /** RGB color converter. */ private final Coordinates2Color rgbConverter = new CoordinatesToColor(); private Slider redSlider; + private Slider greenSlider; + private Slider blueSlider; public ColorPickerLayout() { @@ -80,7 +84,7 @@ public class ColorPickerLayout extends GridLayout { selectors.add(colorSelect); } - private Slider createRGBSlider(final String caption, final String styleName) { + private static Slider createRGBSlider(final String caption, final String styleName) { final Slider slider = new Slider(caption, 0, 255); slider.setImmediate(true); slider.setWidth("150px"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index d6afc2353..71d0dce04 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -21,7 +21,7 @@ import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -280,9 +280,9 @@ public abstract class AbstractMetadataPopupLayout { + i18n.getMessage("caption.entity.delete.action.confirmbox"), + i18n.getMessage("message.confirm.delete.metadata", key), i18n.getMessage(SPUIDefinitions.BUTTON_OK), + i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (ok) { handleOkDeleteMetadata(event, key); } @@ -322,8 +322,7 @@ public abstract class AbstractMetadataPopupLayout onAdd()); return addIcon; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index fad5a0a82..a45c4de82 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -22,7 +22,6 @@ import java.util.stream.Collectors; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon; -import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; @@ -88,8 +87,6 @@ public class CommonDialogWindow extends Window { private HorizontalLayout buttonsLayout; - protected ValueChangeListener buttonEnableListener; - private final ClickListener cancelButtonClickListener; private final ClickListener closeClickListener = this::onCloseEvent; @@ -262,7 +259,11 @@ public class CommonDialogWindow extends Window { cancelButton.addClickListener(closeClickListener); } - protected void addComponentListeners() { + /** + * adds a listener to a component. Depending on the type of component a + * valueChange-, textChange- or itemSetChangeListener will be added. + */ + public void addComponentListeners() { // avoid duplicate registration removeListeners(); @@ -275,7 +276,6 @@ public class CommonDialogWindow extends Window { ((Table) field).addItemSetChangeListener(new ChangeListener(field)); } field.addValueChangeListener(new ChangeListener(field)); - } } @@ -438,8 +438,6 @@ public class CommonDialogWindow extends Window { ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); } else if (content instanceof SoftwareModuleAddUpdateWindow) { ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); - } else if (content instanceof AbstractCreateUpdateTagLayout) { - ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); } mainLayout.addComponent(mandatoryLabel); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java index 9248883c6..a550f0345 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/ConfirmationDialog.java @@ -8,12 +8,14 @@ */ package org.eclipse.hawkbit.ui.common; +import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.springframework.util.StringUtils; +import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.Resource; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; @@ -27,17 +29,44 @@ import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** - * - * module. - * + * Class for the confirmation dialog which pops up when deleting, assigning... + * entities. */ public class ConfirmationDialog implements Button.ClickListener { + private static final long serialVersionUID = 1L; - /** The confirmation callback. */ + private transient ConfirmationDialogCallback callback; + private final Button okButton; + private final Window window; + /** + * Constructor for configuring confirmation dialog. + * + * @param caption + * the dialog caption. + * @param question + * the question. + * @param okLabel + * the Ok button label. + * @param cancelLabel + * the cancel button label. + * @param callback + * the callback. + * @param tab + * ConfirmationTab which contains more information about the + * action which has to be confirmed, e.g. maintenance window + * @param id + * the id of the confirmation window + */ + public ConfirmationDialog(final String caption, final String question, final String okLabel, + final String cancelLabel, final ConfirmationDialogCallback callback, final ConfirmationTab tab, + final String id) { + this(caption, question, okLabel, cancelLabel, callback, null, id, tab); + } + /** * Constructor for configuring confirmation dialog. * @@ -54,7 +83,7 @@ public class ConfirmationDialog implements Button.ClickListener { */ public ConfirmationDialog(final String caption, final String question, final String okLabel, final String cancelLabel, final ConfirmationDialogCallback callback) { - this(caption, question, okLabel, cancelLabel, callback, null, null); + this(caption, question, okLabel, cancelLabel, callback, null, null, null); } /** @@ -75,7 +104,7 @@ public class ConfirmationDialog implements Button.ClickListener { */ public ConfirmationDialog(final String caption, final String question, final String okLabel, final String cancelLabel, final ConfirmationDialogCallback callback, final String id) { - this(caption, question, okLabel, cancelLabel, callback, null, id); + this(caption, question, okLabel, cancelLabel, callback, null, id, null); } /** @@ -96,7 +125,7 @@ public class ConfirmationDialog implements Button.ClickListener { */ public ConfirmationDialog(final String caption, final String question, final String okLabel, final String cancelLabel, final ConfirmationDialogCallback callback, final Resource icon) { - this(caption, question, okLabel, cancelLabel, callback, icon, null); + this(caption, question, okLabel, cancelLabel, callback, icon, null, null); } /** @@ -116,9 +145,13 @@ public class ConfirmationDialog implements Button.ClickListener { * the icon of the dialog * @param id * the id of the confirmation dialog + * @param tab + * ConfirmationTab which contains more information about the + * action which has to be confirmed, e.g. maintenance window */ public ConfirmationDialog(final String caption, final String question, final String okLabel, - final String cancelLabel, final ConfirmationDialogCallback callback, final Resource icon, final String id) { + final String cancelLabel, final ConfirmationDialogCallback callback, final Resource icon, final String id, + final ConfirmationTab tab) { window = new Window(caption); if (!StringUtils.isEmpty(id)) { window.setId(id); @@ -129,29 +162,39 @@ public class ConfirmationDialog implements Button.ClickListener { window.setIcon(icon); } - okButton = SPUIComponentProvider.getButton(UIComponentIdProvider.OK_BUTTON, okLabel, "", - ValoTheme.BUTTON_PRIMARY, false, null, SPUIButtonStyleTiny.class); - okButton.addClickListener(this); + okButton = createOkButton(okLabel); - final Button cancelButton = SPUIComponentProvider.getButton(null, cancelLabel, "", null, false, null, - SPUIButtonStyleTiny.class); - cancelButton.addClickListener(this); - cancelButton.setId(UIComponentIdProvider.CANCEL_BUTTON); + final Button cancelButton = createCancelButton(cancelLabel); window.setModal(true); - window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_SYLE); + window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_STYLE); if (this.callback == null) { this.callback = callback; } final VerticalLayout vLayout = new VerticalLayout(); - if (question != null) { - final Label questionLbl = new Label(String.format("

%s

", question.replaceAll("\n", "
")), - ContentMode.HTML); - questionLbl.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_QUESTION_LABEL); - vLayout.addComponent(questionLbl); - + vLayout.addComponent(createConfirmationQuestion(question)); + } + if (tab != null) { + vLayout.addComponent(tab); } + final HorizontalLayout hButtonLayout = createButtonLayout(cancelButton); + hButtonLayout.addStyleName("marginTop"); + vLayout.addComponent(hButtonLayout); + vLayout.setComponentAlignment(hButtonLayout, Alignment.BOTTOM_CENTER); + + window.setContent(vLayout); + window.setResizable(false); + } + + private static Label createConfirmationQuestion(final String question) { + final Label questionLbl = new Label(String.format("

%s

", question.replaceAll("\n", "
")), + ContentMode.HTML); + questionLbl.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_QUESTION_LABEL); + return questionLbl; + } + + private HorizontalLayout createButtonLayout(final Button cancelButton) { final HorizontalLayout hButtonLayout = new HorizontalLayout(); hButtonLayout.setSpacing(true); hButtonLayout.addComponent(okButton); @@ -159,11 +202,23 @@ public class ConfirmationDialog implements Button.ClickListener { hButtonLayout.setSizeUndefined(); hButtonLayout.setComponentAlignment(okButton, Alignment.TOP_CENTER); hButtonLayout.setComponentAlignment(cancelButton, Alignment.TOP_CENTER); + return hButtonLayout; + } - vLayout.addComponent(hButtonLayout); - vLayout.setComponentAlignment(hButtonLayout, Alignment.BOTTOM_CENTER); - window.setContent(vLayout); - window.setResizable(false); + private Button createCancelButton(final String cancelLabel) { + final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_BUTTON, cancelLabel, "", + null, false, null, SPUIButtonStyleTiny.class); + button.addClickListener(this); + button.setClickShortcut(KeyCode.ESCAPE); + return button; + } + + private Button createOkButton(final String okLabel) { + final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.OK_BUTTON, okLabel, "", + ValoTheme.BUTTON_PRIMARY, false, null, SPUIButtonStyleTiny.class); + button.addClickListener(this); + button.setClickShortcut(KeyCode.ENTER); + return button; } /** @@ -180,11 +235,6 @@ public class ConfirmationDialog implements Button.ClickListener { callback.response(event.getSource().equals(okButton)); } - /** - * Get the window which holds the confirmation dialog - * - * @return the window which holds the confirmation dialog - */ public Window getWindow() { return window; } @@ -203,4 +253,8 @@ public class ConfirmationDialog implements Button.ClickListener { void response(boolean ok); } + public Button getOkButton() { + return okButton; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java index 12d50149a..d6b4ee775 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/builder/LabelBuilder.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.common.builder; +import org.springframework.util.StringUtils; + import com.vaadin.ui.Label; import com.vaadin.ui.themes.ValoTheme; @@ -17,6 +19,8 @@ import com.vaadin.ui.themes.ValoTheme; */ public class LabelBuilder { + private String caption; + private String name; private String id; @@ -25,7 +29,7 @@ public class LabelBuilder { /** * @param name - * the name to set + * the value to set * @return builder */ public LabelBuilder name(final String name) { @@ -33,6 +37,16 @@ public class LabelBuilder { return this; } + /** + * @param caption + * the caption to set + * @return builder + */ + public LabelBuilder caption(final String caption) { + this.caption = caption; + return this; + } + /** * @param id * the id to set @@ -60,7 +74,6 @@ public class LabelBuilder { */ public Label buildCaptionLabel() { final Label label = createLabel(); - label.setValue(name); label.addStyleName("header-caption"); return label; } @@ -75,6 +88,9 @@ public class LabelBuilder { label.setImmediate(false); label.setWidth("-1px"); label.setHeight("-1px"); + if (StringUtils.hasText(caption)) { + label.setCaption(caption); + } return label; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/AbstractConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/AbstractConfirmationWindowLayout.java deleted file mode 100644 index ba759c75c..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/AbstractConfirmationWindowLayout.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.common.confirmwindow.layout; - -import java.util.Map; -import java.util.Map.Entry; - -import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Accordion; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Label; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Abstract layout of confirm actions window. - * - */ -public abstract class AbstractConfirmationWindowLayout extends VerticalLayout { - - private static final long serialVersionUID = 1L; - - private Label actionMessage; - - private Accordion accordion; - - private String consolidatedMessage; - - protected VaadinMessageSource i18n; - - protected transient EventBus.UIEventBus eventBus; - - protected AbstractConfirmationWindowLayout(final VaadinMessageSource i18n, final UIEventBus eventBus) { - this.i18n = i18n; - this.eventBus = eventBus; - } - - /** - * Initialize the confirmation window layout - */ - public void initialize() { - removeAllComponents(); - consolidatedMessage = ""; - createComponents(); - buildLayout(); - } - - private void createComponents() { - createAccordian(); - createActionMessgaeLabel(); - } - - private void createActionMessgaeLabel() { - actionMessage = new LabelBuilder().name("").id(UIComponentIdProvider.ACTION_LABEL).visible(false).buildLabel(); - actionMessage.addStyleName(SPUIStyleDefinitions.CONFIRM_WINDOW_INFO_BOX); - } - - private void createAccordian() { - accordion = new Accordion(); - accordion.setSizeFull(); - } - - private void buildLayout() { - final Map confimrationTabs = getConfirmationTabs(); - for (final Entry captionConfirmationTab : confimrationTabs.entrySet()) { - accordion.addTab(captionConfirmationTab.getValue(), captionConfirmationTab.getKey(), null); - } - final VerticalLayout confirmActionsLayout = new VerticalLayout(); - confirmActionsLayout.addStyleName(SPUIStyleDefinitions.CONFIRM_WINDOW_ACCORDIAN); - confirmActionsLayout.setSpacing(false); - confirmActionsLayout.setMargin(false); - confirmActionsLayout.addComponent(actionMessage); - confirmActionsLayout.addComponent(accordion); - - addComponent(confirmActionsLayout); - setComponentAlignment(confirmActionsLayout, Alignment.MIDDLE_CENTER); - setSpacing(false); - setMargin(false); - } - - /** - * Add to the consolidated result message which will be displayed in the - * notification on closing the window. Each message that will be added in - * new line of previous messages using html
- * - * @param message - * to be added to the consolidated messages. - */ - public void addToConsolitatedMsg(final String message) { - if (consolidatedMessage != null && consolidatedMessage.length() > 0) { - consolidatedMessage = consolidatedMessage + "
"; - } - consolidatedMessage = consolidatedMessage + message; - } - - /** - * @param tab - */ - protected void removeCurrentTab(final ConfirmationTab tab) { - accordion.removeComponent(tab); - } - - /** - * - * @param message - */ - protected void setActionMessage(final String message) { - actionMessage.setValue(message); - actionMessage.setVisible(true); - } - - /** - * Get contents for each tab to be displayed in the accordian. - * - * @return map of caption and content for each tab. - */ - protected abstract Map getConfirmationTabs(); - - /** - * @return the consolidatedMessage - */ - public String getConsolidatedMessage() { - return consolidatedMessage; - } - - protected Button createDiscardButton(final Object itemId, final ClickListener clickListener) { - final Button deletesDsIcon = SPUIComponentProvider.getButton("", "", SPUILabelDefinitions.DISCARD, - ValoTheme.BUTTON_TINY + " " + SPUIStyleDefinitions.REDICON, true, FontAwesome.REPLY, - SPUIButtonStyleSmallNoBorder.class); - deletesDsIcon.setData(itemId); - deletesDsIcon.setImmediate(true); - deletesDsIcon.addClickListener(clickListener); - return deletesDsIcon; - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/ConfirmationTab.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/ConfirmationTab.java index 293cd7c97..2e674e85b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/ConfirmationTab.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/confirmwindow/layout/ConfirmationTab.java @@ -8,144 +8,26 @@ */ package org.eclipse.hawkbit.ui.common.confirmwindow.layout; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; - -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; /** * Confirmation tab of confirmation window. */ public class ConfirmationTab extends VerticalLayout { - private static final long serialVersionUID = -5211351556595775554L; - - private Table table; - - private Button confirmAll; - - private Button discardAll; + private static final long serialVersionUID = 1L; /** * Default constructor. */ public ConfirmationTab() { - createComponents(); buildLayout(); } - private void createComponents() { - // Create table - createTable(); - - // Create confirm all button - createConfirmAllButton(); - - // Create discard all button - createDiscardAllButton(); - - } - private void buildLayout() { - final HorizontalLayout btnLayout = new HorizontalLayout(); - btnLayout.setSpacing(true); - - btnLayout.addStyleName(SPUIStyleDefinitions.SP_ACCORDION_TAB_BTN); - btnLayout.addComponent(confirmAll); - btnLayout.setComponentAlignment(confirmAll, Alignment.MIDDLE_CENTER); - btnLayout.addComponent(discardAll); - btnLayout.setComponentAlignment(discardAll, Alignment.MIDDLE_CENTER); - setSizeFull(); setMargin(false); setSpacing(false); - - addComponent(table); - setComponentAlignment(table, Alignment.MIDDLE_CENTER); - addComponent(btnLayout); - setComponentAlignment(btnLayout, Alignment.MIDDLE_CENTER); - } - - private void createDiscardAllButton() { - discardAll = SPUIComponentProvider.getButton(null, SPUILabelDefinitions.DISCARD_ALL, "", null, false, null, - SPUIButtonStyleTiny.class); - discardAll.setIcon(FontAwesome.REPLY); - } - - private void createConfirmAllButton() { - confirmAll = SPUIComponentProvider.getButton(null, "", "", ValoTheme.BUTTON_PRIMARY, false, null, - SPUIButtonStyleTiny.class); - confirmAll.setIcon(FontAwesome.REPLY); - } - - private void createTable() { - table = new Table(); - table.setSizeFull(); - table.setPageLength(SPUIDefinitions.ACCORDION_TAB_DETAILS_PAGE_LENGTH); - // Build Style - final StringBuilder style = new StringBuilder(ValoTheme.TABLE_COMPACT); - style.append(' '); - style.append(ValoTheme.TABLE_SMALL); - style.append(' '); - style.append(ValoTheme.TABLE_NO_VERTICAL_LINES); - // Set style - table.addStyleName(style.toString()); - table.addStyleName("accordion-tab-table-style"); - table.setImmediate(true); - } - - /** - * @return the table - */ - public Table getTable() { - return table; - } - - /** - * @param table - * the table to set - */ - public void setTable(final Table table) { - this.table = table; - } - - /** - * @return the confirmAll - */ - public Button getConfirmAll() { - return confirmAll; - } - - /** - * @param confirmAll - * the confirmAll to set - */ - public void setConfirmAll(final Button confirmAll) { - this.confirmAll = confirmAll; - } - - /** - * @return the discardAll - */ - public Button getDiscardAll() { - return discardAll; - } - - /** - * @param discardAll - * the discardAll to set - */ - public void setDiscardAll(final Button discardAll) { - this.discardAll = discardAll; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java index 27469ea5e..9ba7f9bc1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractDistributionSetDetails.java @@ -103,6 +103,11 @@ public abstract class AbstractDistributionSetDetails return UIComponentIdProvider.DS_EDIT_BUTTON; } + @Override + protected String getMetadataButtonId() { + return UIComponentIdProvider.DS_METADATA_BUTTON; + } + @Override protected boolean hasEditPermission() { return getPermissionChecker().hasUpdateRepositoryPermission(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractMetadataDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractMetadataDetailsLayout.java index a9949e0c7..349500329 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractMetadataDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractMetadataDetailsLayout.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui.common.detailslayout; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import com.vaadin.data.Item; @@ -25,7 +25,9 @@ import com.vaadin.ui.themes.ValoTheme; */ public abstract class AbstractMetadataDetailsLayout extends Table { - protected static final String METADATA_KEY = "Key"; + private static final long serialVersionUID = 1L; + + private static final String METADATA_KEY = "Key"; protected static final int MAX_METADATA_QUERY = 500; @@ -80,7 +82,7 @@ public abstract class AbstractMetadataDetailsLayout extends Table { private Button customMetadataDetailButton(final String metadataKey) { final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, - "View " + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); + "View " + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleNoBorder.class); viewIcon.setData(metadataKey); viewIcon.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" + " " + "text-style"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractNamedVersionedEntityTableDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractNamedVersionedEntityTableDetailsLayout.java index 571cddbc9..fe7b392b6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractNamedVersionedEntityTableDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractNamedVersionedEntityTableDetailsLayout.java @@ -34,4 +34,5 @@ public abstract class AbstractNamedVersionedEntityTableDetailsLayout extends private final ManagementUIState managementUIState; + private HorizontalLayout nameEditLayout; + protected AbstractTableDetailsLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, final SpPermissionChecker permissionChecker, final ManagementUIState managementUIState) { this.i18n = i18n; @@ -227,21 +229,21 @@ public abstract class AbstractTableDetailsLayout extends return managementUIState; } - private void createComponents() { + protected void createComponents() { caption = createHeaderCaption(); caption.setImmediate(true); caption.setContentMode(ContentMode.HTML); caption.setId(getDetailsHeaderCaptionId()); editButton = SPUIComponentProvider.getButton("", "", "", null, false, FontAwesome.PENCIL_SQUARE_O, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); editButton.setId(getEditButtonId()); editButton.addClickListener(this::onEdit); editButton.setEnabled(false); manageMetadataBtn = SPUIComponentProvider.getButton("", "", "", null, false, FontAwesome.LIST_ALT, - SPUIButtonStyleSmallNoBorder.class); - manageMetadataBtn.setId(getEditButtonId()); + SPUIButtonStyleNoBorder.class); + manageMetadataBtn.setId(getMetadataButtonId()); manageMetadataBtn.setDescription(i18n.getMessage("tooltip.metadata.icon")); manageMetadataBtn.addClickListener(this::showMetadata); manageMetadataBtn.setEnabled(false); @@ -254,8 +256,8 @@ public abstract class AbstractTableDetailsLayout extends detailsTab.setId(getTabSheetId()); } - private void buildLayout() { - final HorizontalLayout nameEditLayout = new HorizontalLayout(); + protected void buildLayout() { + nameEditLayout = new HorizontalLayout(); nameEditLayout.setWidth(100.0F, Unit.PERCENTAGE); nameEditLayout.addComponent(caption); nameEditLayout.setComponentAlignment(caption, Alignment.TOP_LEFT); @@ -288,7 +290,7 @@ public abstract class AbstractTableDetailsLayout extends * If there is no data in table (i.e. no row selected), then disable the * edit button. If row is selected, enable edit button. */ - private void populateData(final T selectedBaseEntity) { + protected void populateData(final T selectedBaseEntity) { this.selectedBaseEntity = selectedBaseEntity; editButton.setEnabled(selectedBaseEntity != null); manageMetadataBtn.setEnabled(selectedBaseEntity != null); @@ -335,6 +337,8 @@ public abstract class AbstractTableDetailsLayout extends protected abstract String getEditButtonId(); + protected abstract String getMetadataButtonId(); + protected abstract boolean onLoadIsTableMaximized(); protected abstract String getTabSheetId(); @@ -349,4 +353,12 @@ public abstract class AbstractTableDetailsLayout extends protected abstract void showMetadata(Button.ClickEvent event); + public HorizontalLayout getNameEditLayout() { + return nameEditLayout; + } + + public Button getEditButton() { + return editButton; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 4bbcbe483..99906b581 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; @@ -223,7 +223,7 @@ public class SoftwareModuleDetailsTable extends Table { horizontalLayout.setSizeFull(); final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(""); final Button reassignSoftModule = SPUIComponentProvider.getButton(sw.getName(), "", "", "", true, - FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TIMES, SPUIButtonStyleNoBorder.class); reassignSoftModule .addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules)); final String softwareModNameVersion = HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTagFilterHeaderEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTagFilterHeaderEvent.java new file mode 100644 index 000000000..ca4ce4183 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTagFilterHeaderEvent.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.event; + +/** + * Event which is thrown when menubar item in the filter header is chosen or + * modify modus is closed. + * + */ +public class DistributionSetTagFilterHeaderEvent extends FilterHeaderEvent { + + /** + * Constructor + * + * @param filterHeaderEnum + * FilterHeaderEnum + */ + public DistributionSetTagFilterHeaderEvent(final FilterHeaderEnum filterHeaderEnum) { + super(filterHeaderEnum); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTypeFilterHeaderEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTypeFilterHeaderEvent.java new file mode 100644 index 000000000..c6a1f0d2b --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/DistributionSetTypeFilterHeaderEvent.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.event; + +/** + * Event which is thrown when menubar item in the filter header is chosen or + * modify modus is closed. + * + */ +public class DistributionSetTypeFilterHeaderEvent extends FilterHeaderEvent { + + /** + * Constructor + * + * @param filterHeaderEnum + * FilterHeaderEnum + */ + public DistributionSetTypeFilterHeaderEvent(final FilterHeaderEnum filterHeaderEnum) { + super(filterHeaderEnum); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/FilterHeaderEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/FilterHeaderEvent.java new file mode 100644 index 000000000..c632b7524 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/FilterHeaderEvent.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.event; + +/** + * Event class for the table header of the tags and types table. Event is fired + * when the edit or delete modus of a tag or type is closed by clicking on the + * cancel icon. The menubar for selecting a tag/type action is shown again. + */ +public class FilterHeaderEvent { + + /** + * FilterHeaderEnum which describes the action to execute + */ + public enum FilterHeaderEnum { + SHOW_MENUBAR, SHOW_CANCEL_BUTTON + } + + private final FilterHeaderEnum filterHeaderEnum; + + /** + * Constructor + * + * @param filterHeaderEnum + * Enum which describes the action to execute + */ + public FilterHeaderEvent(final FilterHeaderEnum filterHeaderEnum) { + this.filterHeaderEnum = filterHeaderEnum; + } + + public FilterHeaderEnum getFilterHeaderEnum() { + return filterHeaderEnum; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/SoftwareModuleTypeFilterHeaderEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/SoftwareModuleTypeFilterHeaderEvent.java new file mode 100644 index 000000000..aada1254f --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/SoftwareModuleTypeFilterHeaderEvent.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.event; + +/** + * Event which is thrown when menubar item in the filter header is chosen or + * modify modus is closed. + * + */ +public class SoftwareModuleTypeFilterHeaderEvent extends FilterHeaderEvent { + + /** + * Constructor + * + * @param filterHeaderEnum + * FilterHeaderEnum + */ + public SoftwareModuleTypeFilterHeaderEvent(final FilterHeaderEnum filterHeaderEnum) { + super(filterHeaderEnum); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/TargetTagFilterHeaderEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/TargetTagFilterHeaderEvent.java new file mode 100644 index 000000000..c791dd550 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/event/TargetTagFilterHeaderEvent.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.common.event; + +/** + * Event which is thrown when menubar item in the filter header is chosen or + * modify modus is closed. + * + */ +public class TargetTagFilterHeaderEvent extends FilterHeaderEvent { + + /** + * Constructor + * + * @param filterHeaderEnum + * FilterHeaderEnum + */ + public TargetTagFilterHeaderEvent(final FilterHeaderEnum filterHeaderEnum) { + super(filterHeaderEnum); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java index 0735b53d9..7ac2b3898 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java @@ -11,13 +11,20 @@ package org.eclipse.hawkbit.ui.common.filterlayout; import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.NO_TAG_BUTTON_ID; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.decorators.SPUITagButtonStyle; +import org.eclipse.hawkbit.ui.management.tag.TagIdName; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.util.StringUtils; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.spring.events.EventBus; @@ -27,9 +34,14 @@ import com.vaadin.data.Item; import com.vaadin.event.dd.DropHandler; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.DragAndDropWrapper.DragStartMode; import com.vaadin.ui.Table; +import com.vaadin.ui.UI; +import com.vaadin.ui.Window; +import com.vaadin.ui.Window.CloseEvent; +import com.vaadin.ui.Window.CloseListener; import com.vaadin.ui.themes.ValoTheme; /** @@ -37,20 +49,22 @@ import com.vaadin.ui.themes.ValoTheme; */ public abstract class AbstractFilterButtons extends Table { - private static final long serialVersionUID = 7783305719009746375L; + private static final long serialVersionUID = 1L; - private static final String DEFAULT_GREEN = "rgb(44,151,32)"; + protected static final String DEFAULT_GREEN = "rgb(44,151,32)"; protected static final String FILTER_BUTTON_COLUMN = "filterButton"; - protected transient EventBus.UIEventBus eventBus; + private final transient EventBus.UIEventBus eventBus; - protected final AbstractFilterButtonClickBehaviour filterButtonClickBehaviour; + private final AbstractFilterButtonClickBehaviour filterButtonClickBehaviour; + + private final VaadinMessageSource i18n; protected AbstractFilterButtons(final UIEventBus eventBus, - final AbstractFilterButtonClickBehaviour filterButtonClickBehaviour) { + final AbstractFilterButtonClickBehaviour filterButtonClickBehaviour, final VaadinMessageSource i18n) { this.eventBus = eventBus; - + this.i18n = i18n; this.filterButtonClickBehaviour = filterButtonClickBehaviour; createTable(); if (doSubscribeToEventBus()) { @@ -77,8 +91,8 @@ public abstract class AbstractFilterButtons extends Table { addColumn(); setTableVisibleColumns(); setDragMode(TableDragMode.NONE); - setSelectable(false); setSizeFull(); + setSelectable(false); } private void setStyle() { @@ -101,6 +115,95 @@ public abstract class AbstractFilterButtons extends Table { addGeneratedColumn(FILTER_BUTTON_COLUMN, (source, itemId, columnId) -> addGeneratedCell(itemId)); } + /** + * Insert the update icons next to the filter tags in target, distribution + * and software module tags/types tables + */ + public void addUpdateColumn() { + if (alreadyContainsColumn(SPUIDefinitions.UPDATE_FILTER_BUTTON_COLUMN)) { + return; + } + deleteColumnIfVisible(SPUIDefinitions.DELETE_FILTER_BUTTON_COLUMN); + addGeneratedColumn(SPUIDefinitions.UPDATE_FILTER_BUTTON_COLUMN, + (source, itemId, columnId) -> addUpdateCell(itemId)); + } + + /** + * Insert the delete icons next to the filter tags in target, distribution + * and software module tags/types tables + */ + public void addDeleteColumn() { + if (alreadyContainsColumn(SPUIDefinitions.DELETE_FILTER_BUTTON_COLUMN)) { + return; + } + deleteColumnIfVisible(SPUIDefinitions.UPDATE_FILTER_BUTTON_COLUMN); + addGeneratedColumn(SPUIDefinitions.DELETE_FILTER_BUTTON_COLUMN, + (source, itemId, columnId) -> addDeleteCell(itemId)); + } + + /** + * Removes the edit and delete icon next to the filter tags in target, + * distribution and software module tags/types tables, when the edit/delete + * action is executed or cancelled + */ + public void removeUpdateAndDeleteColumn() { + removeGeneratedColumn(SPUIDefinitions.UPDATE_FILTER_BUTTON_COLUMN); + removeGeneratedColumn(SPUIDefinitions.DELETE_FILTER_BUTTON_COLUMN); + } + + private List getVisibleColumnsAsList() { + return Arrays.asList(getVisibleColumns()); + } + + private void deleteColumnIfVisible(final String columnName) { + final List columns = getVisibleColumnsAsList(); + if (columns.contains(columnName)) { + removeGeneratedColumn(columnName); + } + } + + private boolean alreadyContainsColumn(final String columnName) { + return getVisibleColumnsAsList().contains(columnName); + } + + private Object addDeleteCell(final Object itemId) { + if (itemId instanceof TagIdName && SPUIDefinitions.NO_TAG.equals(((TagIdName) itemId).getName())) { + return null; + } + + final Button deleteButton = SPUIComponentProvider.getButton("", "", "", "", true, FontAwesome.TRASH_O, + SPUIButtonStyleNoBorder.class); + if (itemId instanceof TagIdName) { + deleteButton.setId(UIComponentIdProvider.DELETE_TAG_ID + ((TagIdName) itemId).getName()); + } else { + deleteButton.setId(UIComponentIdProvider.DELETE_TAG_ID + itemId.toString()); + } + deleteButton.setDescription(SPUIDefinitions.DELETE); + deleteButton.addClickListener(this::addDeleteButtonClickListener); + return deleteButton; + } + + private Button addUpdateCell(final Object itemId) { + if (itemId instanceof TagIdName && SPUIDefinitions.NO_TAG.equals(((TagIdName) itemId).getName())) { + return null; + } + + final Button editButton = SPUIComponentProvider.getButton("", "", "", "", true, FontAwesome.EDIT, + SPUIButtonStyleNoBorder.class); + if (itemId instanceof TagIdName) { + editButton.setId(UIComponentIdProvider.UPDATE_TAG_ID + ((TagIdName) itemId).getName()); + } else { + editButton.setId(UIComponentIdProvider.UPDATE_TAG_ID + itemId.toString()); + } + editButton.setDescription(SPUIDefinitions.EDIT); + editButton.addClickListener(this::addEditButtonClickListener); + return editButton; + } + + protected abstract void addEditButtonClickListener(final ClickEvent event); + + protected abstract void addDeleteButtonClickListener(final ClickEvent event); + private DragAndDropWrapper addGeneratedCell(final Object itemId) { final Item item = getItem(itemId); @@ -115,7 +218,6 @@ public abstract class AbstractFilterButtons extends Table { if ((NO_TAG_BUTTON_ID.equals(typeButton.getData()) && isNoTagStateSelected()) || (id != null && isClickedByDefault(name))) { - filterButtonClickBehaviour.setDefaultClickedButton(typeButton); } @@ -149,7 +251,7 @@ public abstract class AbstractFilterButtons extends Table { columnIds.add(FILTER_BUTTON_COLUMN); setVisibleColumns(columnIds.toArray()); setColumnHeaderMode(ColumnHeaderMode.HIDDEN); - setColumnWidth(FILTER_BUTTON_COLUMN, 137); + setColumnWidth(FILTER_BUTTON_COLUMN, 120); } private Button createFilterButton(final Long id, final String name, final String description, final String color, @@ -187,10 +289,61 @@ public abstract class AbstractFilterButtons extends Table { return caption.toString(); } - protected void refreshTable() { - setContainerDataSource(createButtonsLazyQueryContainer()); + protected String getEntityId(final ClickEvent event) { + final String buttonId = event.getButton().getId(); + if (!StringUtils.hasText(buttonId)) { + return ""; + } + if (buttonId.startsWith(UIComponentIdProvider.UPDATE_TAG_ID)) { + return buttonId.substring(UIComponentIdProvider.UPDATE_TAG_ID.length()); + } + if (buttonId.startsWith(UIComponentIdProvider.DELETE_TAG_ID)) { + return buttonId.substring(UIComponentIdProvider.DELETE_TAG_ID.length()); + } + return ""; } + /** + * Refreshes the tags tables + */ + public void refreshTable() { + setContainerDataSource(createButtonsLazyQueryContainer()); + removeUpdateAndDeleteColumn(); + } + + protected void openConfirmationWindowForDeletion(final String entityToDelete, final String entityName, + final FilterHeaderEvent event) { + final ConfirmationDialog confirmDialog = new ConfirmationDialog( + i18n.getMessage("caption.entity.delete.action.confirmbox"), + i18n.getMessage("message.confirm.delete.entity", entityName.toLowerCase(), + entityToDelete.substring(entityToDelete.indexOf('.') + 1), ""), + i18n.getMessage(SPUIDefinitions.BUTTON_OK), i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { + if (ok) { + deleteEntity(entityToDelete); + } else { + removeUpdateAndDeleteColumn(); + getEventBus().publish(this, event); + } + }); + confirmDialog.getWindow().addCloseListener(getCloseListenerForEditAndDeleteTag(event)); + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + protected CloseListener getCloseListenerForEditAndDeleteTag(final FilterHeaderEvent event) { + return new Window.CloseListener() { + private static final long serialVersionUID = 1L; + + @Override + public void windowClose(final CloseEvent e) { + removeUpdateAndDeleteColumn(); + getEventBus().publish(this, event); + } + }; + } + + protected abstract void deleteEntity(String entityToDelete); + /** * Id of the buttons table to be used in test cases. * @@ -243,4 +396,17 @@ public abstract class AbstractFilterButtons extends Table { * @return button wrapper info. */ protected abstract String getButtonWrapperData(); + + protected EventBus.UIEventBus getEventBus() { + return eventBus; + } + + protected VaadinMessageSource getI18n() { + return i18n; + } + + protected AbstractFilterButtonClickBehaviour getFilterButtonClickBehaviour() { + return filterButtonClickBehaviour; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java index 3caba27b7..8e8edc6d5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterHeader.java @@ -10,9 +10,13 @@ package org.eclipse.hawkbit.ui.common.filterlayout; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.components.ConfigMenuBar; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -20,8 +24,10 @@ import org.vaadin.spring.events.EventBus.UIEventBus; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar.Command; import com.vaadin.ui.VerticalLayout; /** @@ -29,61 +35,130 @@ import com.vaadin.ui.VerticalLayout; */ public abstract class AbstractFilterHeader extends VerticalLayout { - private static final long serialVersionUID = -1388340600522323332L; + private static final long serialVersionUID = 1L; - protected SpPermissionChecker permChecker; + private final SpPermissionChecker permChecker; - protected transient EventBus.UIEventBus eventBus; + private final transient EventBus.UIEventBus eventBus; private Label title; - private Button config; - private Button hideIcon; - protected final VaadinMessageSource i18n; + private ConfigMenuBar menu; - protected AbstractFilterHeader(final SpPermissionChecker permChecker, final UIEventBus eventBus, final VaadinMessageSource i18n) { + private final VaadinMessageSource i18n; + + private HorizontalLayout typeHeaderLayout; + + private Button cancelTagButton; + + protected AbstractFilterHeader(final SpPermissionChecker permChecker, final UIEventBus eventBus, + final VaadinMessageSource i18n) { this.permChecker = permChecker; this.eventBus = eventBus; this.i18n = i18n; createComponents(); buildLayout(); + if (doSubscribeToEventBus()) { + eventBus.subscribe(this); + } } /** - * Create required components. + * Subscribes the view to the eventBus. Method has to be overriden (return + * false) if the view does not contain any listener to avoid Vaadin blowing + * up our logs with warnings. */ + protected boolean doSubscribeToEventBus() { + return true; + } + + protected void removeMenuBarAndAddCancelButton() { + typeHeaderLayout.removeComponent(menu); + typeHeaderLayout.addComponent(createCancelButtonForUpdateOrDeleteTag(), 1); + } + + private Button createCancelButtonForUpdateOrDeleteTag() { + cancelTagButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_UPDATE_TAG_ID, "", "", null, + false, FontAwesome.TIMES_CIRCLE, SPUIButtonStyleNoBorder.class); + cancelTagButton.addClickListener(this::cancelUpdateOrDeleteTag); + return cancelTagButton; + } + + @SuppressWarnings("squid:S1172") + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + removeCancelButtonAndAddMenuBar(); + } + private void createComponents() { title = createHeaderCaption(); - if (hasCreateUpdatePermission() && isAddTagRequired()) { - config = SPUIComponentProvider.getButton(getConfigureFilterButtonId(), "", "", "", true, FontAwesome.COG, - SPUIButtonStyleSmallNoBorder.class); - config.addClickListener(this::settingsIconClicked); + if (isAddTagRequired()) { + menu = new ConfigMenuBar(permChecker.hasCreateRepositoryPermission(), + permChecker.hasUpdateRepositoryPermission(), permChecker.hasDeleteRepositoryPermission(), + getAddButtonCommand(), getUpdateButtonCommand(), getDeleteButtonCommand(), getMenuBarId()); } hideIcon = SPUIComponentProvider.getButton(getHideButtonId(), "", "", "", true, FontAwesome.TIMES, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); hideIcon.addClickListener(event -> hideFilterButtonLayout()); } + protected void processFilterHeaderEvent(final FilterHeaderEvent event) { + if (FilterHeaderEnum.SHOW_MENUBAR == event.getFilterHeaderEnum() + && typeHeaderLayout.getComponent(1).equals(cancelTagButton)) { + removeCancelButtonAndAddMenuBar(); + } else if (FilterHeaderEnum.SHOW_CANCEL_BUTTON == event.getFilterHeaderEnum()) { + removeMenuBarAndAddCancelButton(); + } + } + /** - * Build layout. + * Returns the id for the menubar element for configuring tags and types + * + * @return String with id */ + protected abstract String getMenuBarId(); + + /** + * Command which should be executed when clicking on the delete tag button + * in the menubar + * + * @return Command + */ + protected abstract Command getDeleteButtonCommand(); + + /** + * Command which should be executed when clicking on the update tag button + * in the menubar + * + * @return Command + */ + protected abstract Command getUpdateButtonCommand(); + + /** + * Command which should be executed when clicking on the create tag button + * in the menubar + * + * @return Command + */ + protected abstract Command getAddButtonCommand(); + private void buildLayout() { setStyleName("filter-btns-header-layout"); - final HorizontalLayout typeHeaderLayout = new HorizontalLayout(); - typeHeaderLayout.setWidth(100.0f, Unit.PERCENTAGE); + typeHeaderLayout = new HorizontalLayout(); + typeHeaderLayout.setHeight(32, Unit.PIXELS); + typeHeaderLayout.setWidth(100.0F, Unit.PERCENTAGE); typeHeaderLayout.addComponentAsFirst(title); typeHeaderLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE); typeHeaderLayout.setComponentAlignment(title, Alignment.TOP_LEFT); - if (config != null && hasCreateUpdatePermission()) { - typeHeaderLayout.addComponent(config); - typeHeaderLayout.setComponentAlignment(config, Alignment.TOP_RIGHT); + if (menu != null) { + typeHeaderLayout.addComponent(menu); + typeHeaderLayout.setComponentAlignment(menu, Alignment.TOP_RIGHT); } typeHeaderLayout.addComponent(hideIcon); typeHeaderLayout.setComponentAlignment(hideIcon, Alignment.TOP_RIGHT); - typeHeaderLayout.setExpandRatio(title, 1.0f); + typeHeaderLayout.setExpandRatio(title, 1.0F); addComponent(typeHeaderLayout); } @@ -91,18 +166,17 @@ public abstract class AbstractFilterHeader extends VerticalLayout { return new LabelBuilder().name(getTitle()).buildCaptionLabel(); } - /** - * - * @return - */ - protected abstract String getHideButtonId(); + protected void removeCancelButtonAndAddMenuBar() { + typeHeaderLayout.removeComponent(cancelTagButton); + typeHeaderLayout.addComponent(menu, 1); + } /** - * Check if user is authorized for this action. + * Returns the id of the hide filter button * - * @return true if user has permission otherwise false. + * @return String containing the id */ - protected abstract boolean hasCreateUpdatePermission(); + protected abstract String getHideButtonId(); /** * Get the title to be displayed on the header of filter button layout. @@ -111,14 +185,6 @@ public abstract class AbstractFilterHeader extends VerticalLayout { */ protected abstract String getTitle(); - /** - * This method will be called when settings icon (or) clicked on the header. - * - * @param event - * reference of {@link Button.ClicEvent}. - */ - protected abstract void settingsIconClicked(final Button.ClickEvent event); - /** * Space required to show drop hits in the filter layout header. * @@ -137,8 +203,27 @@ public abstract class AbstractFilterHeader extends VerticalLayout { protected abstract String getConfigureFilterButtonId(); /** - * @return + * Returns the information if the icon for configuring tags should be + * visible + * + * @return boolean */ protected abstract boolean isAddTagRequired(); + protected SpPermissionChecker getPermChecker() { + return permChecker; + } + + protected EventBus.UIEventBus getEventBus() { + return eventBus; + } + + protected VaadinMessageSource getI18n() { + return i18n; + } + + protected HorizontalLayout getTypeHeaderLayout() { + return typeHeaderLayout; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterLayout.java index cade4737c..e7a28fdbb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterLayout.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.common.filterlayout; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.vaadin.spring.events.EventBus.UIEventBus; import com.vaadin.ui.Alignment; import com.vaadin.ui.VerticalLayout; @@ -18,16 +19,21 @@ import com.vaadin.ui.VerticalLayout; */ public abstract class AbstractFilterLayout extends VerticalLayout { - private static final long serialVersionUID = 9190616426688385851L; + private static final long serialVersionUID = 1L; private final AbstractFilterHeader filterHeader; private final AbstractFilterButtons filterButtons; - protected AbstractFilterLayout(final AbstractFilterHeader filterHeader, final AbstractFilterButtons filterButtons) { + private final transient UIEventBus eventBus; + + protected AbstractFilterLayout(final AbstractFilterHeader filterHeader, final AbstractFilterButtons filterButtons, + final UIEventBus eventBus) { this.filterHeader = filterHeader; this.filterButtons = filterButtons; + this.eventBus = eventBus; buildLayout(); + eventBus.subscribe(this); } private void buildLayout() { @@ -65,4 +71,9 @@ public abstract class AbstractFilterLayout extends VerticalLayout { * @return true if filter is cleaned before. */ public abstract Boolean onLoadIsTypeFilterIsClosed(); + + public UIEventBus getEventBus() { + return eventBus; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java deleted file mode 100644 index b9ef01abf..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java +++ /dev/null @@ -1,397 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.common.footer; - -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.Component; -import com.vaadin.ui.DragAndDropWrapper; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Parent class for footer layout. - */ -public abstract class AbstractDeleteActionsLayout extends VerticalLayout implements DropHandler { - - private static final long serialVersionUID = 1L; - - protected VaadinMessageSource i18n; - - protected SpPermissionChecker permChecker; - - protected transient EventBus.UIEventBus eventBus; - - protected UINotification notification; - - private DragAndDropWrapper deleteWrapper; - - private Button noActionBtn; - - private Window unsavedActionsWindow; - - private Button bulkUploadStatusButton; - - protected AbstractDeleteActionsLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, - final UIEventBus eventBus, final UINotification notification) { - this.i18n = i18n; - this.permChecker = permChecker; - this.eventBus = eventBus; - this.notification = notification; - if (doSubscribeToEventBus()) { - eventBus.subscribe(this); - } - } - - /** - * Subscribes the view to the eventBus. Method has to be overriden (return - * false) if the view does not contain any listener to avoid Vaadin blowing - * up our logs with warnings. - */ - protected boolean doSubscribeToEventBus() { - return true; - } - - protected void init() { - if (hasCountMessage() || hasDeletePermission() || hasUpdatePermission() || hasBulkUploadPermission()) { - createComponents(); - buildLayout(); - reload(); - } - } - - protected void reload() { - restoreActionCount(); - restoreBulkUploadStatusCount(); - } - - protected void createComponents() { - if (hasDeletePermission()) { - deleteWrapper = createDeleteWrapperLayout(); - } - if (hasDeletePermission() || hasUpdatePermission()) { - noActionBtn = createActionsButton(); - } - if (hasBulkUploadPermission()) { - bulkUploadStatusButton = createBulkUploadStatusButton(); - } - } - - protected void buildLayout() { - final HorizontalLayout dropHintLayout = new HorizontalLayout(); - if (hasCountMessage()) { - dropHintLayout.addComponent(getCountMessageLabel()); - } - final HorizontalLayout hLayout = new HorizontalLayout(); - hLayout.setId(UIComponentIdProvider.ACTION_BUTTON_LAYOUT); - hLayout.setSpacing(true); - hLayout.setSizeUndefined(); - if (deleteWrapper != null) { - hLayout.addComponent(deleteWrapper); - hLayout.setComponentAlignment(deleteWrapper, Alignment.BOTTOM_LEFT); - } - if (noActionBtn != null) { - hLayout.addComponent(noActionBtn); - hLayout.setComponentAlignment(noActionBtn, Alignment.BOTTOM_LEFT); - } - if (bulkUploadStatusButton != null) { - hLayout.addComponent(bulkUploadStatusButton); - hLayout.setComponentAlignment(bulkUploadStatusButton, Alignment.BOTTOM_LEFT); - } - if (dropHintLayout.getComponentCount() > 0) { - addComponent(dropHintLayout); - setComponentAlignment(dropHintLayout, Alignment.BOTTOM_CENTER); - } - if (hLayout.getComponentCount() > 0) { - addComponent(hLayout); - setComponentAlignment(hLayout, Alignment.BOTTOM_CENTER); - } - setStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); - setWidth("100%"); - } - - private DragAndDropWrapper createDeleteWrapperLayout() { - final Button dropToDelete = new Button(i18n.getMessage("label.components.drop.area")); - dropToDelete.setCaptionAsHtml(true); - dropToDelete.setIcon(FontAwesome.TRASH_O); - dropToDelete.addStyleName(ValoTheme.BUTTON_BORDERLESS); - dropToDelete.addStyleName("drop-to-delete-button"); - dropToDelete.addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - dropToDelete.addStyleName(SPUIStyleDefinitions.DEL_ACTION_BUTTON); - dropToDelete.addStyleName("delete-icon"); - - final DragAndDropWrapper wrapper = new DragAndDropWrapper(dropToDelete); - wrapper.setStyleName(ValoTheme.BUTTON_PRIMARY); - wrapper.setId(getDeleteAreaId()); - wrapper.setDropHandler(this); - wrapper.addStyleName("delete-button-border"); - return wrapper; - } - - private Button createActionsButton() { - final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.PENDING_ACTION_BUTTON, - getNoActionsButtonLabel(), "", "", false, FontAwesome.BELL, SPUIButtonStyleSmall.class); - button.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - button.addStyleName(SPUIStyleDefinitions.DEL_ACTION_BUTTON); - - button.addClickListener(event -> actionButtonClicked()); - button.setHtmlContentAllowed(true); - return button; - } - - private Button createBulkUploadStatusButton() { - final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.BULK_UPLOAD_STATUS_BUTTON, "", "", - "", false, null, SPUIButtonStyleSmall.class); - button.setStyleName(SPUIStyleDefinitions.ACTION_BUTTON); - button.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - button.setWidth("100px"); - button.setHtmlContentAllowed(true); - button.addClickListener(event -> onClickBulkUploadNotificationButton()); - button.setVisible(false); - return button; - } - - private void onClickBulkUploadNotificationButton() { - hideBulkUploadStatusButton(); - showBulkUploadWindow(); - } - - protected void setUploadStatusButtonCaption(final int count) { - if (bulkUploadStatusButton == null) { - return; - } - bulkUploadStatusButton.setCaption("
" + count + "
"); - } - - protected void enableBulkUploadStatusButton() { - if (bulkUploadStatusButton == null) { - return; - } - bulkUploadStatusButton.setVisible(true); - } - - protected void updateUploadBtnIconToComplete() { - if (bulkUploadStatusButton == null) { - return; - } - bulkUploadStatusButton.removeStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - bulkUploadStatusButton.setIcon(FontAwesome.UPLOAD); - } - - protected void updateUploadBtnIconToProgressIndicator() { - if (bulkUploadStatusButton == null) { - return; - } - bulkUploadStatusButton.addStyleName(SPUIStyleDefinitions.UPLOAD_PROGRESS_INDICATOR_STYLE); - bulkUploadStatusButton.setIcon(null); - } - - protected void actionButtonClicked() { - if (!hasUnsavedActions()) { - return; - } - unsavedActionsWindow = new WindowBuilder(SPUIDefinitions.CONFIRMATION_WINDOW) - .caption(getUnsavedActionsWindowCaption()).id(UIComponentIdProvider.CONFIRMATION_POPUP_ID) - .content(getUnsavedActionsWindowContent()).buildWindow(); - unsavedActionsWindow.addCloseListener(event -> unsavedActionsWindowClosed()); - UI.getCurrent().addWindow(unsavedActionsWindow); - } - - /** - * It will close the unsaved actions window. - */ - protected void closeUnsavedActionsWindow() { - UI.getCurrent().removeWindow(unsavedActionsWindow); - } - - @Override - public AcceptCriterion getAcceptCriterion() { - return getDeleteLayoutAcceptCriteria(); - } - - @Override - public void drop(final DragAndDropEvent event) { - processDroppedComponent(event); - } - - /** - * Update the pending actions count. - * - * @param newCount - * new count value. - */ - protected void updateActionsCount(final int newCount) { - if (noActionBtn != null) { - if (newCount > 0) { - noActionBtn.setCaption(getActionsButtonLabel() + "
" + newCount + "
"); - } else { - noActionBtn.setCaption(getNoActionsButtonLabel()); - } - } - } - - protected void hideBulkUploadStatusButton() { - if (null != bulkUploadStatusButton) { - bulkUploadStatusButton.setCaption(null); - bulkUploadStatusButton.setVisible(false); - } - } - - /** - * - * @return true if the count label is displayed; false is not displayed - */ - protected boolean hasCountMessage() { - return false; - } - - /** - * - * @return the count message label - */ - protected Label getCountMessageLabel() { - return null; - } - - /** - * @return true if bulk upload is allowed and has required create - * permissions. - */ - protected boolean hasBulkUploadPermission() { - // can be overriden - return false; - } - - protected void showBulkUploadWindow() { - // can be overriden - } - - /** - * restore the upload status count. - */ - protected void restoreBulkUploadStatusCount() { - // can be overriden - } - - /** - * Check if user has delete permission. - * - * @return true if user has permission, otherwise return false. - */ - protected abstract boolean hasDeletePermission(); - - /** - * Check if user has update permission. - * - * @return true if user has permission, otherwise return false. - */ - protected abstract boolean hasUpdatePermission(); - - /** - * Get label for delete drop area. - * - * @return label of delete drop area. - */ - protected abstract String getDeleteAreaLabel(); - - /** - * Get Id of the delete drop area. - * - * @return Id of the delete drop area. - */ - protected abstract String getDeleteAreaId(); - - /** - * Get the accept criteria for the delete layout drop. - * - * @return reference of {@link AcceptCriteria} - */ - protected abstract AcceptCriterion getDeleteLayoutAcceptCriteria(); - - /** - * Process the dropped component. - * - * @param event - * reference of {@link DragAndDropEvent} - */ - protected abstract void processDroppedComponent(DragAndDropEvent event); - - /** - * Get the no actions button label. - * - * @return the no actions label. - */ - protected String getNoActionsButtonLabel() { - return i18n.getMessage("button.no.actions"); - } - - /** - * Get the pending actions button label. - * - * @return the actions label. - */ - protected String getActionsButtonLabel() { - return i18n.getMessage("button.actions"); - } - - /** - * Get caption of unsaved actions window. - * - * @return caption of the window. - */ - protected String getUnsavedActionsWindowCaption() { - return i18n.getMessage("caption.save.window"); - } - - /** - * reload the count value. - */ - protected abstract void restoreActionCount(); - - /** - * This method will be called when unsaved actions window is closed. - */ - protected abstract void unsavedActionsWindowClosed(); - - /** - * Get the content to be displayed in unsaved actions window. - * - * @return reference of the component. - */ - protected abstract Component getUnsavedActionsWindowContent(); - - /** - * Check if any unsaved actions done by the user. - * - * @return 'true' if any unsaved actions available, otherwise return - * 'false'. - */ - protected abstract boolean hasUnsavedActions(); - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridComponentLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridComponentLayout.java index 796e6998d..2d7014a52 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridComponentLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridComponentLayout.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.common.grid; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -193,7 +192,6 @@ public abstract class AbstractGridComponentLayout extends VerticalLayout { private Layout createFooterMessageComponent() { final HorizontalLayout footerLayout = new HorizontalLayout(); footerLayout.addComponent(getFooterMessageLabel()); - footerLayout.setStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); footerLayout.setWidth(100, Unit.PERCENTAGE); return footerLayout; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java index ed4d1a3e2..2315b9f82 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/AbstractGridHeader.java @@ -12,7 +12,7 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -116,7 +116,7 @@ public abstract class AbstractGridHeader extends VerticalLayout { private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(getSearchRestIconId(), "", "", null, - false, FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class); + false, FontAwesome.SEARCH, SPUIButtonStyleNoBorder.class); button.addClickListener(event -> onSearchResetClick()); button.setData(Boolean.FALSE); return button; @@ -124,14 +124,14 @@ public abstract class AbstractGridHeader extends VerticalLayout { private Button createAddButton() { final Button button = SPUIComponentProvider.getButton(getAddIconId(), "", "", null, false, FontAwesome.PLUS, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); button.addClickListener(this::addNewItem); return button; } private Button createCloseButton() { final Button button = SPUIComponentProvider.getButton(getCloseButtonId(), "", "", null, false, - FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TIMES, SPUIButtonStyleNoBorder.class); button.addClickListener(this::onClose); return button; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/DefaultGridHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/DefaultGridHeader.java index b8d155c2f..cfa0e7867 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/DefaultGridHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/grid/DefaultGridHeader.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.ui.common.grid; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -218,7 +218,7 @@ public class DefaultGridHeader extends VerticalLayout { */ protected SPUIButton createMinMaxButton(final String buttonId) { return (SPUIButton) SPUIComponentProvider.getButton(buttonId, "", "Maximize", null, true, - FontAwesome.EXPAND, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.EXPAND, SPUIButtonStyleNoBorder.class); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java index e567a9001..314fe889d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.List; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -30,20 +31,18 @@ import com.vaadin.ui.DragAndDropWrapper; */ public abstract class AbstractNamedVersionTable extends AbstractTable { - private static final long serialVersionUID = 780050712209750719L; + private static final long serialVersionUID = 1L; protected AbstractNamedVersionTable(final UIEventBus eventBus, final VaadinMessageSource i18n, - final UINotification notification) { - super(eventBus, i18n, notification); - setMultiSelect(true); - setSelectable(true); + final UINotification notification, final SpPermissionChecker permChecker) { + super(eventBus, i18n, notification, permChecker); } @Override protected List getTableVisibleColumns() { final List columnList = super.getTableVisibleColumns(); final float versionColumnSize = isMaximized() ? 0.1F : 0.2F; - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VERSION, i18n.getMessage("header.version"), + columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VERSION, getI18n().getMessage("header.version"), versionColumnSize)); return columnList; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractSoftwareModuleTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractSoftwareModuleTableHeader.java index a9633c7e7..78f982818 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractSoftwareModuleTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractSoftwareModuleTableHeader.java @@ -79,7 +79,7 @@ public abstract class AbstractSoftwareModuleTableHeader extends AbstractTableHea @Override protected void addNewItem(final ClickEvent event) { final Window addSoftwareModule = softwareModuleAddUpdateWindow.createAddSoftwareModuleWindow(); - addSoftwareModule.setCaption(i18n.getMessage("upload.caption.add.new.swmodule")); + addSoftwareModule.setCaption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.software.module"))); UI.getCurrent().addWindow(addSoftwareModule); addSoftwareModule.setVisible(Boolean.TRUE); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java index 0e2275c3a..d99f604a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java @@ -18,10 +18,14 @@ import java.util.Set; import java.util.stream.Collectors; import org.eclipse.hawkbit.repository.model.NamedEntity; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.ManagementEntityState; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; import org.eclipse.hawkbit.ui.components.RefreshableContainer; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -40,6 +44,9 @@ import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.server.FontAwesome; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.Table; @@ -56,21 +63,36 @@ public abstract class AbstractTable extends Table impleme private static final long serialVersionUID = 1L; + protected static final String MESSAGE_CONFIRM_DELETE_ENTITY = "message.confirm.delete.entity"; + + protected static final String DISTRIBUTIONSET_NOT_EXISTS = "distributionset.not.exists"; + + protected static final String TARGETS_NOT_EXISTS = "targets.not.exists"; + + protected static final String CAPTION_ENTITY_ASSIGN_ACTION_CONFIRMBOX = "caption.entity.assign.action.confirmbox"; + + protected static final String MESSAGE_CONFIRM_ASSIGN_ENTITY = "message.confirm.assign.entity"; + + protected static final String MESSAGE_CONFIRM_ASSIGN_MULTIPLE_ENTITIES = "message.confirm.assign.multiple.entities"; + private static final float DEFAULT_COLUMN_NAME_MIN_SIZE = 0.8F; protected static final String ACTION_NOT_ALLOWED_MSG = "message.action.not.allowed"; - protected transient EventBus.UIEventBus eventBus; + private final transient EventBus.UIEventBus eventBus; - protected VaadinMessageSource i18n; + private final VaadinMessageSource i18n; - protected UINotification notification; + private final UINotification notification; + + private final SpPermissionChecker permChecker; protected AbstractTable(final UIEventBus eventBus, final VaadinMessageSource i18n, - final UINotification notification) { + final UINotification notification, final SpPermissionChecker permChecker) { this.eventBus = eventBus; this.i18n = i18n; this.notification = notification; + this.permChecker = permChecker; setStyleName("sp-table"); setSizeFull(); setImmediate(true); @@ -80,6 +102,7 @@ public abstract class AbstractTable extends Table impleme setSortEnabled(false); setId(getTableId()); addCustomGeneratedColumns(); + addDeleteColumn(); setDefault(); addValueChangeListener(event -> onValueChange()); setPageLength(SPUIDefinitions.PAGE_SIZE); @@ -97,6 +120,17 @@ public abstract class AbstractTable extends Table impleme return true; } + // can be overriden + protected boolean hasDeletePermission() { + return permChecker.hasDeleteRepositoryPermission(); + } + + private void addDeleteColumn() { + if (hasDeletePermission()) { + addGeneratedColumn(SPUIDefinitions.DELETE_ENTITY, (source, itemId, columnId) -> createDeleteButton(itemId)); + } + } + /** * Gets the selected item id or in multiselect mode a set of selected ids. * @@ -156,11 +190,11 @@ public abstract class AbstractTable extends Table impleme protected void selectRow() { if (!isMaximized()) { - if (isFirstRowSelectedOnLoad()) { - selectFirstRow(); - } else { - setValue(getItemIdToSelect()); + final Object itemIdToSelect = getItemIdToSelect(); + if (itemIdToSelect == null) { + return; } + setValue(itemIdToSelect); } } @@ -176,6 +210,7 @@ public abstract class AbstractTable extends Table impleme protected void setColumnProperties() { final List columnList = getTableVisibleColumns(); + addDeleteButtonToColumnList(columnList); final List swColumnIds = new ArrayList<>(); for (final TableColumn column : columnList) { setColumnHeader(column.getColumnPropertyId(), column.getColumnHeader()); @@ -185,11 +220,9 @@ public abstract class AbstractTable extends Table impleme setVisibleColumns(swColumnIds.toArray()); } - private void selectFirstRow() { - final Container container = getContainerDataSource(); - final int size = container.size(); - if (size > 0) { - select(firstItemId()); + private void addDeleteButtonToColumnList(final List columnList) { + if (hasDeletePermission()) { + columnList.add(new TableColumn(SPUIDefinitions.DELETE_ENTITY, "", 0.0F)); } } @@ -248,18 +281,18 @@ public abstract class AbstractTable extends Table impleme * the table transferable * @return set of entities id which will deleted */ - public Set getDeletedEntityByTransferable(final TableTransferable transferable) { + public Set getSelectedEntitiesByTransferable(final TableTransferable transferable) { final Set selectedEntities = getTableValue(this); final Set ids = new HashSet<>(); - final Long tranferableData = (Long) transferable.getData(SPUIDefinitions.ITEMID); - if (tranferableData == null) { + final Long transferableData = (Long) transferable.getData(SPUIDefinitions.ITEMID); + if (transferableData == null) { return ids; } - if (!selectedEntities.contains(tranferableData)) { - ids.add(tranferableData); - } else { + if (entityToBeDeletedIsSelectedInTable(transferableData, selectedEntities)) { ids.addAll(selectedEntities); + } else { + ids.add(transferableData); } return ids; } @@ -291,6 +324,9 @@ public abstract class AbstractTable extends Table impleme protected abstract void publishSelectedEntityEvent(final E selectedLastEntity); protected void setLastSelectedEntityId(final Long selectedLastEntityId) { + if (selectedLastEntityId == null) { + return; + } getManagementEntityState().setLastSelectedEntityId(selectedLastEntityId); } @@ -323,14 +359,97 @@ public abstract class AbstractTable extends Table impleme // can be overriden } - /** - * Check if the first row should be selected by default on load. (if there - * is no other item selected) - * - * @return true if it should be selected otherwise return false, if there is - * a different item already selected. - */ - protected abstract boolean isFirstRowSelectedOnLoad(); + private Object createDeleteButton(final Object itemId) { + final Button deleteButton = SPUIComponentProvider.getButton("", "", "", "", true, FontAwesome.TRASH_O, + SPUIButtonStyleNoBorderWithIcon.class); + final String id = getEntityId(itemId); + deleteButton.setId("delete.entity." + id); + deleteButton.setDescription(SPUIDefinitions.DELETE); + deleteButton.addClickListener(this::addDeleteButtonClickListener); + return deleteButton; + } + + private void addDeleteButtonClickListener(final ClickEvent event) { + openConfirmationWindowDeleteAction(event); + } + + private void openConfirmationWindowDeleteAction(final ClickEvent event) { + final List entitiesToBeDeleted = getEntitiesForDeletion(event); + final String confirmationQuestion = createConfirmationQuestionForDeletion(entitiesToBeDeleted); + final ConfirmationDialog confirmDialog = createConfirmationWindowForDeletion(entitiesToBeDeleted, + confirmationQuestion); + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + private List getEntitiesForDeletion(final ClickEvent event) { + List entitiesToBeDeleted; + final Long id = getDeleteButtonId(event); + final Set selectedEntities = getSelectedEntities(); + if (entityToBeDeletedIsSelectedInTable(id, selectedEntities)) { + entitiesToBeDeleted = selectedEntities.stream().collect(Collectors.toList()); + } else { + final Table table = getTable(event); + unselectSelectedEntitiesInTable(selectedEntities, table); + selectEntityToDeleteInTable(id, table); + entitiesToBeDeleted = new ArrayList<>(); + entitiesToBeDeleted.add(id); + } + return entitiesToBeDeleted; + } + + private ConfirmationDialog createConfirmationWindowForDeletion(final List entitiesToBeDeleted, + final String confirmationQuestion) { + return new ConfirmationDialog(i18n.getMessage("caption.entity.delete.action.confirmbox", getEntityType()), + confirmationQuestion, i18n.getMessage(SPUIDefinitions.BUTTON_OK), + i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { + if (ok) { + handleOkDelete(entitiesToBeDeleted); + } + }); + } + + private String createConfirmationQuestionForDeletion(final List entitiesToBeDeleted) { + if (entitiesToBeDeleted.size() == 1) { + return i18n.getMessage(MESSAGE_CONFIRM_DELETE_ENTITY, getEntityType().toLowerCase(), + getDeletedEntityName(entitiesToBeDeleted.get(0)), ""); + } else { + return i18n.getMessage(MESSAGE_CONFIRM_DELETE_ENTITY, entitiesToBeDeleted.size(), + getEntityType().toLowerCase(), "s"); + } + } + + private static boolean entityToBeDeletedIsSelectedInTable(final Long id, final Set selectedEntities) { + return selectedEntities.contains(id); + } + + private static Table getTable(final ClickEvent event) { + final Button source = (Button) event.getSource(); + return (Table) source.getParent(); + } + + private static void selectEntityToDeleteInTable(final Long id, final Table table) { + table.select(id); + } + + private static void unselectSelectedEntitiesInTable(final Set selectedEntities, final Table table) { + selectedEntities.forEach(table::unselect); + } + + private static long getDeleteButtonId(final ClickEvent event) { + final String id = event.getButton().getId(); + return Long.parseLong(id.substring(id.lastIndexOf('.') + 1)); + } + + protected abstract String getDeletedEntityName(Long entityId); + + protected abstract void handleOkDelete(List allEntities); + + protected abstract String getEntityType(); + + protected abstract Set getSelectedEntities(); + + protected abstract String getEntityId(Object itemId); /** * Get Item Id which should be displayed as selected. @@ -368,7 +487,6 @@ public abstract class AbstractTable extends Table impleme i18n.getMessage("header.modifiedDate"), 0.1F)); columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.getMessage("header.description"), 0.2F)); setItemDescriptionGenerator((source, itemId, propertyId) -> { - if (SPUILabelDefinitions.VAR_CREATED_BY.equals(propertyId)) { return getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_CREATED_BY).getValue().toString(); } @@ -377,7 +495,6 @@ public abstract class AbstractTable extends Table impleme } return null; }); - return columnList; } @@ -416,17 +533,16 @@ public abstract class AbstractTable extends Table impleme final AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails) event.getTargetDetails(); final Long targetItemId = (Long) dropData.getItemIdOver(); - if (!targetSelected.contains(targetItemId)) { - return Sets.newHashSet(targetItemId); + if (entityToBeDeletedIsSelectedInTable(targetItemId, targetSelected)) { + return targetSelected; } - - return targetSelected; + return Sets.newHashSet(targetItemId); } private Set getDraggedTargetList(final TableTransferable transferable, final Table source) { @SuppressWarnings("unchecked") final AbstractTable table = (AbstractTable) source; - return table.getDeletedEntityByTransferable(transferable); + return table.getSelectedEntitiesByTransferable(transferable); } private boolean validateDropList(final Set droplist) { @@ -499,6 +615,27 @@ public abstract class AbstractTable extends Table impleme publishSelectedEntityEvent(entity); } + protected void selectDroppedEntities(final Long targetId) { + getSelectedEntities().forEach(this::unselect); + select(targetId); + } + + protected void selectDraggedEntities(final AbstractTable source, final Set ids) { + source.setValue(ids); + } + + protected EventBus.UIEventBus getEventBus() { + return eventBus; + } + + protected VaadinMessageSource getI18n() { + return i18n; + } + + protected SpPermissionChecker getPermChecker() { + return permChecker; + } + protected abstract List hasMissingPermissionsForDrop(); protected abstract boolean validateDragAndDropWrapper(final DragAndDropWrapper wrapperSource); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java index 9cd3928dd..c36482ad4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java @@ -14,7 +14,7 @@ import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -221,7 +221,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(getSearchRestIconId(), "", "", null, - false, FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class); + false, FontAwesome.SEARCH, SPUIButtonStyleNoBorder.class); button.addClickListener(event -> onSearchResetClick()); button.setData(Boolean.FALSE); return button; @@ -229,21 +229,21 @@ public abstract class AbstractTableHeader extends VerticalLayout { private Button createAddIcon() { final Button button = SPUIComponentProvider.getButton(getAddIconId(), "", "", null, false, FontAwesome.PLUS, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); button.addClickListener(this::addNewItem); return button; } private Button createBulkUploadIcon() { final Button button = SPUIComponentProvider.getButton(getBulkUploadIconId(), "", "", null, false, - FontAwesome.UPLOAD, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.UPLOAD, SPUIButtonStyleNoBorder.class); button.addClickListener(this::bulkUpload); return button; } private Button createShowFilterButtonLayout() { final Button button = SPUIComponentProvider.getButton(getShowFilterButtonLayoutId(), null, null, null, false, - FontAwesome.TAGS, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TAGS, SPUIButtonStyleNoBorder.class); button.setVisible(false); button.addClickListener(event -> showFilterButtonsIconClicked()); return button; @@ -251,7 +251,7 @@ public abstract class AbstractTableHeader extends VerticalLayout { private SPUIButton createMaxMinIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton(getMaxMinIconId(), "", "", null, false, - FontAwesome.EXPAND, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.EXPAND, SPUIButtonStyleNoBorder.class); button.addClickListener(event -> maxMinButtonClicked()); return button; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/ConfigMenuBar.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/ConfigMenuBar.java new file mode 100644 index 000000000..1d3a93333 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/ConfigMenuBar.java @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.components; + +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; + +import com.vaadin.server.FontAwesome; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.themes.ValoTheme; + +/** + * Menubar for configuring tags and types (create, update, delete). The menubar + * is placed in the header of the filter by tags or types tables. + * + */ +public class ConfigMenuBar extends MenuBar { + + private static final long serialVersionUID = 1L; + + private MenuItem config; + + private final boolean createPermission; + + private final boolean updatePermission; + + private final boolean deletePermission; + + private final Command addButtonCommand; + + private final Command updateButtonCommand; + + private final Command deleteButtonCommand; + + private final String id; + + /** + * Constructor for the menubar + * + * @param createPermission + * flag if the logged-in user has permission to create the entity + * which should be configured with this menubar + * @param updatePermission + * flag if the logged-in user has permission to update the entity + * which should be configured with this menubar + * @param deletePermission + * flag if the logged-in user has permission to delete the entity + * which should be configured with this menubar + * @param addButtonCommand + * action which should be executed when clicking on the create + * command + * @param updateButtonCommand + * action which should be executed when clicking on the update + * command + * @param deleteButtonCommand + * action which should be executed when clicking on the delete + * command + * @param id + * the id of the menuBar + */ + public ConfigMenuBar(final boolean createPermission, final boolean updatePermission, final boolean deletePermission, + final Command addButtonCommand, final Command updateButtonCommand, final Command deleteButtonCommand, + final String id) { + this.createPermission = createPermission; + this.updatePermission = updatePermission; + this.deletePermission = deletePermission; + this.addButtonCommand = addButtonCommand; + this.updateButtonCommand = updateButtonCommand; + this.deleteButtonCommand = deleteButtonCommand; + this.id = id; + + init(); + } + + private void init() { + setId(id); + if (!createPermission && !updatePermission && !deletePermission) { + return; + } + setStyleName(ValoTheme.MENUBAR_BORDERLESS); + addStyleName(SPUIStyleDefinitions.CONFIG_MENU_BAR_POSITION); + config = addItem("", FontAwesome.COG, null); + config.setStyleName(SPUIStyleDefinitions.CONFIG_MENU_BAR_ITEMS); + + addMenuItems(); + } + + private void addMenuItems() { + if (createPermission) { + config.addItem(UIComponentIdProvider.CONFIG_MENU_BAR_CREATE, FontAwesome.PLUS, addButtonCommand); + } + if (updatePermission) { + config.addItem(UIComponentIdProvider.CONFIG_MENU_BAR_UPDATE, FontAwesome.EDIT, updateButtonCommand); + } + if (deletePermission) { + config.addItem(UIComponentIdProvider.CONFIG_MENU_BAR_DELETE, FontAwesome.TRASH_O, deleteButtonCommand); + } + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/NotificationUnreadButton.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/NotificationUnreadButton.java index b959077f4..236c26f3e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/NotificationUnreadButton.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/NotificationUnreadButton.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.eclipse.hawkbit.ui.push.EventContainer; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.beans.factory.annotation.Autowired; @@ -62,7 +61,6 @@ public class NotificationUnreadButton extends Button { this.unreadNotifications = new ConcurrentHashMap<>(); setIcon(FontAwesome.BELL); setId(UIComponentIdProvider.NOTIFICATION_UNREAD_ID); - addStyleName(SPUIStyleDefinitions.ACTION_BUTTON); addStyleName(ValoTheme.BUTTON_SMALL); addStyleName(STYLE); setHtmlContentAllowed(true); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 59f03cc8e..6890eec18 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -66,13 +66,13 @@ public final class SPUIComponentProvider { * signifies if combo is mandatory * @param data * combo box data - * @param promt + * @param prompt * input prompt * @return ComboBox */ public static ComboBox getComboBox(final String caption, final String width, final String style, - final String styleName, final boolean required, final String data, final String promt) { - return SPUIComboBoxDecorator.decorate(caption, width, style, styleName, required, data, promt); + final String styleName, final boolean required, final String data, final String prompt) { + return SPUIComboBoxDecorator.decorate(caption, width, style, styleName, required, data, prompt); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterion.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterion.java index cad4d2f11..3295ea7d4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterion.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/client/criteria/ViewClientCriterion.java @@ -16,6 +16,7 @@ import java.util.logging.Logger; import org.eclipse.hawkbit.ui.dd.criteria.ServerViewClientCriterion; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; @@ -95,8 +96,8 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce SafeHtml notificationMsg(String msg); } - private static VAcceptCriterion getCriteria(UIDL configuration, int i) { - UIDL childUIDL = configuration.getChildUIDL(i); + private static VAcceptCriterion getCriteria(final UIDL configuration, final int i) { + final UIDL childUIDL = configuration.getChildUIDL(i); return VAcceptCriteria.get(childUIDL.getStringAttribute("name")); } @@ -121,7 +122,7 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce if (isDragStarting(drag)) { final NativePreviewHandler nativeEventHandler = new NativePreviewHandler() { @Override - public void onPreviewNativeEvent(NativePreviewEvent event) { + public void onPreviewNativeEvent(final NativePreviewEvent event) { if (isEscKey(event) || isMouseUp(event)) { try { hideDropTargetHints(configuration); @@ -136,10 +137,10 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce setMultiRowDragDecoration(drag); } - int childCount = configuration.getChildCount(); + final int childCount = configuration.getChildCount(); accepted = false; for (int childIndex = 0; childIndex < childCount; childIndex++) { - VAcceptCriterion crit = getCriteria(configuration, childIndex); + final VAcceptCriterion crit = getCriteria(configuration, childIndex); crit.accept(drag, configuration.getChildUIDL(childIndex), this); if (Boolean.TRUE.equals(accepted)) { callback.accepted(drag); @@ -155,18 +156,18 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce } @Override - public boolean needsServerSideCheck(VDragEvent drag, UIDL criterioUIDL) { + public boolean needsServerSideCheck(final VDragEvent drag, final UIDL criterioUIDL) { return false; } @Override - protected boolean accept(VDragEvent drag, UIDL configuration) { + protected boolean accept(final VDragEvent drag, final UIDL configuration) { // not used here: return false; } @Override - public void accepted(VDragEvent event) { + public void accepted(final VDragEvent event) { accepted = true; } @@ -176,24 +177,25 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce * @param drag * the current drag event holding the context. */ - void setMultiRowDragDecoration(VDragEvent drag) { - Widget widget = drag.getTransferable().getDragSource().getWidget(); + void setMultiRowDragDecoration(final VDragEvent drag) { + final Widget widget = drag.getTransferable().getDragSource().getWidget(); if (widget instanceof VScrollTable) { - VScrollTable table = (VScrollTable) widget; - int rowCount = table.selectedRowKeys.size(); + final VScrollTable table = (VScrollTable) widget; + final int rowCount = table.selectedRowKeys.size(); Element dragCountElement = Document.get().getElementById(SP_DRAG_COUNT); if (rowCount > 1 && table.selectedRowKeys.contains(table.focusedRow.getKey())) { if (dragCountElement == null) { dragCountElement = Document.get().createStyleElement(); dragCountElement.setId(SP_DRAG_COUNT); - HeadElement head = HeadElement.as(Document.get().getElementsByTagName(HeadElement.TAG).getItem(0)); + final HeadElement head = HeadElement + .as(Document.get().getElementsByTagName(HeadElement.TAG).getItem(0)); head.appendChild(dragCountElement); } - SafeHtml formattedCssStyle = getDraggableTemplate().multiSelectionStyle(determineActiveTheme(drag), - String.valueOf(rowCount)); - StyleElement dragCountStyleElement = StyleElement.as(dragCountElement); + final SafeHtml formattedCssStyle = getDraggableTemplate() + .multiSelectionStyle(determineActiveTheme(drag), String.valueOf(rowCount)); + final StyleElement dragCountStyleElement = StyleElement.as(dragCountElement); dragCountStyleElement.setInnerSafeHtml(formattedCssStyle); } else if (dragCountElement != null) { dragCountElement.removeFromParent(); @@ -210,9 +212,9 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce * key, otherwise false. */ private static boolean isEscKey(final NativePreviewEvent event) { - int typeInt = event.getTypeInt(); + final int typeInt = event.getTypeInt(); if (typeInt == Event.ONKEYDOWN) { - int keyCode = event.getNativeEvent().getKeyCode(); + final int keyCode = event.getNativeEvent().getKeyCode(); if (KeyCodes.KEY_ESCAPE == keyCode) { return true; } @@ -242,16 +244,16 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce // Exception squid:S2221 - This code is trans-coded to JavaScript, hence // Exception semantics changes @SuppressWarnings({ "squid:S1166", "squid:S2221" }) - void hideDropTargetHints(UIDL configuration) { - int totalDropTargetHintsCount = configuration.getIntAttribute(DROP_AREA_CONFIG_COUNT); + void hideDropTargetHints(final UIDL configuration) { + final int totalDropTargetHintsCount = configuration.getIntAttribute(DROP_AREA_CONFIG_COUNT); for (int dropAreaIndex = 0; dropAreaIndex < totalDropTargetHintsCount; dropAreaIndex++) { try { - String dropArea = configuration.getStringAttribute(DROP_AREA_CONFIG + dropAreaIndex); - Element hideHintFor = Document.get().getElementById(dropArea); + final String dropArea = configuration.getStringAttribute(DROP_AREA_CONFIG + dropAreaIndex); + final Element hideHintFor = Document.get().getElementById(dropArea); if (hideHintFor != null) { hideHintFor.removeClassName(ViewComponentClientCriterion.HINT_AREA_STYLE); } - } catch (Exception e) { + } catch (final Exception e) { // log and continue LOGGER.log(Level.SEVERE, "Error highlighting valid drop targets: " + e.getLocalizedMessage()); } @@ -264,11 +266,11 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce * @param drag * the current drag event holding the context. */ - private void showErrorNotification(VDragEvent drag) { - VNotification n = VNotification.createNotification(SPUILabelDefinitions.SP_DELAY, + private void showErrorNotification(final VDragEvent drag) { + final VNotification n = VNotification.createNotification(SPUILabelDefinitions.SP_DELAY, drag.getTransferable().getDragSource().getWidget()); n.show(getDraggableTemplate().notificationMsg(SPUILabelDefinitions.ACTION_NOT_ALLOWED).asString(), - Position.BOTTOM_RIGHT, SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE); + Position.BOTTOM_RIGHT, SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE); } /** @@ -278,7 +280,7 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce * the event the UI theme is retrieved for. * @return the active theme (e.g. "hawkbit"). */ - private static String determineActiveTheme(VDragEvent drag) { + private static String determineActiveTheme(final VDragEvent drag) { return drag.getTransferable().getDragSource().getConnection().getUIConnector().getActiveTheme(); } @@ -292,7 +294,7 @@ public final class ViewClientCriterion extends VAcceptCriterion implements VAcce * @return true if the drag operation is starting, otherwise * false */ - private boolean isDragStarting(VDragEvent drag) { + private boolean isDragStarting(final VDragEvent drag) { boolean result = false; if (!drag.equals(previousDragEvent)) { result = true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/DistributionsViewClientCriterion.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/DistributionsViewClientCriterion.java index f90e3e770..da84131bf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/DistributionsViewClientCriterion.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/DistributionsViewClientCriterion.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.dd.criteria; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import com.vaadin.spring.annotation.SpringComponent; @@ -22,10 +21,7 @@ import com.vaadin.spring.annotation.UIScope; @UIScope public final class DistributionsViewClientCriterion extends ServerViewClientCriterion { - /** - * serialVersionUID. - */ - private static final long serialVersionUID = 8602945302654554257L; + private static final long serialVersionUID = 1L; private static final ServerViewComponentClientCriterion[] COMPONENT_CRITERIA = createViewComponentClientCriteria(); @@ -43,30 +39,13 @@ public final class DistributionsViewClientCriterion extends ServerViewClientCrit * @return accept criterion elements */ static ServerViewComponentClientCriterion[] createViewComponentClientCriteria() { - ServerViewComponentClientCriterion[] criteria = new ServerViewComponentClientCriterion[4]; + final ServerViewComponentClientCriterion[] criteria = new ServerViewComponentClientCriterion[1]; - // Distribution table acceptable components. - criteria[0] = ServerViewComponentClientCriterion.createBuilder() - .dragSourceIdPrefix(UIComponentIdProvider.DIST_TABLE_ID) - .dropTargetIdPrefixes(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID).build(); - // Distribution set type acceptable components. - criteria[1] = ServerViewComponentClientCriterion.createBuilder() - .dragSourceIdPrefix(SPUIDefinitions.DISTRIBUTION_SET_TYPE_ID_PREFIXS) - .dropTargetIdPrefixes(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID).build(); // Upload software module table acceptable components. - criteria[2] = ServerViewComponentClientCriterion.createBuilder() + criteria[0] = ServerViewComponentClientCriterion.createBuilder() .dragSourceIdPrefix(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE) - .dropTargetIdPrefixes(UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DIST_TABLE_ID, UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .build(); - // Software module tag acceptable components. - criteria[3] = ServerViewComponentClientCriterion.createBuilder() - .dragSourceIdPrefix(SPUIDefinitions.SOFTWARE_MODULE_TAG_ID_PREFIXS) - .dropTargetIdPrefixes(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID).build(); + .dropTargetIdPrefixes(UIComponentIdProvider.DIST_TABLE_ID) + .dropAreaIds(UIComponentIdProvider.DIST_TABLE_ID).build(); return criteria; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ManagementViewClientCriterion.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ManagementViewClientCriterion.java index 85e20c49d..d9e296b82 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ManagementViewClientCriterion.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/ManagementViewClientCriterion.java @@ -43,40 +43,32 @@ public final class ManagementViewClientCriterion extends ServerViewClientCriteri * @return accept criterion elements */ static ServerViewComponentClientCriterion[] createViewComponentClientCriteria() { - ServerViewComponentClientCriterion[] criteria = new ServerViewComponentClientCriterion[4]; + final ServerViewComponentClientCriterion[] criteria = new ServerViewComponentClientCriterion[4]; // Target table acceptable components. criteria[0] = ServerViewComponentClientCriterion.createBuilder() .dragSourceIdPrefix(UIComponentIdProvider.TARGET_TABLE_ID) - .dropTargetIdPrefixes(SPUIDefinitions.TARGET_TAG_ID_PREFIXS, UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.TARGET_TAG_DROP_AREA_ID, UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) + .dropTargetIdPrefixes(SPUIDefinitions.TARGET_TAG_ID_PREFIXS, UIComponentIdProvider.DIST_TABLE_ID) + .dropAreaIds(UIComponentIdProvider.TARGET_TAG_DROP_AREA_ID, UIComponentIdProvider.DIST_TABLE_ID) .build(); // Target Tag acceptable components. criteria[1] = ServerViewComponentClientCriterion.createBuilder() .dragSourceIdPrefix(SPUIDefinitions.TARGET_TAG_ID_PREFIXS) - .dropTargetIdPrefixes(UIComponentIdProvider.TARGET_TABLE_ID, UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.TARGET_TABLE_ID, UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .build(); + .dropTargetIdPrefixes(UIComponentIdProvider.TARGET_TABLE_ID, UIComponentIdProvider.DIST_TABLE_ID) + .dropAreaIds(UIComponentIdProvider.TARGET_TABLE_ID, UIComponentIdProvider.DIST_TABLE_ID).build(); // Distribution table acceptable components. criteria[2] = ServerViewComponentClientCriterion.createBuilder() .dragSourceIdPrefix(UIComponentIdProvider.DIST_TABLE_ID) .dropTargetIdPrefixes(UIComponentIdProvider.TARGET_TABLE_ID, - UIComponentIdProvider.TARGET_DROP_FILTER_ICON, SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) + UIComponentIdProvider.TARGET_DROP_FILTER_ICON, SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS) .dropAreaIds(UIComponentIdProvider.TARGET_TABLE_ID, UIComponentIdProvider.TARGET_DROP_FILTER_ICON, - UIComponentIdProvider.DISTRIBUTION_TAG_TABLE_ID, UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) + UIComponentIdProvider.DISTRIBUTION_TAG_TABLE_ID) .build(); // Distribution tag acceptable components. criteria[3] = ServerViewComponentClientCriterion.createBuilder() .dragSourceIdPrefix(SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS) - .dropTargetIdPrefixes(UIComponentIdProvider.DIST_TABLE_ID, - UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DIST_TABLE_ID, UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .build(); + .dropTargetIdPrefixes(UIComponentIdProvider.DIST_TABLE_ID) + .dropAreaIds(UIComponentIdProvider.DIST_TABLE_ID).build(); return criteria; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/UploadViewClientCriterion.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/UploadViewClientCriterion.java index b8580cfb1..c239b2127 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/UploadViewClientCriterion.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/dd/criteria/UploadViewClientCriterion.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.ui.dd.criteria; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.UIScope; @@ -42,19 +40,6 @@ public final class UploadViewClientCriterion extends ServerViewClientCriterion { * @return accept criterion elements */ static ServerViewComponentClientCriterion[] createViewComponentClientCriteria() { - ServerViewComponentClientCriterion[] criteria = new ServerViewComponentClientCriterion[2]; - - // Upload type acceptable components. - criteria[0] = ServerViewComponentClientCriterion.createBuilder() - .dragSourceIdPrefix(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX) - .dropTargetIdPrefixes(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID).build(); - // Upload software module table acceptable components. - criteria[1] = ServerViewComponentClientCriterion.createBuilder() - .dragSourceIdPrefix(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE) - .dropTargetIdPrefixes(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID) - .dropAreaIds(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID).build(); - - return criteria; + return new ServerViewComponentClientCriterion[0]; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmallNoBorder.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleNoBorder.java similarity index 86% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmallNoBorder.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleNoBorder.java index 83fd25ac7..d5e1ffa2b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmallNoBorder.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleNoBorder.java @@ -15,7 +15,7 @@ import com.vaadin.ui.themes.ValoTheme; /** * Style for button: Small NoBorder. */ -public class SPUIButtonStyleSmallNoBorder implements SPUIButtonDecorator { +public class SPUIButtonStyleNoBorder implements SPUIButtonDecorator { /** * Decorate Button and return. @@ -32,13 +32,11 @@ public class SPUIButtonStyleSmallNoBorder implements SPUIButtonDecorator { */ @Override public Button decorate(final Button button, final String style, final boolean setStyle, final Resource icon) { - // Set Style - if (null != style && setStyle) { + if (style != null && setStyle) { button.addStyleName(style); } button.addStyleName(ValoTheme.BUTTON_BORDERLESS); - // Set icon - if (null != icon) { + if (icon != null) { button.addStyleName(ValoTheme.BUTTON_ICON_ONLY); button.addStyleName("button-no-border"); button.setIcon(icon); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmall.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmall.java index 6166dbf5a..6c95f1a2a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmall.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonStyleSmall.java @@ -21,16 +21,14 @@ public class SPUIButtonStyleSmall implements SPUIButtonDecorator { @Override public Button decorate(final Button button, final String style, final boolean setStyle, final Resource icon) { button.addStyleName(ValoTheme.BUTTON_SMALL); - // Set Style - if (null != style) { + if (style != null) { if (setStyle) { button.setStyleName(style); } else { button.addStyleName(style); } } - // Set icon - if (null != icon) { + if (icon != null) { button.addStyleName(ValoTheme.BUTTON_ICON_ONLY); button.setIcon(icon); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java index 225e16100..442156031 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java @@ -30,11 +30,12 @@ import org.eclipse.hawkbit.ui.components.AbstractNotificationView; import org.eclipse.hawkbit.ui.components.NotificationUnreadButton; import org.eclipse.hawkbit.ui.components.RefreshableContainer; import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; -import org.eclipse.hawkbit.ui.distributions.disttype.DSTypeFilterLayout; +import org.eclipse.hawkbit.ui.distributions.disttype.filter.DSTypeFilterButtons; +import org.eclipse.hawkbit.ui.distributions.disttype.filter.DSTypeFilterLayout; import org.eclipse.hawkbit.ui.distributions.dstable.DistributionSetTableLayout; -import org.eclipse.hawkbit.ui.distributions.footer.DSDeleteActionsLayout; import org.eclipse.hawkbit.ui.distributions.smtable.SwModuleTableLayout; -import org.eclipse.hawkbit.ui.distributions.smtype.DistSMTypeFilterLayout; +import org.eclipse.hawkbit.ui.distributions.smtype.filter.DistSMTypeFilterButtons; +import org.eclipse.hawkbit.ui.distributions.smtype.filter.DistSMTypeFilterLayout; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; @@ -57,7 +58,6 @@ import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.spring.annotation.SpringView; import com.vaadin.spring.annotation.UIScope; -import com.vaadin.ui.Alignment; import com.vaadin.ui.GridLayout; /** @@ -85,8 +85,6 @@ public class DistributionsView extends AbstractNotificationView implements Brows private final DistSMTypeFilterLayout filterBySMTypeLayout; - private final DSDeleteActionsLayout deleteActionsLayout; - private final ManageDistUIState manageDistUIState; private final DistributionsViewMenuItem distributionsViewMenuItem; @@ -109,9 +107,13 @@ public class DistributionsView extends AbstractNotificationView implements Brows this.permChecker = permChecker; this.i18n = i18n; this.uiNotification = uiNotification; + this.manageDistUIState = manageDistUIState; + final DSTypeFilterButtons dsTypeFilterButtons = new DSTypeFilterButtons(eventBus, manageDistUIState, + distributionsViewClientCriterion, distributionSetTypeManagement, i18n, entityFactory, permChecker, + uiNotification, softwareModuleTypeManagement, distributionSetManagement, systemManagement); this.filterByDSTypeLayout = new DSTypeFilterLayout(manageDistUIState, i18n, permChecker, eventBus, entityFactory, uiNotification, softwareModuleTypeManagement, distributionSetTypeManagement, - distributionSetManagement, distributionsViewClientCriterion); + dsTypeFilterButtons); this.distributionTableLayout = new DistributionSetTableLayout(i18n, eventBus, permChecker, manageDistUIState, softwareModuleManagement, distributionSetManagement, distributionSetTypeManagement, targetManagement, entityFactory, uiNotification, distributionSetTagManagement, distributionsViewClientCriterion, @@ -119,12 +121,12 @@ public class DistributionsView extends AbstractNotificationView implements Brows this.softwareModuleTableLayout = new SwModuleTableLayout(i18n, uiNotification, eventBus, softwareModuleManagement, softwareModuleTypeManagement, entityFactory, manageDistUIState, permChecker, distributionsViewClientCriterion, artifactUploadState, artifactManagement); + + final DistSMTypeFilterButtons distSmTypeFilterButtons = new DistSMTypeFilterButtons(eventBus, manageDistUIState, + distributionsViewClientCriterion, softwareModuleTypeManagement, i18n, entityFactory, permChecker, + uiNotification); this.filterBySMTypeLayout = new DistSMTypeFilterLayout(eventBus, i18n, permChecker, manageDistUIState, - entityFactory, uiNotification, softwareModuleTypeManagement, distributionsViewClientCriterion); - this.deleteActionsLayout = new DSDeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, - systemManagement, manageDistUIState, distributionsViewClientCriterion, distributionSetManagement, - distributionSetTypeManagement, softwareModuleManagement, softwareModuleTypeManagement); - this.manageDistUIState = manageDistUIState; + entityFactory, uiNotification, softwareModuleTypeManagement, distSmTypeFilterButtons); this.distributionsViewMenuItem = distributionsViewMenuItem; } @@ -177,18 +179,18 @@ public class DistributionsView extends AbstractNotificationView implements Brows } private void createMainLayout() { - mainLayout = new GridLayout(4, 2); + mainLayout = new GridLayout(4, 1); mainLayout.setSizeFull(); mainLayout.setSpacing(true); + mainLayout.setStyleName("fullSize"); + mainLayout.addComponent(filterByDSTypeLayout, 0, 0); mainLayout.addComponent(distributionTableLayout, 1, 0); mainLayout.addComponent(softwareModuleTableLayout, 2, 0); mainLayout.addComponent(filterBySMTypeLayout, 3, 0); - mainLayout.addComponent(deleteActionsLayout, 1, 1, 2, 1); mainLayout.setRowExpandRatio(0, 1.0F); mainLayout.setColumnExpandRatio(1, 0.5F); mainLayout.setColumnExpandRatio(2, 0.5F); - mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); } @EventBusListenerMethod(scope = EventScope.UI) @@ -212,7 +214,6 @@ public class DistributionsView extends AbstractNotificationView implements Brows private void maximizeSwTable() { mainLayout.removeComponent(filterByDSTypeLayout); mainLayout.removeComponent(distributionTableLayout); - mainLayout.removeComponent(deleteActionsLayout); mainLayout.setColumnExpandRatio(2, 1F); mainLayout.setColumnExpandRatio(0, 0F); mainLayout.setColumnExpandRatio(1, 0F); @@ -221,26 +222,20 @@ public class DistributionsView extends AbstractNotificationView implements Brows private void minimizeSwTable() { mainLayout.addComponent(filterByDSTypeLayout, 0, 0); mainLayout.addComponent(distributionTableLayout, 1, 0); - mainLayout.addComponent(deleteActionsLayout, 1, 1, 2, 1); mainLayout.setColumnExpandRatio(1, 0.5F); mainLayout.setColumnExpandRatio(2, 0.5F); - mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); } private void minimizeDistTable() { mainLayout.addComponent(softwareModuleTableLayout, 2, 0); mainLayout.addComponent(filterBySMTypeLayout, 3, 0); - mainLayout.addComponent(deleteActionsLayout, 1, 1, 2, 1); mainLayout.setColumnExpandRatio(1, 0.5F); mainLayout.setColumnExpandRatio(2, 0.5F); - mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); } private void maximizeDistTable() { mainLayout.removeComponent(softwareModuleTableLayout); mainLayout.removeComponent(filterBySMTypeLayout); - mainLayout.removeComponent(deleteActionsLayout); - mainLayout.setColumnExpandRatio(1, 1F); mainLayout.setColumnExpandRatio(2, 0F); mainLayout.setColumnExpandRatio(3, 0F); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/AbstractDistributionSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/AbstractDistributionSetTypeLayout.java new file mode 100644 index 000000000..5f57220ac --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/AbstractDistributionSetTypeLayout.java @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype; + +import java.util.Optional; + +import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.layouts.AbstractTypeLayout; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * General Layout for Distribution Type pop-up window which is provided on + * Distribution View when creating, updating, or deleting a Distribution Set + * Type + */ +public abstract class AbstractDistributionSetTypeLayout extends AbstractTypeLayout { + + private static final long serialVersionUID = 1L; + + private final transient DistributionSetTypeManagement distributionSetTypeManagement; + + private DistributionSetTypeSoftwareModuleSelectLayout twinTables; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + */ + public AbstractDistributionSetTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final DistributionSetTypeManagement distributionSetTypeManagement, + final SoftwareModuleTypeManagement softwareModuleTypeManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification); + this.distributionSetTypeManagement = distributionSetTypeManagement; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + createTwinTables(); + } + + private void createTwinTables() { + twinTables = new DistributionSetTypeSoftwareModuleSelectLayout(getI18n(), softwareModuleTypeManagement); + getMainLayout().addComponent(twinTables, 2, 0); + updateRequiredFields(); + } + + private void updateRequiredFields() { + getWindow().updateAllComponents(getMainLayout()); + getWindow().addComponentListeners(); + } + + @Override + protected int getTagNameSize() { + return DistributionSetType.NAME_MAX_SIZE; + } + + @Override + protected int getTagDescSize() { + return DistributionSetType.DESCRIPTION_MAX_SIZE; + } + + @Override + protected int getTypeKeySize() { + return DistributionSetType.KEY_MAX_SIZE; + } + + @Override + protected String getTagNameId() { + return UIComponentIdProvider.NEW_DISTRIBUTION_TYPE_NAME; + } + + @Override + protected String getTagDescId() { + return UIComponentIdProvider.NEW_DISTRIBUTION_TYPE_DESC; + } + + @Override + protected String getTypeKeyId() { + return UIComponentIdProvider.NEW_DISTRIBUTION_TYPE_KEY; + } + + @Override + protected void resetFields() { + super.resetFields(); + twinTables.reset(); + } + + @Override + protected Optional findEntityByKey() { + return distributionSetTypeManagement.getByKey(getTypeKey().getValue()); + } + + @Override + protected String getDuplicateKeyErrorMessage(final DistributionSetType existingType) { + return getI18n().getMessage("message.type.key.duplicate.check", existingType.getKey()); + } + + @Override + protected Optional findEntityByName() { + return distributionSetTypeManagement.getByName(getTagName().getValue()); + } + + public DistributionSetTypeSoftwareModuleSelectLayout getTwinTables() { + return twinTables; + } + + public DistributionSetTypeManagement getDistributionSetTypeManagement() { + return distributionSetTypeManagement; + } + + public SoftwareModuleTypeManagement getSoftwareModuleTypeManagement() { + return softwareModuleTypeManagement; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateDistributionSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateDistributionSetTypeLayout.java new file mode 100644 index 000000000..fb524ac4a --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateDistributionSetTypeLayout.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.util.CollectionUtils; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Layout for pop-up window for creating a new Distribution Set Type on + * Distribution View. Logic for storing the new entity. + */ +public class CreateDistributionSetTypeLayout extends AbstractDistributionSetTypeLayout { + + private static final long serialVersionUID = 1L; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + */ + public CreateDistributionSetTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final DistributionSetTypeManagement distributionSetTypeManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, distributionSetTypeManagement, + softwareModuleTypeManagement); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.create.new", getI18n().getMessage("caption.type")); + } + + @Override + protected void saveEntity() { + createNewDistributionSetType(); + } + + @SuppressWarnings("unchecked") + private void createNewDistributionSetType() { + + final String colorPicked = ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()); + final String typeNameValue = getTagName().getValue(); + final String typeKeyValue = getTypeKey().getValue(); + final String typeDescValue = getTagDesc().getValue(); + final List itemIds = (List) getTwinTables().getSelectedTable().getItemIds(); + + if (typeNameValue != null && typeKeyValue != null && !CollectionUtils.isEmpty(itemIds)) { + final List mandatory = itemIds.stream() + .filter(itemId -> DistributionSetTypeSoftwareModuleSelectLayout + .isMandatoryModuleType(getTwinTables().getSelectedTable().getItem(itemId))) + .collect(Collectors.toList()); + + final List optional = itemIds.stream() + .filter(itemId -> DistributionSetTypeSoftwareModuleSelectLayout + .isOptionalModuleType(getTwinTables().getSelectedTable().getItem(itemId))) + .collect(Collectors.toList()); + + final DistributionSetType newDistType = getDistributionSetTypeManagement() + .create(getEntityFactory().distributionSetType().create().key(typeKeyValue).name(typeNameValue) + .description(typeDescValue).colour(colorPicked).mandatory(mandatory).optional(optional)); + getUiNotification().displaySuccess(getI18n().getMessage("message.save.success", newDistType.getName())); + getEventBus().publish(this, + new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType)); + } else { + getUiNotification().displayValidationError(getI18n().getMessage("message.error.missing.typenameorkey")); + } + } + + @Override + protected boolean isUpdateAction() { + return false; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java deleted file mode 100644 index 7f602c9b0..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ /dev/null @@ -1,614 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.disttype; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; -import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; -import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; -import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.data.domain.PageRequest; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; -import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.data.Item; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.server.FontAwesome; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; -import com.vaadin.ui.Alignment; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.Component; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Table; -import com.vaadin.ui.TextField; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Window for create update Distribution Set Type. - */ -public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { - - private static final long serialVersionUID = 1L; - private static final String DIST_TYPE_NAME = "name"; - private static final String DIST_TYPE_DESCRIPTION = "description"; - private static final String DIST_TYPE_MANDATORY = "mandatory"; - private static final String STAR = " * "; - - private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; - - private final transient DistributionSetTypeManagement distributionSetTypeManagement; - - private final transient DistributionSetManagement distributionSetManagement; - - private HorizontalLayout distTypeSelectLayout; - private Table sourceTable; - private Table selectedTable; - - private IndexedContainer selectedTableContainer; - private IndexedContainer sourceTableContainer; - - private IndexedContainer originalSelectedTableContainer; - - /** - * Constructor for {@link CreateUpdateDistSetTypeLayout}. - * - * @param i18n - * I18N - * @param entityFactory - * EntityFactory - * @param eventBus - * UIEventBus - * @param permChecker - * SpPermissionChecker - * @param uiNotification - * UINotification - * @param softwareModuleTypeManagement - * management for {@link SoftwareModuleType}s - * @param distributionSetTypeManagement - * DistributionSetTypeManagement - * @param distributionSetManagement - * DistributionSetManagement - */ - public CreateUpdateDistSetTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, - final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final DistributionSetTypeManagement distributionSetTypeManagement, - final DistributionSetManagement distributionSetManagement) { - super(i18n, entityFactory, eventBus, permChecker, uiNotification); - this.softwareModuleTypeManagement = softwareModuleTypeManagement; - this.distributionSetTypeManagement = distributionSetTypeManagement; - this.distributionSetManagement = distributionSetManagement; - } - - @Override - protected void createRequiredComponents() { - - super.createRequiredComponents(); - - tagName = createTextField("textfield.name", SPUIDefinitions.DIST_SET_TYPE_NAME, - SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME, DistributionSetType.NAME_MAX_SIZE); - - typeKey = createTextField("textfield.key", SPUIDefinitions.DIST_SET_TYPE_KEY, - SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY, DistributionSetType.KEY_MAX_SIZE); - - tagDesc = new TextAreaBuilder(DistributionSetType.DESCRIPTION_MAX_SIZE) - .caption(i18n.getMessage("textfield.description")) - .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC) - .id(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC).buildTextComponent(); - } - - private TextField createTextField(final String in18Key, final String styleName, final String id, - final int maxSize) { - return new TextFieldBuilder(maxSize).caption(i18n.getMessage(in18Key)) - .styleName(ValoTheme.TEXTFIELD_TINY + " " + styleName).required(true, i18n).id(id).buildTextComponent(); - } - - @Override - protected void buildLayout() { - - super.buildLayout(); - ColorPickerHelper.setRgbSliderValues(colorPickerLayout); - getFormLayout().addComponent(typeKey, 4); - - distTypeSelectLayout = createTwinColumnLayout(); - - final VerticalLayout twinTableLayout = new VerticalLayout(); - twinTableLayout.setSizeFull(); - twinTableLayout.addComponent(distTypeSelectLayout); - - mainLayout.addComponent(twinTableLayout, 2, 0); - } - - @Override - protected Color getColorForColorPicker() { - final Optional existedDistType = distributionSetTypeManagement - .getByName(tagNameComboBox.getValue().toString()); - if (existedDistType.isPresent()) { - return existedDistType.get().getColour() != null - ? ColorPickerHelper.rgbToColorConverter(existedDistType.get().getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR); - } - return ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR); - } - - private HorizontalLayout createTwinColumnLayout() { - - final HorizontalLayout twinColumnLayout = new HorizontalLayout(); - twinColumnLayout.setSizeFull(); - twinColumnLayout.setWidth("400px"); - - buildSourceTable(); - buildSelectedTable(); - - final VerticalLayout selectButtonLayout = new VerticalLayout(); - final Button selectButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SELECT_DIST_TYPE, "", "", - "arrow-button", true, FontAwesome.FORWARD, SPUIButtonStyleSmallNoBorder.class); - selectButton.addClickListener(event -> addSMType()); - final Button unSelectButton = SPUIComponentProvider.getButton("unselect-dist-type", "", "", "arrow-button", - true, FontAwesome.BACKWARD, SPUIButtonStyleSmallNoBorder.class); - unSelectButton.addClickListener(event -> removeSMType()); - selectButtonLayout.addComponent(selectButton); - selectButtonLayout.addComponent(unSelectButton); - selectButtonLayout.setComponentAlignment(selectButton, Alignment.MIDDLE_CENTER); - selectButtonLayout.setComponentAlignment(unSelectButton, Alignment.MIDDLE_CENTER); - - twinColumnLayout.addComponent(sourceTable); - twinColumnLayout.addComponent(selectButtonLayout); - twinColumnLayout.addComponent(selectedTable); - twinColumnLayout.setComponentAlignment(sourceTable, Alignment.MIDDLE_LEFT); - twinColumnLayout.setComponentAlignment(selectButtonLayout, Alignment.MIDDLE_CENTER); - twinColumnLayout.setComponentAlignment(selectedTable, Alignment.MIDDLE_RIGHT); - twinColumnLayout.setExpandRatio(sourceTable, 0.45F); - twinColumnLayout.setExpandRatio(selectButtonLayout, 0.07F); - twinColumnLayout.setExpandRatio(selectedTable, 0.48F); - sourceTable.setVisibleColumns(DIST_TYPE_NAME); - return twinColumnLayout; - } - - private void buildSelectedTable() { - - selectedTable = new Table(); - selectedTable.setId(SPUIDefinitions.TWIN_TABLE_SELECTED_ID); - selectedTable.setSelectable(true); - selectedTable.setMultiSelect(true); - selectedTable.setSortEnabled(false); - selectedTable.addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); - selectedTable.addStyleName(ValoTheme.TABLE_NO_STRIPES); - selectedTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); - selectedTable.addStyleName(ValoTheme.TABLE_SMALL); - selectedTable.addStyleName("dist_type_twin-table"); - selectedTable.setSizeFull(); - createSelectedTableContainer(); - selectedTable.setContainerDataSource(selectedTableContainer); - addTooltTipToSelectedTable(); - selectedTable.setImmediate(true); - selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY); - selectedTable.setColumnHeaders(i18n.getMessage("header.dist.twintable.selected"), STAR); - selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75F); - selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25F); - selectedTable.setRequired(true); - } - - private void addTooltTipToSelectedTable() { - - selectedTable.setItemDescriptionGenerator(new ItemDescriptionGenerator() { - private static final long serialVersionUID = 99432397408575324L; - - @Override - public String generateDescription(final Component source, final Object itemId, final Object propertyId) { - final Item item = selectedTable.getItem(itemId); - final String description = (String) (item.getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); - if (DIST_TYPE_NAME.equals(propertyId) && !StringUtils.isEmpty(description)) { - return i18n.getMessage("label.description") + description; - } else if (DIST_TYPE_MANDATORY.equals(propertyId)) { - return i18n.getMessage("tooltip.check.for.mandatory"); - } - return null; - } - }); - } - - /** - * - */ - private void buildSourceTable() { - - sourceTable = new Table(); - sourceTable.setId(SPUIDefinitions.TWIN_TABLE_SOURCE_ID); - sourceTable.setSelectable(true); - sourceTable.setMultiSelect(true); - sourceTable.addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); - sourceTable.addStyleName(ValoTheme.TABLE_NO_STRIPES); - sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); - sourceTable.addStyleName(ValoTheme.TABLE_SMALL); - sourceTable.setImmediate(true); - sourceTable.setSizeFull(); - sourceTable.addStyleName("dist_type_twin-table"); - sourceTable.setSortEnabled(false); - sourceTableContainer = new IndexedContainer(); - sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - sourceTable.setContainerDataSource(sourceTableContainer); - - sourceTable.setVisibleColumns(DIST_TYPE_NAME); - sourceTable.setColumnHeaders(i18n.getMessage("header.dist.twintable.available")); - sourceTable.setColumnExpandRatio(DIST_TYPE_NAME, 1.0F); - getSourceTableData(); - addTooltip(); - sourceTable.select(sourceTable.firstItemId()); - } - - private void createSelectedTableContainer() { - - selectedTableContainer = new IndexedContainer(); - selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); - } - - private void createOriginalSelectedTableContainer() { - - originalSelectedTableContainer = new IndexedContainer(); - originalSelectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - originalSelectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - originalSelectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); - } - - @SuppressWarnings("unchecked") - private void addSMType() { - - final Set selectedIds = (Set) sourceTable.getValue(); - if (selectedIds == null) { - return; - } - for (final Long id : selectedIds) { - addTargetTableData(id); - } - } - - private void removeSMType() { - - @SuppressWarnings("unchecked") - final Set selectedIds = (Set) selectedTable.getValue(); - if (selectedIds == null) { - return; - } - for (final Long id : selectedIds) { - addSourceTableData(id); - selectedTable.removeItem(id); - } - } - - @SuppressWarnings("unchecked") - private void getSourceTableData() { - - sourceTableContainer.removeAllItems(); - final Iterable moduleTypeBeans = softwareModuleTypeManagement - .findAll(new PageRequest(0, 1_000)); - Item saveTblitem; - for (final SoftwareModuleType swTypeTag : moduleTypeBeans) { - saveTblitem = sourceTableContainer.addItem(swTypeTag.getId()); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName()); - saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription()); - } - } - - private void addTooltip() { - - sourceTable.setItemDescriptionGenerator(new ItemDescriptionGenerator() { - private static final long serialVersionUID = 1L; - - @Override - public String generateDescription(final Component source, final Object itemId, final Object propertyId) { - final Item item = sourceTable.getItem(itemId); - final String description = (String) item.getItemProperty(DIST_TYPE_DESCRIPTION).getValue(); - if (DIST_TYPE_NAME.equals(propertyId) && !StringUtils.isEmpty(description)) { - return i18n.getMessage("label.description") + description; - } - return null; - } - }); - } - - private void addTargetTableData(final Long selectedId) { - - getSelectedTableItemData(selectedId); - sourceTable.removeItem(selectedId); - } - - @SuppressWarnings("unchecked") - private void getSelectedTableItemData(final Long id) { - - Item saveTblitem; - if (selectedTableContainer != null) { - saveTblitem = selectedTableContainer.addItem(id); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( - sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); - final CheckBox mandatoryCheckBox = new CheckBox(); - window.updateAllComponents(mandatoryCheckBox); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox); - saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue( - sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); - } - } - - @SuppressWarnings("unchecked") - private void addSourceTableData(final Long selectedId) { - - if (sourceTableContainer != null) { - Item saveTblitem; - saveTblitem = sourceTableContainer.addItem(selectedId); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() - .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); - saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource() - .getItem(selectedId).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); - } - } - - /** - * Create new DistSet Type tag. - */ - @SuppressWarnings("unchecked") - private void createNewDistributionSetType() { - - final String colorPicked = ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()); - final String typeNameValue = tagName.getValue(); - final String typeKeyValue = typeKey.getValue(); - final String typeDescValue = tagDesc.getValue(); - final List itemIds = (List) selectedTable.getItemIds(); - if (typeNameValue != null && typeKeyValue != null && !CollectionUtils.isEmpty(itemIds)) { - - final List mandatory = itemIds.stream() - .filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId))) - .collect(Collectors.toList()); - - final List optional = itemIds.stream() - .filter(itemId -> isOptionalModuleType(selectedTable.getItem(itemId))).collect(Collectors.toList()); - - final DistributionSetType newDistType = distributionSetTypeManagement - .create(entityFactory.distributionSetType().create().key(typeKeyValue).name(typeNameValue) - .description(typeDescValue).colour(colorPicked).mandatory(mandatory).optional(optional)); - uiNotification.displaySuccess(i18n.getMessage("message.save.success", newDistType.getName())); - eventBus.publish(this, - new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType)); - } else { - uiNotification.displayValidationError(i18n.getMessage("message.error.missing.typenameorkey")); - } - } - - private static boolean isMandatoryModuleType(final Item item) { - final CheckBox mandatoryCheckBox = (CheckBox) item.getItemProperty(DIST_TYPE_MANDATORY).getValue(); - return mandatoryCheckBox.getValue(); - } - - private static boolean isOptionalModuleType(final Item item) { - return !isMandatoryModuleType(item); - } - - /** - * update distributionSet Type. - */ - @SuppressWarnings("unchecked") - private void updateDistributionSetType(final DistributionSetType existingType) { - - final List itemIds = (List) selectedTable.getItemIds(); - - final DistributionSetTypeUpdate update = entityFactory.distributionSetType().update(existingType.getId()) - .description(tagDesc.getValue()) - .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); - if (distributionSetManagement.countByTypeId(existingType.getId()) <= 0 && !CollectionUtils.isEmpty(itemIds)) { - - update.mandatory(itemIds.stream().filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId))) - .collect(Collectors.toList())) - .optional(itemIds.stream().filter(itemId -> isOptionalModuleType(selectedTable.getItem(itemId))) - .collect(Collectors.toList())); - } - - final DistributionSetType updateDistSetType = distributionSetTypeManagement.update(update); - - uiNotification.displaySuccess(i18n.getMessage("message.update.success", updateDistSetType.getName())); - eventBus.publish(this, - new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); - - } - - /** - * reset the components. - */ - @Override - protected void reset() { - - super.reset(); - selectedTable.removeAllItems(); - getSourceTableData(); - } - - /** - * Listener for option group - Create tag/Update. - * - * @param event - * ValueChangeEvent - */ - @Override - protected void optionValueChanged(final ValueChangeEvent event) { - - super.optionValueChanged(event); - - if (updateTagStr.equals(event.getProperty().getValue())) { - selectedTable.getContainerDataSource().removeAllItems(); - getSourceTableData(); - distTypeSelectLayout.setEnabled(false); - } else { - distTypeSelectLayout.setEnabled(true); - selectedTable.setEnabled(true); - selectedTable.getContainerDataSource().removeAllItems(); - sourceTable.getContainerDataSource().removeAllItems(); - getSourceTableData(); - } - } - - /** - * Populate DistributionSet Type name combo. - */ - @Override - public void populateTagNameCombo() { - - tagNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer()); - tagNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); - } - - /** - * Get the LazyQueryContainer instance for DistributionSetTypes. - * - * @return - */ - private static LazyQueryContainer getDistSetTypeLazyQueryContainer() { - - final LazyQueryContainer disttypeContainer = HawkbitCommonUtil - .createLazyQueryContainer(new BeanQueryFactory<>(DistributionSetTypeBeanQuery.class)); - disttypeContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", true, true); - - return disttypeContainer; - } - - @Override - protected void resetTagNameField() { - - super.resetTagNameField(); - typeKey.setEnabled(false); - typeKey.clear(); - selectedTable.removeAllItems(); - getSourceTableData(); - } - - /** - * Select tag & set tag name & tag desc values corresponding to selected - * tag. - * - * @param targetTagSelected - * as the selected tag from combo - */ - @Override - protected void setTagDetails(final String distSetTypeSelected) { - tagName.setValue(distSetTypeSelected); - getSourceTableData(); - selectedTable.getContainerDataSource().removeAllItems(); - distributionSetTypeManagement.getByName(distSetTypeSelected).ifPresent(selectedTypeTag -> { - tagDesc.setValue(selectedTypeTag.getDescription()); - typeKey.setValue(selectedTypeTag.getKey()); - if (distributionSetManagement.countByTypeId(selectedTypeTag.getId()) <= 0) { - distTypeSelectLayout.setEnabled(true); - selectedTable.setEnabled(true); - } else { - uiNotification.displayValidationError( - selectedTypeTag.getName() + " " + i18n.getMessage("message.error.dist.set.type.update")); - distTypeSelectLayout.setEnabled(false); - selectedTable.setEnabled(false); - } - - createOriginalSelectedTableContainer(); - selectedTypeTag.getOptionalModuleTypes() - .forEach(swModuleType -> addTargetTableforUpdate(swModuleType, false)); - selectedTypeTag.getMandatoryModuleTypes() - .forEach(swModuleType -> addTargetTableforUpdate(swModuleType, true)); - setColorPickerComponentsColor(selectedTypeTag.getColour()); - }); - } - - @SuppressWarnings("unchecked") - private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { - - if (selectedTableContainer == null) { - return; - } - final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); - sourceTable.removeItem(swModuleType.getId()); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - final CheckBox mandatoryCheckbox = new CheckBox("", mandatory); - mandatoryCheckbox.setId(swModuleType.getName()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); - - final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); - originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); - - window.updateAllComponents(mandatoryCheckbox); - } - - @Override - protected void updateEntity(final DistributionSetType entity) { - updateDistributionSetType(entity); - - } - - @Override - protected void createEntity() { - createNewDistributionSetType(); - - } - - @Override - protected Optional findEntityByKey() { - return distributionSetTypeManagement.getByKey(typeKey.getValue()); - } - - @Override - protected Optional findEntityByName() { - return distributionSetTypeManagement.getByName(tagName.getValue()); - } - - @Override - protected String getDuplicateKeyErrorMessage(final DistributionSetType existingType) { - return i18n.getMessage("message.type.key.duplicate.check", existingType.getKey()); - } - - @Override - protected String getWindowCaption() { - return i18n.getMessage("caption.add.type"); - } - - @Override - protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { - - super.createOptionGroup(hasCreatePermission, hasUpdatePermission); - optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java deleted file mode 100644 index 54c9adc2d..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.disttype; - -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; -import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; -import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; -import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; -import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.DropHandler; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; - -/** - * Distribution Set Type filter buttons. - */ -public class DSTypeFilterButtons extends AbstractFilterButtons { - - private static final long serialVersionUID = 771251569981876005L; - - private final ManageDistUIState manageDistUIState; - - private final DistributionsViewClientCriterion distributionsViewClientCriterion; - - DSTypeFilterButtons(final UIEventBus eventBus, final ManageDistUIState manageDistUIState, - final DistributionsViewClientCriterion distributionsViewClientCriterion, - final DistributionSetTypeManagement distributionSetTypeManagement) { - super(eventBus, new DSTypeFilterButtonClick(eventBus, manageDistUIState, distributionSetTypeManagement)); - this.manageDistUIState = manageDistUIState; - this.distributionsViewClientCriterion = distributionsViewClientCriterion; - } - - @Override - protected String getButtonsTableId() { - - return UIComponentIdProvider.DISTRIBUTION_SET_TYPE_TABLE_ID; - } - - @Override - protected LazyQueryContainer createButtonsLazyQueryContainer() { - return HawkbitCommonUtil.createLazyQueryContainer(new BeanQueryFactory<>(DistributionSetTypeBeanQuery.class)); - } - - @Override - protected boolean isClickedByDefault(final String typeName) { - return manageDistUIState.getManageDistFilters().getClickedDistSetType() != null - && manageDistUIState.getManageDistFilters().getClickedDistSetType().getName().equals(typeName); - } - - @Override - protected String createButtonId(final String name) { - - return UIComponentIdProvider.DS_TYPE_FILTER_BTN_ID + name; - } - - @Override - protected DropHandler getFilterButtonDropHandler() { - - return new DropHandler() { - private static final long serialVersionUID = 1L; - - @Override - public AcceptCriterion getAcceptCriterion() { - return distributionsViewClientCriterion; - } - - @Override - public void drop(final DragAndDropEvent event) { - /* Not required */ - } - }; - } - - @Override - protected String getButtonWrapperData() { - return null; - } - - @Override - protected String getButttonWrapperIdPrefix() { - - return SPUIDefinitions.DISTRIBUTION_SET_TYPE_ID_PREFIXS; - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final DistributionSetTypeEvent event) { - if (event.getDistributionSetTypeEnum() == DistributionSetTypeEvent.DistributionSetTypeEnum.ADD_DIST_SET_TYPE - || event.getDistributionSetTypeEnum() == DistributionSetTypeEvent.DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE) { - refreshTypeTable(); - } - - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final SaveActionWindowEvent event) { - if (event == SaveActionWindowEvent.SAVED_DELETE_DIST_SET_TYPES) { - refreshTypeTable(); - } - - } - - private void refreshTypeTable() { - setContainerDataSource(createButtonsLazyQueryContainer()); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterHeader.java deleted file mode 100644 index f39590ae8..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterHeader.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.disttype; - -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.CommonDialogWindow; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; -import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.UI; - -/** - * Distribution Set Type filter buttons header. - */ -public class DSTypeFilterHeader extends AbstractFilterHeader { - - private static final long serialVersionUID = 3433417459392880222L; - - private final ManageDistUIState manageDistUIState; - - private final CreateUpdateDistSetTypeLayout createUpdateDistSetTypeLayout; - - DSTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, - final ManageDistUIState manageDistUIState, final EntityFactory entityFactory, - final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final DistributionSetTypeManagement distributionSetTypeManagement, - final DistributionSetManagement distributionSetManagement) { - super(permChecker, eventBus, i18n); - this.manageDistUIState = manageDistUIState; - this.createUpdateDistSetTypeLayout = new CreateUpdateDistSetTypeLayout(i18n, entityFactory, eventBus, - permChecker, uiNotification, softwareModuleTypeManagement, distributionSetTypeManagement, - distributionSetManagement); - if (hasCreateUpdatePermission()) { - createUpdateDistSetTypeLayout.init(); - } - } - - @Override - protected boolean hasCreateUpdatePermission() { - return permChecker.hasCreateRepositoryPermission() || permChecker.hasUpdateRepositoryPermission(); - } - - @Override - protected String getTitle() { - return SPUILabelDefinitions.TYPE; - } - - @Override - protected void settingsIconClicked(final ClickEvent event) { - final CommonDialogWindow addUpdateWindow = createUpdateDistSetTypeLayout.getWindow(); - UI.getCurrent().addWindow(addUpdateWindow); - } - - @Override - protected boolean dropHitsRequired() { - return false; - } - - @Override - protected void hideFilterButtonLayout() { - manageDistUIState.setDistTypeFilterClosed(true); - eventBus.publish(this, DistributionsUIEvent.HIDE_DIST_FILTER_BY_TYPE); - } - - @Override - protected String getConfigureFilterButtonId() { - - return SPUIDefinitions.ADD_DISTRIBUTION_TYPE_TAG; - } - - @Override - protected String getHideButtonId() { - return SPUIDefinitions.HIDE_FILTER_DIST_TYPE; - } - - @Override - protected boolean isAddTagRequired() { - return true; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DistributionSetTypeSoftwareModuleSelectLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DistributionSetTypeSoftwareModuleSelectLayout.java new file mode 100644 index 000000000..173d5a3c0 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DistributionSetTypeSoftwareModuleSelectLayout.java @@ -0,0 +1,330 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype; + +import java.util.Set; + +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; +import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.data.domain.PageRequest; +import org.springframework.util.StringUtils; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.FontAwesome; +import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +/** + * Layout for the software modules select tables for managing Distribution Set + * Types on the Distributions View. + */ +public class DistributionSetTypeSoftwareModuleSelectLayout extends VerticalLayout { + + private static final long serialVersionUID = 1L; + + private static final String DIST_TYPE_DESCRIPTION = "description"; + + private static final String DIST_TYPE_MANDATORY = "mandatory"; + + private static final String STAR = " * "; + + private static final String DIST_TYPE_NAME = "name"; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private Table selectedTable; + + private Table sourceTable; + + private IndexedContainer selectedTableContainer; + + private IndexedContainer sourceTableContainer; + + private HorizontalLayout distTypeSelectLayout; + + private final VaadinMessageSource i18n; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + */ + public DistributionSetTypeSoftwareModuleSelectLayout(final VaadinMessageSource i18n, + final SoftwareModuleTypeManagement softwareModuleTypeManagement) { + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.i18n = i18n; + init(); + } + + protected void init() { + distTypeSelectLayout = createTwinColumnLayout(); + setSizeFull(); + addComponent(distTypeSelectLayout); + } + + private HorizontalLayout createTwinColumnLayout() { + final HorizontalLayout twinColumnLayout = new HorizontalLayout(); + twinColumnLayout.setSizeFull(); + twinColumnLayout.setWidth("400px"); + + buildSourceTable(); + buildSelectedTable(); + + final VerticalLayout selectButtonLayout = new VerticalLayout(); + final Button selectButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SELECT_DIST_TYPE, "", "", + "arrow-button", true, FontAwesome.FORWARD, SPUIButtonStyleNoBorder.class); + selectButton.addClickListener(event -> addSMType()); + final Button unSelectButton = SPUIComponentProvider.getButton("unselect-dist-type", "", "", "arrow-button", + true, FontAwesome.BACKWARD, SPUIButtonStyleNoBorder.class); + unSelectButton.addClickListener(event -> removeSMType()); + selectButtonLayout.addComponent(selectButton); + selectButtonLayout.addComponent(unSelectButton); + selectButtonLayout.setComponentAlignment(selectButton, Alignment.MIDDLE_CENTER); + selectButtonLayout.setComponentAlignment(unSelectButton, Alignment.MIDDLE_CENTER); + + twinColumnLayout.addComponent(sourceTable); + twinColumnLayout.addComponent(selectButtonLayout); + twinColumnLayout.addComponent(selectedTable); + twinColumnLayout.setComponentAlignment(sourceTable, Alignment.MIDDLE_LEFT); + twinColumnLayout.setComponentAlignment(selectButtonLayout, Alignment.MIDDLE_CENTER); + twinColumnLayout.setComponentAlignment(selectedTable, Alignment.MIDDLE_RIGHT); + twinColumnLayout.setExpandRatio(sourceTable, 0.45F); + twinColumnLayout.setExpandRatio(selectButtonLayout, 0.07F); + twinColumnLayout.setExpandRatio(selectedTable, 0.48F); + sourceTable.setVisibleColumns(DIST_TYPE_NAME); + return twinColumnLayout; + } + + private void buildSelectedTable() { + selectedTable = new Table(); + selectedTable.setId(SPUIDefinitions.TWIN_TABLE_SELECTED_ID); + selectedTable.setSelectable(true); + selectedTable.setMultiSelect(true); + selectedTable.setSortEnabled(false); + selectedTable.addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); + selectedTable.addStyleName(ValoTheme.TABLE_NO_STRIPES); + selectedTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); + selectedTable.addStyleName(ValoTheme.TABLE_SMALL); + selectedTable.addStyleName("dist_type_twin-table"); + selectedTable.setSizeFull(); + createSelectedTableContainer(); + selectedTable.setContainerDataSource(selectedTableContainer); + addTooltTipToSelectedTable(); + selectedTable.setImmediate(true); + selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY); + selectedTable.setColumnHeaders(i18n.getMessage("header.dist.twintable.selected"), STAR); + selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75F); + selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25F); + selectedTable.setRequired(true); + } + + private void addTooltTipToSelectedTable() { + selectedTable.setItemDescriptionGenerator(new ItemDescriptionGenerator() { + private static final long serialVersionUID = 1L; + + @Override + public String generateDescription(final Component source, final Object itemId, final Object propertyId) { + final Item item = selectedTable.getItem(itemId); + final String description = (String) (item.getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); + if (DIST_TYPE_NAME.equals(propertyId) && !StringUtils.isEmpty(description)) { + return i18n.getMessage("label.description") + description; + } else if (DIST_TYPE_MANDATORY.equals(propertyId)) { + return i18n.getMessage("tooltip.check.for.mandatory"); + } + return null; + } + }); + } + + private void buildSourceTable() { + sourceTable = new Table(); + sourceTable.setId(SPUIDefinitions.TWIN_TABLE_SOURCE_ID); + sourceTable.setSelectable(true); + sourceTable.setMultiSelect(true); + sourceTable.addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); + sourceTable.addStyleName(ValoTheme.TABLE_NO_STRIPES); + sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); + sourceTable.addStyleName(ValoTheme.TABLE_SMALL); + sourceTable.setImmediate(true); + sourceTable.setSizeFull(); + sourceTable.addStyleName("dist_type_twin-table"); + sourceTable.setSortEnabled(false); + sourceTableContainer = new IndexedContainer(); + sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + sourceTable.setContainerDataSource(sourceTableContainer); + + sourceTable.setVisibleColumns(DIST_TYPE_NAME); + sourceTable.setColumnHeaders(i18n.getMessage("header.dist.twintable.available")); + sourceTable.setColumnExpandRatio(DIST_TYPE_NAME, 1.0F); + createSourceTableData(); + addTooltip(); + sourceTable.select(sourceTable.firstItemId()); + } + + @SuppressWarnings("unchecked") + protected void createSourceTableData() { + sourceTableContainer.removeAllItems(); + final Iterable moduleTypeBeans = softwareModuleTypeManagement + .findAll(new PageRequest(0, 1000)); + Item saveTblitem; + for (final SoftwareModuleType swTypeTag : moduleTypeBeans) { + saveTblitem = sourceTableContainer.addItem(swTypeTag.getId()); + saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName()); + saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription()); + } + } + + protected void addTooltip() { + sourceTable.setItemDescriptionGenerator(new ItemDescriptionGenerator() { + private static final long serialVersionUID = 1L; + + @Override + public String generateDescription(final Component source, final Object itemId, final Object propertyId) { + final Item item = sourceTable.getItem(itemId); + final String description = (String) item.getItemProperty(DIST_TYPE_DESCRIPTION).getValue(); + if (DIST_TYPE_NAME.equals(propertyId) && !StringUtils.isEmpty(description)) { + return i18n.getMessage("label.description") + description; + } + return null; + } + }); + } + + protected void createSelectedTableContainer() { + selectedTableContainer = new IndexedContainer(); + selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); + } + + @SuppressWarnings("unchecked") + private void addSMType() { + final Set selectedIds = (Set) sourceTable.getValue(); + if (selectedIds == null) { + return; + } + for (final Long id : selectedIds) { + addTargetTableData(id); + } + } + + private void addTargetTableData(final Long selectedId) { + getSelectedTableItemData(selectedId); + sourceTable.removeItem(selectedId); + } + + @SuppressWarnings("unchecked") + private void getSelectedTableItemData(final Long id) { + Item saveTblitem; + if (selectedTableContainer != null) { + saveTblitem = selectedTableContainer.addItem(id); + saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( + sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); + final CheckBox mandatoryCheckBox = new CheckBox(); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox); + saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue( + sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); + } + } + + @SuppressWarnings("unchecked") + private void addSourceTableData(final Long selectedId) { + if (sourceTableContainer != null) { + Item saveTblitem; + saveTblitem = sourceTableContainer.addItem(selectedId); + saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() + .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); + saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource() + .getItem(selectedId).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); + } + } + + private void removeSMType() { + @SuppressWarnings("unchecked") + final Set selectedIds = (Set) selectedTable.getValue(); + if (selectedIds == null) { + return; + } + for (final Long id : selectedIds) { + addSourceTableData(id); + selectedTable.removeItem(id); + } + } + + public Table getSelectedTable() { + return selectedTable; + } + + public static String getDistTypeMandatory() { + return DIST_TYPE_MANDATORY; + } + + public static String getDistTypeDescription() { + return DIST_TYPE_DESCRIPTION; + } + + public static String getDistTypeName() { + return DIST_TYPE_NAME; + } + + public Table getSourceTable() { + return sourceTable; + } + + public IndexedContainer getSourceTableContainer() { + return sourceTableContainer; + } + + protected static boolean isMandatoryModuleType(final Item item) { + final CheckBox mandatoryCheckBox = (CheckBox) item.getItemProperty(getDistTypeMandatory()).getValue(); + return mandatoryCheckBox.getValue(); + } + + public IndexedContainer getSelectedTableContainer() { + return selectedTableContainer; + } + + protected static boolean isOptionalModuleType(final Item item) { + return !isMandatoryModuleType(item); + } + + public HorizontalLayout getDistTypeSelectLayout() { + return distTypeSelectLayout; + } + + public void setDistTypeSelectLayout(final HorizontalLayout distTypeSelectLayout) { + this.distTypeSelectLayout = distTypeSelectLayout; + } + + /** + * Resets the tables for selecting the software modules + */ + public void reset() { + selectedTableContainer.removeAllItems(); + createSourceTableData(); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/UpdateDistributionSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/UpdateDistributionSetTypeLayout.java new file mode 100644 index 000000000..0a3e3586c --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/UpdateDistributionSetTypeLayout.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; +import org.eclipse.hawkbit.ui.layouts.UpdateTag; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.util.CollectionUtils; +import org.vaadin.spring.events.EventBus.UIEventBus; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Window.CloseListener; + +/** + * Layout for the pop-up window which is created when updating a Distribution + * Set Type on the Distributions View. + * + */ +public class UpdateDistributionSetTypeLayout extends AbstractDistributionSetTypeLayout implements UpdateTag { + + private static final long serialVersionUID = 1L; + + private final transient DistributionSetManagement distributionSetManagement; + + private final String selectedTypeName; + + private IndexedContainer originalSelectedTableContainer; + + private final CloseListener closeListener; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + * @param distributionSetManagement + * DistributionSetManagement + * @param selectedTypeName + * the name of the distribution set type to update + * @param closeListener + * CloseListener + */ + public UpdateDistributionSetTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final DistributionSetTypeManagement distributionSetTypeManagement, + final DistributionSetManagement distributionSetManagement, final String selectedTypeName, + final CloseListener closeListener) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, distributionSetTypeManagement, + softwareModuleTypeManagement); + this.distributionSetManagement = distributionSetManagement; + this.selectedTypeName = selectedTypeName; + this.closeListener = closeListener; + initUpdatePopup(); + } + + private void initUpdatePopup() { + setTagDetails(selectedTypeName); + getWindow().addCloseListener(closeListener); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.update", getI18n().getMessage("caption.type")); + } + + @Override + protected void saveEntity() { + updateDistributionSetType(findEntityByName() + .orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, getTagName().getValue()))); + } + + @Override + protected void buildLayout() { + super.buildLayout(); + disableFields(); + } + + @Override + protected void disableFields() { + getTypeKey().setEnabled(false); + getTagName().setEnabled(false); + } + + @Override + public void setTagDetails(final String selectedEntity) { + getTwinTables().createSourceTableData(); + getTwinTables().getSelectedTable().getContainerDataSource().removeAllItems(); + final Optional selectedDistSetType = getDistributionSetTypeManagement() + .getByName(selectedEntity); + selectedDistSetType.ifPresent(selectedType -> { + getTagName().setValue(selectedType.getName()); + getTagDesc().setValue(selectedType.getDescription()); + getTypeKey().setValue(selectedType.getKey()); + if (distributionSetManagement.countByTypeId(selectedType.getId()) <= 0) { + getTwinTables().getDistTypeSelectLayout().setEnabled(true); + getTwinTables().getSelectedTable().setEnabled(true); + } else { + getUiNotification().displayValidationError( + selectedType.getName() + " " + getI18n().getMessage("message.error.dist.set.type.update")); + getTwinTables().getDistTypeSelectLayout().setEnabled(false); + getTwinTables().getSelectedTable().setEnabled(false); + } + + createOriginalSelectedTableContainer(); + selectedType.getOptionalModuleTypes().forEach(swModuleType -> addTargetTableForUpdate(swModuleType, false)); + selectedType.getMandatoryModuleTypes().forEach(swModuleType -> addTargetTableForUpdate(swModuleType, true)); + setColorPickerComponentsColor(selectedType.getColour()); + }); + + disableFields(); + getWindow().setOrginaleValues(); + } + + private void createOriginalSelectedTableContainer() { + originalSelectedTableContainer = new IndexedContainer(); + originalSelectedTableContainer.addContainerProperty( + DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeName(), String.class, ""); + originalSelectedTableContainer.addContainerProperty( + DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeDescription(), String.class, ""); + originalSelectedTableContainer.addContainerProperty( + DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeMandatory(), CheckBox.class, null); + } + + @SuppressWarnings("unchecked") + private void addTargetTableForUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { + if (getTwinTables().getSelectedTableContainer() == null) { + return; + } + final Item saveTblitem = getTwinTables().getSelectedTableContainer().addItem(swModuleType.getId()); + getTwinTables().getSourceTable().removeItem(swModuleType.getId()); + saveTblitem.getItemProperty(DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeName()) + .setValue(swModuleType.getName()); + final CheckBox mandatoryCheckbox = new CheckBox("", mandatory); + mandatoryCheckbox.setId(swModuleType.getName()); + saveTblitem.getItemProperty(DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeMandatory()) + .setValue(mandatoryCheckbox); + + final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); + originalItem.getItemProperty(DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeName()) + .setValue(swModuleType.getName()); + originalItem.getItemProperty(DistributionSetTypeSoftwareModuleSelectLayout.getDistTypeMandatory()) + .setValue(mandatoryCheckbox); + + getWindow().updateAllComponents(mandatoryCheckbox); + } + + @SuppressWarnings("unchecked") + private void updateDistributionSetType(final DistributionSetType existingType) { + final List itemIds = (List) getTwinTables().getSelectedTable().getItemIds(); + final DistributionSetTypeUpdate update = getEntityFactory().distributionSetType().update(existingType.getId()) + .description(getTagDesc().getValue()) + .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); + if (distributionSetManagement.countByTypeId(existingType.getId()) <= 0 && !CollectionUtils.isEmpty(itemIds)) { + update.mandatory(itemIds.stream() + .filter(itemId -> DistributionSetTypeSoftwareModuleSelectLayout + .isMandatoryModuleType(getTwinTables().getSelectedTable().getItem(itemId))) + .collect(Collectors.toList())) + .optional(itemIds.stream() + .filter(itemId -> DistributionSetTypeSoftwareModuleSelectLayout + .isOptionalModuleType(getTwinTables().getSelectedTable().getItem(itemId))) + .collect(Collectors.toList())); + } + + final DistributionSetType updateDistSetType = getDistributionSetTypeManagement().update(update); + + getUiNotification().displaySuccess(getI18n().getMessage("message.update.success", updateDistSetType.getName())); + getEventBus().publish(this, + new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); + } + + @Override + protected boolean isUpdateAction() { + return true; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtonClick.java similarity index 94% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtonClick.java index 48268c587..6a6c758bc 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtonClick.java @@ -6,9 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.distributions.disttype; - -import java.io.Serializable; +package org.eclipse.hawkbit.ui.distributions.disttype.filter; import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterSingleButtonClick; @@ -22,7 +20,7 @@ import com.vaadin.ui.Button; /** * Single button click behaviour of filter buttons layout. */ -public class DSTypeFilterButtonClick extends AbstractFilterSingleButtonClick implements Serializable { +public class DSTypeFilterButtonClick extends AbstractFilterSingleButtonClick { private static final long serialVersionUID = 1L; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtons.java new file mode 100644 index 000000000..05f690e8a --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterButtons.java @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype.filter; + +import java.util.Optional; + +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.event.DistributionSetTypeFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; +import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; +import org.eclipse.hawkbit.ui.distributions.disttype.UpdateDistributionSetTypeLayout; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; +import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; +import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; +import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; +import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.ui.Button.ClickEvent; + +/** + * Distribution Set Type filter buttons. + */ +public class DSTypeFilterButtons extends AbstractFilterButtons { + + private static final long serialVersionUID = 1L; + + private final ManageDistUIState manageDistUIState; + + private final DistributionsViewClientCriterion distributionsViewClientCriterion; + + private final transient EntityFactory entityFactory; + + private final SpPermissionChecker permChecker; + + private final UINotification uiNotification; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private final transient DistributionSetManagement distributionSetManagement; + + private final transient DistributionSetTypeManagement distributionSetTypeManagement; + + private final transient SystemManagement systemManagement; + + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param manageDistUIState + * ManageDistUIState + * @param distributionsViewClientCriterion + * DistributionsViewClientCriterion + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param distributionSetManagement + * DistributionSetManagement + * @param systemManagement + * SystemManagement + */ + public DSTypeFilterButtons(final UIEventBus eventBus, final ManageDistUIState manageDistUIState, + final DistributionsViewClientCriterion distributionsViewClientCriterion, + final DistributionSetTypeManagement distributionSetTypeManagement, final VaadinMessageSource i18n, + final EntityFactory entityFactory, final SpPermissionChecker permChecker, + final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final DistributionSetManagement distributionSetManagement, final SystemManagement systemManagement) { + super(eventBus, new DSTypeFilterButtonClick(eventBus, manageDistUIState, distributionSetTypeManagement), i18n); + this.manageDistUIState = manageDistUIState; + this.distributionsViewClientCriterion = distributionsViewClientCriterion; + this.entityFactory = entityFactory; + this.permChecker = permChecker; + this.uiNotification = uiNotification; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.distributionSetManagement = distributionSetManagement; + this.distributionSetTypeManagement = distributionSetTypeManagement; + this.systemManagement = systemManagement; + } + + @Override + protected String getButtonsTableId() { + return UIComponentIdProvider.DISTRIBUTION_SET_TYPE_TABLE_ID; + } + + @Override + protected LazyQueryContainer createButtonsLazyQueryContainer() { + return HawkbitCommonUtil.createLazyQueryContainer(new BeanQueryFactory<>(DistributionSetTypeBeanQuery.class)); + } + + @Override + protected boolean isClickedByDefault(final String typeName) { + return manageDistUIState.getManageDistFilters().getClickedDistSetType() != null + && manageDistUIState.getManageDistFilters().getClickedDistSetType().getName().equals(typeName); + } + + @Override + protected String createButtonId(final String name) { + return UIComponentIdProvider.DS_TYPE_FILTER_BTN_ID + name; + } + + @Override + protected DropHandler getFilterButtonDropHandler() { + + return new DropHandler() { + private static final long serialVersionUID = 1L; + + @Override + public AcceptCriterion getAcceptCriterion() { + return distributionsViewClientCriterion; + } + + @Override + public void drop(final DragAndDropEvent event) { + /* Not required */ + } + }; + } + + @Override + protected String getButtonWrapperData() { + return null; + } + + @Override + protected String getButttonWrapperIdPrefix() { + return SPUIDefinitions.DISTRIBUTION_SET_TYPE_ID_PREFIXS; + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final DistributionSetTypeEvent event) { + if (event.getDistributionSetTypeEnum() == DistributionSetTypeEvent.DistributionSetTypeEnum.ADD_DIST_SET_TYPE + || event.getDistributionSetTypeEnum() == DistributionSetTypeEvent.DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE) { + refreshTable(); + } + if (event + .getDistributionSetTypeEnum() == DistributionSetTypeEvent.DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE) { + getEventBus().publish(this, new DistributionSetTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + } + + @EventBusListenerMethod(scope = EventScope.UI) + void onEvent(final SaveActionWindowEvent event) { + if (event == SaveActionWindowEvent.SAVED_DELETE_DIST_SET_TYPES) { + refreshTable(); + } + } + + @Override + protected void addEditButtonClickListener(final ClickEvent event) { + new UpdateDistributionSetTypeLayout(getI18n(), entityFactory, getEventBus(), permChecker, uiNotification, + softwareModuleTypeManagement, distributionSetTypeManagement, distributionSetManagement, + getEntityId(event), getCloseListenerForEditAndDeleteTag( + new DistributionSetTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR))); + } + + @Override + protected void addDeleteButtonClickListener(final ClickEvent event) { + openConfirmationWindowForDeletion(getEntityId(event), getI18n().getMessage("caption.entity.distribution.type"), + new DistributionSetTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + + @Override + protected void deleteEntity(final String entityToDelete) { + final Optional distTypeToDelete = distributionSetTypeManagement.getByName(entityToDelete); + distTypeToDelete.ifPresent(tag -> { + if (tag.equals(manageDistUIState.getManageDistFilters().getClickedDistSetType())) { + uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityToDelete)); + removeUpdateAndDeleteColumn(); + } else if (isDefaultDsType(entityToDelete)) { + uiNotification.displayValidationError(getI18n().getMessage("message.cannot.delete.default.dstype")); + removeUpdateAndDeleteColumn(); + } else { + distributionSetTypeManagement.delete(distTypeToDelete.get().getId()); + getEventBus().publish(this, SaveActionWindowEvent.SAVED_DELETE_DIST_SET_TYPES); + uiNotification.displaySuccess(getI18n().getMessage("message.delete.success", entityToDelete)); + } + }); + } + + private boolean isDefaultDsType(final String dsTypeName) { + return getCurrentDistributionSetType() != null && getCurrentDistributionSetType().getName().equals(dsTypeName); + } + + private DistributionSetType getCurrentDistributionSetType() { + return systemManagement.getTenantMetadata().getDefaultDsType(); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterHeader.java new file mode 100644 index 000000000..332a24de7 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterHeader.java @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.disttype.filter; + +import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.event.DistributionSetTypeFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; +import org.eclipse.hawkbit.ui.distributions.disttype.CreateDistributionSetTypeLayout; +import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; +import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.MenuBar.Command; + +/** + * Distribution Set Type filter buttons header. + */ +public class DSTypeFilterHeader extends AbstractFilterHeader { + + private static final long serialVersionUID = 1L; + + private final ManageDistUIState manageDistUIState; + + private final transient EntityFactory entityFactory; + + private final transient UINotification uiNotification; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private final transient DistributionSetTypeManagement distributionSetTypeManagement; + + private final DSTypeFilterButtons dSTypeFilterButtons; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param permChecker + * SpPermissionChecker + * @param eventBus + * UIEventBus + * @param manageDistUIState + * ManageDistUIState + * @param entityFactory + * EntityFactory + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + * @param dSTypeFilterButtons + * DSTypeFilterButtons + */ + DSTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, + final ManageDistUIState manageDistUIState, final EntityFactory entityFactory, + final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final DistributionSetTypeManagement distributionSetTypeManagement, + final DSTypeFilterButtons dSTypeFilterButtons) { + super(permChecker, eventBus, i18n); + this.manageDistUIState = manageDistUIState; + this.entityFactory = entityFactory; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.distributionSetTypeManagement = distributionSetTypeManagement; + this.uiNotification = uiNotification; + this.dSTypeFilterButtons = dSTypeFilterButtons; + } + + @Override + protected String getTitle() { + return SPUILabelDefinitions.TYPE; + } + + @Override + protected boolean dropHitsRequired() { + return false; + } + + @Override + protected void hideFilterButtonLayout() { + manageDistUIState.setDistTypeFilterClosed(true); + getEventBus().publish(this, DistributionsUIEvent.HIDE_DIST_FILTER_BY_TYPE); + } + + @Override + protected String getConfigureFilterButtonId() { + + return UIComponentIdProvider.ADD_DISTRIBUTION_TYPE_TAG; + } + + @Override + protected String getHideButtonId() { + return UIComponentIdProvider.HIDE_FILTER_DIST_TYPE; + } + + @Override + protected boolean isAddTagRequired() { + return true; + } + + @Override + protected Command getAddButtonCommand() { + return command -> new CreateDistributionSetTypeLayout(getI18n(), entityFactory, getEventBus(), getPermChecker(), + uiNotification, softwareModuleTypeManagement, distributionSetTypeManagement); + } + + @Override + protected Command getDeleteButtonCommand() { + return command -> { + dSTypeFilterButtons.addDeleteColumn(); + getEventBus().publish(this, new DistributionSetTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected Command getUpdateButtonCommand() { + return command -> { + dSTypeFilterButtons.addUpdateColumn(); + getEventBus().publish(this, new DistributionSetTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + super.cancelUpdateOrDeleteTag(event); + dSTypeFilterButtons.removeUpdateAndDeleteColumn(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + private void onEvent(final DistributionSetTypeFilterHeaderEvent event) { + processFilterHeaderEvent(event); + } + + @Override + protected String getMenuBarId() { + return UIComponentIdProvider.DIST_TAG_MENU_BAR_ID; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterLayout.java similarity index 72% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterLayout.java index bbf712a65..66258fe54 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/filter/DSTypeFilterLayout.java @@ -6,15 +6,13 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.distributions.disttype; +package org.eclipse.hawkbit.ui.distributions.disttype.filter; -import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterLayout; -import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -28,24 +26,42 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; */ public class DSTypeFilterLayout extends AbstractFilterLayout { - private static final long serialVersionUID = 2689002932344750781L; + private static final long serialVersionUID = 1L; private final ManageDistUIState manageDistUIState; + /** + * Constructor + * + * @param manageDistUIState + * ManageDistUIState + * @param i18n + * VaadinMessageSource + * @param permChecker + * SpPermissionChecker + * @param eventBus + * UIEventBus + * @param entityFactory + * EntityFactory + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param distributionSetTypeManagement + * DistributionSetTypeManagement + * @param dSTypeFilterButtons + * DSTypeFilterButtons + */ public DSTypeFilterLayout(final ManageDistUIState manageDistUIState, final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, final EntityFactory entityFactory, final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, final DistributionSetTypeManagement distributionSetTypeManagement, - final DistributionSetManagement distributionSetManagement, - final DistributionsViewClientCriterion distributionsViewClientCriterion) { + final DSTypeFilterButtons dSTypeFilterButtons) { super(new DSTypeFilterHeader(i18n, permChecker, eventBus, manageDistUIState, entityFactory, uiNotification, - softwareModuleTypeManagement, distributionSetTypeManagement, distributionSetManagement), - new DSTypeFilterButtons(eventBus, manageDistUIState, distributionsViewClientCriterion, - distributionSetTypeManagement)); + softwareModuleTypeManagement, distributionSetTypeManagement, dSTypeFilterButtons), dSTypeFilterButtons, + eventBus); this.manageDistUIState = manageDistUIState; - restoreState(); - eventBus.subscribe(this); } @EventBusListenerMethod(scope = EventScope.UI) @@ -60,7 +76,6 @@ public class DSTypeFilterLayout extends AbstractFilterLayout { @Override public Boolean onLoadIsTypeFilterIsClosed() { - return manageDistUIState.isDistTypeFilterClosed(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 1b05e812a..06edaca14 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -25,7 +25,7 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.detailslayout.TargetFilterQueryDetailsTable; import org.eclipse.hawkbit.ui.common.entity.SoftwareModuleIdName; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.management.dstable.DistributionAddUpdateWindowLayout; @@ -158,7 +158,7 @@ public class DistributionSetDetails extends AbstractDistributionSetDetails { .map(selected -> targetManagement.countByAssignedDistributionSet(selected) <= 0).orElse(false)) { final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true, - FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TIMES, SPUIButtonStyleNoBorder.class); reassignSoftModule.setEnabled(false); return reassignSoftModule; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index de6477eec..374a9c959 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -18,6 +18,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -29,14 +30,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.entity.SoftwareModuleIdName; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; @@ -46,14 +46,10 @@ import org.eclipse.hawkbit.ui.push.DistributionSetUpdatedEventContainer; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.eclipse.hawkbit.ui.view.filter.OnlyEventsFromDistributionsViewFilter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition; @@ -66,8 +62,6 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Button; import com.vaadin.ui.Component; import com.vaadin.ui.Table; import com.vaadin.ui.UI; @@ -79,8 +73,6 @@ public class DistributionSetTable extends AbstractNamedVersionTable events.stream().filter(Objects::nonNull) .filter(event -> event.getEntityId().equals(lastSelectedDsIdName)).findAny() - .ifPresent(event -> eventBus.publish(this, + .ifPresent(event -> getEventBus().publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity())))); } @@ -173,14 +162,10 @@ public class DistributionSetTable extends AbstractNamedVersionTable source = (AbstractTable) transferable.getSourceComponent(); - final Set softwareModulesIdList = source.getDeletedEntityByTransferable(transferable); + final Set softwareModulesIdList = source.getSelectedEntitiesByTransferable(transferable); + selectDraggedEntities(source, softwareModulesIdList); final AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails) event.getTargetDetails(); final Object distItemId = dropData.getItemIdOver(); if (distItemId != null) { - handleDropEvent(source, softwareModulesIdList, distItemId); + assignSwmToDs(source, softwareModulesIdList, (long) distItemId); } } @@ -236,30 +222,44 @@ public class DistributionSetTable extends AbstractNamedVersionTable softwareModulesIdList, final Object distId) { - final Optional distributionSet = distributionSetManagement.get((Long) distId); - + private void assignSwmToDs(final Table source, final Set softwareModulesIdList, final long distId) { + final Optional distributionSet = distributionSetManagement.get(distId); + distributionSet.ifPresent(set -> { + final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(set); + selectDroppedEntities(distributionSetIdName.getId()); + final HashMap> map = createAssignmentMap(distributionSetIdName); + handleSoftwareModulesForAssignment(source, softwareModulesIdList, distId, map); + final HashSet softwareModules = new HashSet<>(); + map.keySet().forEach(typeId -> softwareModules.addAll(map.get(typeId))); + manageDistUIState.getAssignedList().put(distributionSetIdName, softwareModules); + openConfirmationWindowForAssignment(distributionSetIdName.getName(), + softwareModules.toArray(new SoftwareModuleIdName[softwareModules.size()])); + }); if (!distributionSet.isPresent()) { - notification.displayWarning(i18n.getMessage("distributionset.not.exists")); - return; + getNotification().displayWarning(getI18n().getMessage("distributionset.not.exists")); } + } - final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distributionSet.get()); - + private HashMap> createAssignmentMap( + final DistributionSetIdName distributionSetIdName) { final HashMap> map; - if (manageDistUIState.getConsolidatedDistSoftwarewList().containsKey(distributionSetIdName)) { - map = manageDistUIState.getConsolidatedDistSoftwarewList().get(distributionSetIdName); + if (manageDistUIState.getConsolidatedDistSoftwareList().containsKey(distributionSetIdName)) { + map = manageDistUIState.getConsolidatedDistSoftwareList().get(distributionSetIdName); } else { map = new HashMap<>(); - manageDistUIState.getConsolidatedDistSoftwarewList().put(distributionSetIdName, map); + manageDistUIState.getConsolidatedDistSoftwareList().put(distributionSetIdName, map); } + return map; + } + private void handleSoftwareModulesForAssignment(final Table source, final Set softwareModulesIdList, + final long distId, final HashMap> map) { for (final Long softwareModuleId : softwareModulesIdList) { final Item softwareItem = source.getContainerDataSource().getItem(softwareModuleId); final String name = (String) softwareItem.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); @@ -267,27 +267,19 @@ public class DistributionSetTable extends AbstractNamedVersionTable softwareModule = softwareModuleManagement.get(softwareModuleId); - if (softwareModule.isPresent() && validSoftwareModule((Long) distId, softwareModule.get())) { + if (softwareModule.isPresent() && validSoftwareModule(distId, softwareModule.get())) { final SoftwareModuleIdName softwareModuleIdName = new SoftwareModuleIdName(softwareModuleId, name.concat(":" + swVersion)); - publishAssignEvent((Long) distId, softwareModule.get()); + publishAssignEvent(distId, softwareModule.get()); handleSoftwareCase(map, softwareModule.get(), softwareModuleIdName); handleFirmwareCase(map, softwareModule.get(), softwareModuleIdName); - } else { - return; } } - - // hashset is seriablizable - final HashSet softwareModules = new HashSet<>(); - map.keySet().forEach(typeId -> softwareModules.addAll(map.get(typeId))); - - updateDropedDetails(distributionSetIdName, softwareModules); } private void publishAssignEvent(final Long distId, final SoftwareModule softwareModule) { if (manageDistUIState.getLastSelectedDistribution().map(distId::equals).orElse(false)) { - eventBus.publish(this, + getEventBus().publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.ASSIGN_SOFTWARE_MODULE, softwareModule)); } } @@ -313,11 +305,56 @@ public class DistributionSetTable extends AbstractNamedVersionTable softwareModules) { - LOG.debug("Adding a log to check if distributionSetIdName is null : {} ", distributionSetIdName); - manageDistUIState.getAssignedList().put(distributionSetIdName, softwareModules); - eventBus.publish(this, DistributionsUIEvent.UPDATE_COUNT); + private void openConfirmationWindowForAssignment(final String distributionNameToAssign, + final SoftwareModuleIdName[] softwareModules) { + final String confirmQuestion = createConfirmationMessageForAssignment(distributionNameToAssign, + softwareModules); + final ConfirmationDialog confirmDialog = createConfirmationWindowForAssignment(confirmQuestion); + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + private ConfirmationDialog createConfirmationWindowForAssignment(final String confirmQuestion) { + return new ConfirmationDialog(getI18n().getMessage(CAPTION_ENTITY_ASSIGN_ACTION_CONFIRMBOX), confirmQuestion, + getI18n().getMessage(SPUIDefinitions.BUTTON_OK), getI18n().getMessage(SPUIDefinitions.BUTTON_CANCEL), + ok -> { + if (ok) { + saveAllAssignments(); + } else { + manageDistUIState.getAssignedList().clear(); + manageDistUIState.getConsolidatedDistSoftwareList().clear(); + } + }, UIComponentIdProvider.SOFT_MODULE_TO_DIST_ASSIGNMENT_CONFIRM_ID); + } + + private String createConfirmationMessageForAssignment(final String distributionNameToAssign, + final SoftwareModuleIdName[] softwareModules) { + if (softwareModules.length == 1) { + return getI18n().getMessage(MESSAGE_CONFIRM_ASSIGN_ENTITY, distributionNameToAssign, "software module", + softwareModules[0].getName()); + } else { + return getI18n().getMessage(MESSAGE_CONFIRM_ASSIGN_MULTIPLE_ENTITIES, softwareModules.length, + "software modules", distributionNameToAssign); + } + } + + private void saveAllAssignments() { + manageDistUIState.getAssignedList().forEach((distIdName, softIdNameSet) -> { + final List softIds = softIdNameSet.stream().map(softIdName -> softIdName.getId()) + .collect(Collectors.toList()); + distributionSetManagement.assignSoftwareModules(distIdName.getId(), softIds); + }); + + int count = 0; + for (final Entry> entry : manageDistUIState + .getAssignedList().entrySet()) { + count += entry.getValue().size(); + } + + getNotification().displaySuccess(getI18n().getMessage("message.software.assignment", count)); + manageDistUIState.getAssignedList().clear(); + manageDistUIState.getConsolidatedDistSoftwareList().clear(); + getEventBus().publish(this, SaveActionWindowEvent.SAVED_ASSIGNMENTS); } private boolean validSoftwareModule(final Long distId, final SoftwareModule sm) { @@ -330,8 +367,8 @@ public class DistributionSetTable extends AbstractNamedVersionTable 0) { /* Distribution is already assigned */ - notification.displayValidationError(i18n.getMessage("message.dist.inuse", + getNotification().displayValidationError(getI18n().getMessage("message.dist.inuse", HawkbitCommonUtil.concatStrings(":", ds.getName(), ds.getVersion()))); return false; } if (ds.getModules().contains(sm)) { /* Already has software module */ - notification.displayValidationError(i18n.getMessage("message.software.dist.already.assigned", + getNotification().displayValidationError(getI18n().getMessage("message.software.dist.already.assigned", HawkbitCommonUtil.concatStrings(":", sm.getName(), sm.getVersion()), HawkbitCommonUtil.concatStrings(":", ds.getName(), ds.getVersion()))); return false; @@ -355,7 +392,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable swModuleIdNames = entry.getValue(); for (final SoftwareModuleIdName swModuleIdName : swModuleIdNames) { if ((sm.getName().concat(":" + sm.getVersion())).equals(swModuleIdName.getName())) { - notification.displayValidationError(i18n.getMessage("message.software.already.dragged", + getNotification().displayValidationError(getI18n().getMessage("message.software.already.dragged", HawkbitCommonUtil.concatStrings(":", sm.getName(), sm.getVersion()))); return false; } @@ -449,54 +486,46 @@ public class DistributionSetTable extends AbstractNamedVersionTable showMetadataDetails((Long) itemId)); - return manageMetaDataBtn; - } - }); - } - - @Override - protected List getTableVisibleColumns() { - final List columnList = super.getTableVisibleColumns(); - if (!isMaximized()) { - columnList.add(new TableColumn(SPUILabelDefinitions.METADATA_ICON, "", 0.1F)); - } - return columnList; - } - - private Button createManageMetadataButton(final String nameVersionStr) { - final Button manageMetadataBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, - FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); - manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON); - manageMetadataBtn.setDescription(i18n.getMessage("tooltip.metadata.icon")); - return manageMetadataBtn; - } - - private void showMetadataDetails(final Long itemId) { - distributionSetManagement.getWithDetails(itemId) - .ifPresent(ds -> UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null))); - } - - private String getNameAndVerion(final Object itemId) { - final Item item = getItem(itemId); - final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); - final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); - return name + "." + version; - } - private void updateDistributionInTable(final DistributionSet editedDs) { final Item item = getContainerDataSource().getItem(editedDs.getId()); updateEntity(editedDs, item); } + @Override + protected void handleOkDelete(final List entitiesToDelete) { + distributionSetManagement.delete(entitiesToDelete); + getEventBus().publish(this, new DistributionTableEvent(BaseEntityEventType.REMOVE_ENTITY, entitiesToDelete)); + getNotification().displaySuccess(getI18n().getMessage("message.delete.success", + entitiesToDelete.size() + " " + getI18n().getMessage("distribution.details.header") + "(s)")); + + manageDistUIState.getSelectedDistributions().clear(); + getEventBus().publish(this, SaveActionWindowEvent.DELETED_DISTRIBUTIONS); + } + + @Override + protected String getEntityType() { + return getI18n().getMessage("distribution.details.header"); + } + + @Override + protected Set getSelectedEntities() { + return manageDistUIState.getSelectedDistributions(); + } + + @Override + protected String getEntityId(final Object itemId) { + final String entityId = String.valueOf( + getContainerDataSource().getItem(itemId).getItemProperty(SPUILabelDefinitions.DIST_ID).getValue()); + return "distributionSet." + entityId; + } + + @Override + protected String getDeletedEntityName(final Long entityId) { + final Optional distribution = distributionSetManagement.get(entityId); + if (distribution.isPresent()) { + return distribution.get().getName(); + } + return ""; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java index 9dcd64e56..077af359b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java @@ -43,17 +43,17 @@ public class DistributionSetTableLayout extends AbstractTableLayout { - private static final long serialVersionUID = 5176481314404662215L; + private static final long serialVersionUID = 1L; + private Sort sort = new Sort(Direction.ASC, "id"); private String searchText; private transient DistributionSetManagement distributionSetManagement; private transient Page firstPageDistributionSets; - private DistributionSetType distributionSetType; + private transient DistributionSetType distributionSetType; private Boolean dsComplete; /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DSDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DSDeleteActionsLayout.java deleted file mode 100644 index 63d22a0f9..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DSDeleteActionsLayout.java +++ /dev/null @@ -1,316 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.footer; - -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.SystemManagement; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; -import org.eclipse.hawkbit.ui.common.entity.SoftwareModuleIdName; -import org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout; -import org.eclipse.hawkbit.ui.common.table.AbstractTable; -import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; -import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; -import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.ui.Component; -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.TableTransferable; -import com.vaadin.ui.UI; - -/** - * Distributions footer layout implementation. - */ -public class DSDeleteActionsLayout extends AbstractDeleteActionsLayout { - - private static final long serialVersionUID = 3494052985006132714L; - - private final transient SystemManagement systemManagement; - private final transient DistributionSetManagement distributionSetManagement; - - private final ManageDistUIState manageDistUIState; - - private final DistributionsConfirmationWindowLayout distConfirmationWindowLayout; - - private final DistributionsViewClientCriterion distributionsViewClientCriterion; - - public DSDeleteActionsLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, - final UIEventBus eventBus, final UINotification notification, final SystemManagement systemManagement, - final ManageDistUIState manageDistUIState, - final DistributionsViewClientCriterion distributionsViewClientCriterion, - final DistributionSetManagement distributionSetManagement, - final DistributionSetTypeManagement distributionSetTypeManagement, - final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement) { - super(i18n, permChecker, eventBus, notification); - this.systemManagement = systemManagement; - this.manageDistUIState = manageDistUIState; - this.distConfirmationWindowLayout = new DistributionsConfirmationWindowLayout(i18n, eventBus, - distributionSetManagement, distributionSetTypeManagement, softwareModuleManagement, - softwareModuleTypeManagement, manageDistUIState); - this.distributionsViewClientCriterion = distributionsViewClientCriterion; - this.distributionSetManagement = distributionSetManagement; - init(); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final SaveActionWindowEvent event) { - if (event != null) { - UI.getCurrent().access(() -> { - if (!hasUnsavedActions()) { - closeUnsavedActionsWindow(); - final String message = distConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - } - updateDSActionCount(); - }); - } - } - - @Override - protected boolean hasDeletePermission() { - return permChecker.hasDeleteRepositoryPermission(); - - } - - @Override - protected boolean hasUpdatePermission() { - - return permChecker.hasUpdateRepositoryPermission(); - } - - @Override - protected String getDeleteAreaLabel() { - return i18n.getMessage("label.components.drop.area"); - } - - @Override - protected String getDeleteAreaId() { - - return UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID; - } - - @Override - protected AcceptCriterion getDeleteLayoutAcceptCriteria() { - return distributionsViewClientCriterion; - } - - @Override - protected void processDroppedComponent(final DragAndDropEvent event) { - final Component sourceComponent = event.getTransferable().getSourceComponent(); - if (sourceComponent instanceof Table) { - final Table sourceTable = (Table) event.getTransferable().getSourceComponent(); - if (isDistributionTable(sourceTable)) { - addInDeleteDistributionList(sourceTable, (TableTransferable) event.getTransferable()); - updateDSActionCount(); - } else if (isSoftwareModuleTable(sourceTable)) { - addToSWDeleteList(sourceTable, (TableTransferable) event.getTransferable()); - updateDSActionCount(); - } - } else if (sourceComponent.getId().startsWith(SPUIDefinitions.DISTRIBUTION_SET_TYPE_ID_PREFIXS)) { - processDeleteDitSetType(sourceComponent.getId()); - } else if (sourceComponent.getId().startsWith(SPUIDefinitions.SOFTWARE_MODULE_TAG_ID_PREFIXS)) { - processDeleteSWType(sourceComponent.getId()); - - } - - } - - private void processDeleteDitSetType(final String distTypeId) { - final String distTypeName = HawkbitCommonUtil.removePrefix(distTypeId, - SPUIDefinitions.DISTRIBUTION_SET_TYPE_ID_PREFIXS); - if (isDsTypeSelected(distTypeName)) { - notification.displayValidationError( - i18n.getMessage("message.dist.type.check.delete", new Object[] { distTypeName })); - } else if (isDefaultDsType(distTypeName)) { - notification.displayValidationError(i18n.getMessage("message.cannot.delete.default.dstype")); - } else { - manageDistUIState.getSelectedDeleteDistSetTypes().add(distTypeName); - updateDSActionCount(); - } - } - - /** - * Check if distribution set type is selected. - * - * @param distTypeName - * @return true if ds type is selected - */ - private boolean isDsTypeSelected(final String distTypeName) { - return null != manageDistUIState.getManageDistFilters().getClickedDistSetType() && manageDistUIState - .getManageDistFilters().getClickedDistSetType().getName().equalsIgnoreCase(distTypeName); - } - - private void processDeleteSWType(final String swTypeId) { - final String swModuleTypeName = HawkbitCommonUtil.removePrefix(swTypeId, - SPUIDefinitions.SOFTWARE_MODULE_TAG_ID_PREFIXS); - - if (manageDistUIState.getSoftwareModuleFilters().getSoftwareModuleType() - .map(type -> type.getName().equalsIgnoreCase(swModuleTypeName)).orElse(false)) { - notification.displayValidationError( - i18n.getMessage("message.swmodule.type.check.delete", new Object[] { swModuleTypeName })); - } else { - manageDistUIState.getSelectedDeleteSWModuleTypes().add(swModuleTypeName); - updateDSActionCount(); - } - - } - - private void addInDeleteDistributionList(final Table sourceTable, final TableTransferable transferable) { - final AbstractTable table = (AbstractTable) sourceTable; - final Set ids = table.getDeletedEntityByTransferable(transferable); - final List findDistributionSetAllById = distributionSetManagement - .get(ids); - - if (findDistributionSetAllById.isEmpty()) { - notification.displayWarning(i18n.getMessage("distributionsets.not.exists")); - return; - } - - final Set distributionIdNameSet = findDistributionSetAllById.stream() - .map(DistributionSetIdName::new).collect(Collectors.toSet()); - - final int existingDeletedDistributionsSize = manageDistUIState.getDeletedDistributionList().size(); - manageDistUIState.getDeletedDistributionList().addAll(distributionIdNameSet); - final int newDeletedDistributionsSize = manageDistUIState.getDeletedDistributionList().size(); - if (newDeletedDistributionsSize == existingDeletedDistributionsSize) { - notification.displayValidationError(i18n.getMessage("message.targets.already.deleted")); - } else if (newDeletedDistributionsSize - existingDeletedDistributionsSize != distributionIdNameSet.size()) { - notification.displayValidationError(i18n.getMessage("message.dist.deleted.pending")); - } - - } - - private void addToSWDeleteList(final Table sourceTable, final TableTransferable transferable) { - final AbstractTable swTable = (AbstractTable) sourceTable; - final Set swModuleIdNameSet = swTable.getDeletedEntityByTransferable(transferable); - - swModuleIdNameSet.forEach(id -> { - final String swModuleName = (String) sourceTable.getContainerDataSource().getItem(id) - .getItemProperty(SPUILabelDefinitions.NAME_VERSION).getValue(); - manageDistUIState.getDeleteSofwareModulesList().put(id, swModuleName); - }); - } - - /** - * Update the software module delete count. - */ - private void updateDSActionCount() { - int count = manageDistUIState.getSelectedDeleteDistSetTypes().size() - + manageDistUIState.getSelectedDeleteSWModuleTypes().size() - + manageDistUIState.getDeleteSofwareModulesList().size() - + manageDistUIState.getDeletedDistributionList().size(); - - for (final Entry> mapEntry : manageDistUIState - .getAssignedList().entrySet()) { - count += manageDistUIState.getAssignedList().get(mapEntry.getKey()).size(); - } - updateActionsCount(count); - } - - /** - * DistributionsUIEvent. - * - * @param event - * as instance of {@link DistributionsUIEvent} - */ - @EventBusListenerMethod(scope = EventScope.UI) - public void onEvent(final DistributionsUIEvent event) { - if (event == DistributionsUIEvent.UPDATE_COUNT) { - updateDSActionCount(); - } - - } - - private boolean isDistributionTable(final Component source) { - return UIComponentIdProvider.DIST_TABLE_ID.equals(source.getId()); - } - - private boolean isSoftwareModuleTable(final Component source) { - return UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE.equals(source.getId()); - } - - @Override - protected void restoreActionCount() { - updateDSActionCount(); - - } - - @Override - protected void unsavedActionsWindowClosed() { - final String message = distConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - - } - - @Override - protected Component getUnsavedActionsWindowContent() { - distConfirmationWindowLayout.initialize(); - return distConfirmationWindowLayout; - } - - @Override - protected boolean hasUnsavedActions() { - boolean unSavedActionsTypes = false; - boolean unSavedActionsTables = false; - if (!manageDistUIState.getSelectedDeleteDistSetTypes().isEmpty() - || !manageDistUIState.getSelectedDeleteSWModuleTypes().isEmpty()) { - unSavedActionsTypes = true; - } else if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty() - || !manageDistUIState.getDeletedDistributionList().isEmpty() - || !manageDistUIState.getAssignedList().isEmpty()) { - unSavedActionsTables = true; - } - - return unSavedActionsTables || unSavedActionsTypes; - } - - private DistributionSetType getCurrentDistributionSetType() { - return systemManagement.getTenantMetadata().getDefaultDsType(); - } - - /** - * Check if the distribution set type is default. - * - * @param dsTypeName - * distribution set name - * @return true if distribution set type is set default in configuration - */ - private boolean isDefaultDsType(final String dsTypeName) { - return getCurrentDistributionSetType() != null && getCurrentDistributionSetType().getName().equals(dsTypeName); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DistributionsConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DistributionsConfirmationWindowLayout.java deleted file mode 100644 index 9a782ede4..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/footer/DistributionsConfirmationWindowLayout.java +++ /dev/null @@ -1,660 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.footer; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; -import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; -import org.eclipse.hawkbit.ui.common.entity.SoftwareModuleIdName; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.util.CollectionUtils; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.google.common.collect.Maps; -import com.vaadin.data.Container; -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.Table.Align; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Abstract layout of confirm actions window. - * - */ -public class DistributionsConfirmationWindowLayout extends AbstractConfirmationWindowLayout { - - private static final long serialVersionUID = 3641621131320823058L; - - private static final String SW_MODULE_NAME_MSG = "SW MOdule Name"; - - private static final String SW_DISCARD_CHGS = "DiscardChanges"; - - private static final String SW_MODULE_TYPE_NAME = "SoftwareModuleTypeName"; - - private static final String DISCARD = "Discard"; - - private static final String DIST_NAME = "DistributionName"; - - private static final String SOFTWARE_MODULE_NAME = "SoftwareModuleName"; - - private static final String DIST_ID_NAME = "DistributionIdName"; - - private static final String DIST_SET_NAME = "DistributionSetTypeName"; - - private static final String SOFTWARE_MODULE_ID_NAME = "SoftwareModuleIdName"; - - private ConfirmationTab assignmnetTab; - - private final transient DistributionSetManagement distributionSetManagement; - - private final transient DistributionSetTypeManagement distributionSetTypeManagement; - - private final transient SoftwareModuleManagement softwareModuleManagement; - - private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; - - private final ManageDistUIState manageDistUIState; - - DistributionsConfirmationWindowLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, - final DistributionSetManagement dsManagement, - final DistributionSetTypeManagement distributionSetTypeManagement, - final SoftwareModuleManagement softwareModuleManagement, - final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final ManageDistUIState manageDistUIState) { - super(i18n, eventBus); - this.distributionSetManagement = dsManagement; - this.distributionSetTypeManagement = distributionSetTypeManagement; - this.softwareModuleTypeManagement = softwareModuleTypeManagement; - this.softwareModuleManagement = softwareModuleManagement; - this.manageDistUIState = manageDistUIState; - } - - @Override - protected Map getConfirmationTabs() { - final Map tabs = Maps.newHashMapWithExpectedSize(5); - /* Create tab for SW Modules delete */ - if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab()); - } - - /* Create tab for SW Module Type delete */ - if (!manageDistUIState.getSelectedDeleteSWModuleTypes().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.sw.module.type.accordion.tab"), - createSMtypeDeleteConfirmationTab()); - } - - /* Create tab for Distributions delete */ - if (!manageDistUIState.getDeletedDistributionList().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.dist.accordion.tab"), createDistDeleteConfirmationTab()); - } - - /* Create tab for Distribution Set Types delete */ - if (!manageDistUIState.getSelectedDeleteDistSetTypes().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.dist.set.type.accordion.tab"), - createDistSetTypeDeleteConfirmationTab()); - } - - /* Create tab for Assign Software Module */ - if (!manageDistUIState.getAssignedList().isEmpty()) { - tabs.put(i18n.getMessage("caption.assign.dist.accordion.tab"), createAssignSWModuleConfirmationTab()); - } - - return tabs; - - } - - private ConfirmationTab createSMDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.SW_DELETE_ALL); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteSMAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().addClickListener(event -> discardSMAll(tab)); - - /* Add items container to the table. */ - tab.getTable().setContainerDataSource(getSWModuleTableContainer()); - - /* Add the discard action column */ - tab.getTable().addGeneratedColumn(SW_DISCARD_CHGS, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardSoftwareDelete(event, itemId, tab); - return createDiscardButton(itemId, clickListener); - }); - - tab.getTable().setVisibleColumns(SW_MODULE_NAME_MSG, SW_DISCARD_CHGS); - tab.getTable().setColumnHeaders(i18n.getMessage("upload.swModuleTable.header"), - i18n.getMessage("header.second.deletetarget.table")); - - tab.getTable().setColumnExpandRatio(SW_MODULE_NAME_MSG, SPUIDefinitions.TARGET_DISTRIBUTION_COLUMN_WIDTH); - tab.getTable().setColumnExpandRatio(SW_DISCARD_CHGS, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(SW_DISCARD_CHGS, Align.CENTER); - return tab; - } - - private void deleteSMAll(final ConfirmationTab tab) { - final Set swmoduleIds = manageDistUIState.getDeleteSofwareModulesList().keySet(); - - if (manageDistUIState.getAssignedList() == null || manageDistUIState.getAssignedList().isEmpty()) { - removeAssignedSoftwareModules(); - } - - softwareModuleManagement.delete(swmoduleIds); - eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.REMOVE_ENTITY, swmoduleIds)); - - addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.swModule.deleted", swmoduleIds.size())); - manageDistUIState.getDeleteSofwareModulesList().clear(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.software.delete.success")); - eventBus.publish(this, SaveActionWindowEvent.DELETE_ALL_SOFWARE); - } - - private void removeAssignedSoftwareModules() { - for (final Entry> entryAssignSM : manageDistUIState - .getAssignedList().entrySet()) { - for (final Entry entryDeleteSM : manageDistUIState.getDeleteSofwareModulesList().entrySet()) { - final SoftwareModuleIdName smIdName = new SoftwareModuleIdName(entryDeleteSM.getKey(), - entryDeleteSM.getValue()); - if (entryAssignSM.getValue().contains(smIdName)) { - entryAssignSM.getValue().remove(smIdName); - assignmnetTab.getTable().removeItem(HawkbitCommonUtil.concatStrings("|||", - entryAssignSM.getKey().getId().toString(), smIdName.getId().toString())); - } - - if (entryAssignSM.getValue().isEmpty()) { - manageDistUIState.getAssignedList().remove(entryAssignSM.getKey()); - } - } - } - } - - private void discardSMAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - manageDistUIState.getDeleteSofwareModulesList().clear(); - setActionMessage(i18n.getMessage("message.software.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_SOFTWARE); - } - - /** - * Get SWModule table container. - * - * @return IndexedContainer - */ - @SuppressWarnings("unchecked") - private IndexedContainer getSWModuleTableContainer() { - final IndexedContainer swcontactContainer = new IndexedContainer(); - swcontactContainer.addContainerProperty("SWModuleId", String.class, ""); - swcontactContainer.addContainerProperty(SW_MODULE_NAME_MSG, String.class, ""); - for (final Long swModuleID : manageDistUIState.getDeleteSofwareModulesList().keySet()) { - final Item item = swcontactContainer.addItem(swModuleID); - item.getItemProperty("SWModuleId").setValue(swModuleID.toString()); - item.getItemProperty(SW_MODULE_NAME_MSG) - .setValue(manageDistUIState.getDeleteSofwareModulesList().get(swModuleID)); - } - return swcontactContainer; - } - - private void discardSoftwareDelete(final Button.ClickEvent event, final Object itemId, final ConfirmationTab tab) { - final Long swmoduleId = (Long) ((Button) event.getComponent()).getData(); - if (null != manageDistUIState.getDeleteSofwareModulesList() - && !manageDistUIState.getDeleteSofwareModulesList().isEmpty() - && manageDistUIState.getDeleteSofwareModulesList().containsKey(swmoduleId)) { - manageDistUIState.getDeleteSofwareModulesList().remove(swmoduleId); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_SOFTWARE); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DELETE_SOFTWARE); - } - } - - private ConfirmationTab createSMtypeDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.SAVE_DELETE_SW_MODULE_TYPE); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteSMtypeAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().setId(UIComponentIdProvider.DISCARD_SW_MODULE_TYPE); - tab.getDiscardAll().addClickListener(event -> discardSMtypeAll(tab)); - - // Add items container to the table. - tab.getTable().setContainerDataSource(getSWModuleTypeTableContainer()); - - // Add the discard action column - tab.getTable().addGeneratedColumn(DISCARD, (source, itemId, columnId) -> { - final StringBuilder style = new StringBuilder(ValoTheme.BUTTON_TINY); - style.append(' '); - style.append(SPUIStyleDefinitions.REDICON); - final Button deleteIcon = SPUIComponentProvider.getButton("", "", SPUILabelDefinitions.DISCARD, - style.toString(), true, FontAwesome.REPLY, SPUIButtonStyleSmallNoBorder.class); - deleteIcon.setData(itemId); - deleteIcon.setImmediate(true); - deleteIcon.addClickListener(event -> discardSoftwareTypeDelete( - (String) ((Button) event.getComponent()).getData(), itemId, tab)); - return deleteIcon; - }); - - tab.getTable().setVisibleColumns(SW_MODULE_TYPE_NAME, DISCARD); - tab.getTable().setColumnHeaders(i18n.getMessage("header.first.delete.swmodule.type.table"), - i18n.getMessage("header.second.delete.swmodule.type.table")); - - tab.getTable().setColumnExpandRatio(SW_MODULE_TYPE_NAME, 2); - tab.getTable().setColumnExpandRatio(SW_DISCARD_CHGS, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(SW_DISCARD_CHGS, Align.CENTER); - return tab; - } - - private void deleteSMtypeAll(final ConfirmationTab tab) { - final int deleteSWModuleTypeCount = manageDistUIState.getSelectedDeleteSWModuleTypes().size(); - for (final String swModuleTypeName : manageDistUIState.getSelectedDeleteSWModuleTypes()) { - - softwareModuleTypeManagement.getByName(swModuleTypeName).map(SoftwareModuleType::getId) - .ifPresent(softwareModuleTypeManagement::delete); - } - addToConsolitatedMsg(FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.sw.module.type.delete", new Object[] { deleteSWModuleTypeCount })); - manageDistUIState.getSelectedDeleteSWModuleTypes().clear(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.software.type.delete.success")); - eventBus.publish(this, SaveActionWindowEvent.SAVED_DELETE_SW_MODULE_TYPES); - } - - private void discardSMtypeAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - manageDistUIState.getSelectedDeleteSWModuleTypes().clear(); - setActionMessage(i18n.getMessage("message.software.type.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DELETE_SW_MODULE_TYPES); - } - - private Container getSWModuleTypeTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(SW_MODULE_TYPE_NAME, String.class, ""); - - for (final String swModuleTypeName : manageDistUIState.getSelectedDeleteSWModuleTypes()) { - final Item saveTblitem = contactContainer.addItem(swModuleTypeName); - - saveTblitem.getItemProperty(SW_MODULE_TYPE_NAME).setValue(swModuleTypeName); - } - - return contactContainer; - } - - private void discardSoftwareTypeDelete(final String discardSWModuleType, final Object itemId, - final ConfirmationTab tab) { - if (!CollectionUtils.isEmpty(manageDistUIState.getSelectedDeleteSWModuleTypes()) - && manageDistUIState.getSelectedDeleteSWModuleTypes().contains(discardSWModuleType)) { - manageDistUIState.getSelectedDeleteSWModuleTypes().remove(discardSWModuleType); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DELETE_SW_MODULE_TYPES); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DELETE_SW_MODULE_TYPE); - } - } - - /* for Distributions */ - private ConfirmationTab createDistDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.DIST_DELETE_ALL); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteDistAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().addClickListener(event -> discardDistAll(tab)); - - /* Add items container to the table. */ - tab.getTable().setContainerDataSource(getDistTableContainer()); - - /* Add the discard action column */ - tab.getTable().addGeneratedColumn(DISCARD, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardDistDelete(event, itemId, tab); - return createDiscardButton(itemId, clickListener); - - }); - - tab.getTable().setVisibleColumns(DIST_NAME, DISCARD); - tab.getTable().setColumnHeaders(i18n.getMessage("header.one.deletedist.table"), - i18n.getMessage("header.second.deletedist.table")); - - tab.getTable().setColumnExpandRatio(DIST_NAME, SPUIDefinitions.TARGET_DISTRIBUTION_COLUMN_WIDTH); - tab.getTable().setColumnExpandRatio(DISCARD, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(DISCARD, Align.CENTER); - return tab; - } - - /* Delete Distributions. */ - private void deleteDistAll(final ConfirmationTab tab) { - final Long[] deletedIds = manageDistUIState.getDeletedDistributionList().stream().map(idName -> idName.getId()) - .toArray(Long[]::new); - if (manageDistUIState.getAssignedList() != null && !manageDistUIState.getAssignedList().isEmpty()) { - manageDistUIState.getDeletedDistributionList().forEach(distSetName -> { - if (manageDistUIState.getAssignedList().containsKey(distSetName)) { - manageDistUIState.getAssignedList().remove(distSetName); - } - }); - } - - distributionSetManagement.delete(Arrays.asList(deletedIds)); - eventBus.publish(this, - new DistributionTableEvent(BaseEntityEventType.REMOVE_ENTITY, Arrays.asList(deletedIds))); - - addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.dist.deleted", deletedIds.length)); - - manageDistUIState.getDeletedDistributionList() - .forEach(deletedIdname -> manageDistUIState.getAssignedList().remove(deletedIdname)); - removeCurrentTab(tab); - manageDistUIState.getDeletedDistributionList().clear(); - eventBus.publish(this, SaveActionWindowEvent.DELETED_DISTRIBUTIONS); - } - - private void discardDistAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - manageDistUIState.getDeletedDistributionList().clear(); - setActionMessage(i18n.getMessage("message.dist.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DISTRIBUTIONS); - - } - - private IndexedContainer getDistTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(DIST_ID_NAME, DistributionSetIdName.class, ""); - contactContainer.addContainerProperty(DIST_NAME, String.class, ""); - for (final DistributionSetIdName distIdName : manageDistUIState.getDeletedDistributionList()) { - final Item item = contactContainer.addItem(distIdName); - item.getItemProperty(DIST_NAME).setValue(distIdName.getName().concat(":" + distIdName.getVersion())); - } - return contactContainer; - - } - - private void discardDistDelete(final Button.ClickEvent event, final Object itemId, final ConfirmationTab tab) { - - final DistributionSetIdName distId = (DistributionSetIdName) ((Button) event.getComponent()).getData(); - if (!CollectionUtils.isEmpty(manageDistUIState.getDeletedDistributionList()) - && manageDistUIState.getDeletedDistributionList().contains(distId)) { - manageDistUIState.getDeletedDistributionList().remove(distId); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DISTRIBUTIONS); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DEL_DISTRIBUTION); - } - } - - /* For Distribution set Type */ - - private ConfirmationTab createDistSetTypeDeleteConfirmationTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - tab.getConfirmAll().setId(UIComponentIdProvider.SAVE_DELETE_DIST_SET_TYPE); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteDistSetTypeAll(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().setId(UIComponentIdProvider.DISCARD_DIST_SET_TYPE); - tab.getDiscardAll().addClickListener(event -> discardDistSetTypeAll(tab)); - - // Add items container to the table. - tab.getTable().setContainerDataSource(getDistSetTypeTableContainer()); - - // Add the discard action column - tab.getTable().addGeneratedColumn(DISCARD, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardDistTypeDelete( - (String) ((Button) event.getComponent()).getData(), itemId, tab); - return createDiscardButton(itemId, clickListener); - - }); - - tab.getTable().setVisibleColumns(DIST_SET_NAME, DISCARD); - tab.getTable().setColumnHeaders(i18n.getMessage("header.first.delete.dist.type.table"), - i18n.getMessage("header.second.delete.dist.type.table")); - - tab.getTable().setColumnExpandRatio(DIST_SET_NAME, 2); - tab.getTable().setColumnExpandRatio(DISCARD, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(DISCARD, Align.CENTER); - return tab; - } - - private void deleteDistSetTypeAll(final ConfirmationTab tab) { - - final int deleteDistTypeCount = manageDistUIState.getSelectedDeleteDistSetTypes().size(); - manageDistUIState.getSelectedDeleteDistSetTypes().stream() - .map(deleteDistTypeName -> distributionSetTypeManagement - .getByName(deleteDistTypeName).get().getId()) - .forEach(distributionSetTypeManagement::delete); - - addToConsolitatedMsg(FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.dist.type.delete", new Object[] { deleteDistTypeCount })); - manageDistUIState.getSelectedDeleteDistSetTypes().clear(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.dist.set.type.deleted.success")); - eventBus.publish(this, SaveActionWindowEvent.SAVED_DELETE_DIST_SET_TYPES); - } - - private void discardDistSetTypeAll(final ConfirmationTab tab) { - removeCurrentTab(tab); - manageDistUIState.getSelectedDeleteDistSetTypes().clear(); - setActionMessage(i18n.getMessage("message.dist.type.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DELETE_DIST_SET_TYPES); - } - - private IndexedContainer getDistSetTypeTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(DIST_SET_NAME, String.class, ""); - - for (final String distTypeMName : manageDistUIState.getSelectedDeleteDistSetTypes()) { - final Item saveTblitem = contactContainer.addItem(distTypeMName); - - saveTblitem.getItemProperty(DIST_SET_NAME).setValue(distTypeMName); - } - - return contactContainer; - - } - - private void discardDistTypeDelete(final String discardDSType, final Object itemId, final ConfirmationTab tab) { - - if (!CollectionUtils.isEmpty(manageDistUIState.getSelectedDeleteDistSetTypes()) - && manageDistUIState.getSelectedDeleteDistSetTypes().contains(discardDSType)) { - manageDistUIState.getSelectedDeleteDistSetTypes().remove(discardDSType); - } - tab.getTable().getContainerDataSource().removeItem(itemId); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DELETE_DIST_SET_TYPES); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DELETE_DIST_SET_TYPE); - } - } - - /* For Assign software modules */ - private ConfirmationTab createAssignSWModuleConfirmationTab() { - - assignmnetTab = new ConfirmationTab(); - - assignmnetTab.getConfirmAll().setId(UIComponentIdProvider.SAVE_ASSIGNMENT); - assignmnetTab.getConfirmAll().setIcon(FontAwesome.SAVE); - assignmnetTab.getConfirmAll().setCaption(i18n.getMessage("button.assign.all")); - assignmnetTab.getConfirmAll().addClickListener(event -> saveAllAssignments(assignmnetTab)); - - assignmnetTab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - assignmnetTab.getDiscardAll().setId(UIComponentIdProvider.DISCARD_ASSIGNMENT); - assignmnetTab.getDiscardAll().addClickListener(event -> discardAllSWAssignments(assignmnetTab)); - - // Add items container to the table. - assignmnetTab.getTable().setContainerDataSource(getSWAssignmentsTableContainer()); - - // Add the discard action column - assignmnetTab.getTable().addGeneratedColumn(DISCARD, (source, itemId, columnId) -> { - final StringBuilder style = new StringBuilder(ValoTheme.BUTTON_TINY); - style.append(' '); - style.append(SPUIStyleDefinitions.REDICON); - final Button deleteIcon = SPUIComponentProvider.getButton("", "", SPUILabelDefinitions.DISCARD, - style.toString(), true, FontAwesome.REPLY, SPUIButtonStyleSmallNoBorder.class); - deleteIcon.setData(itemId); - deleteIcon.setImmediate(true); - deleteIcon.addClickListener(event -> discardSWAssignment((String) ((Button) event.getComponent()).getData(), - itemId, assignmnetTab)); - return deleteIcon; - }); - - assignmnetTab.getTable().setVisibleColumns(DIST_NAME, SOFTWARE_MODULE_NAME, DISCARD); - assignmnetTab.getTable().setColumnHeaders(i18n.getMessage("header.dist.first.assignment.table"), - i18n.getMessage("header.dist.second.assignment.table"), - i18n.getMessage("header.third.assignment.table")); - - assignmnetTab.getTable().setColumnExpandRatio(DIST_NAME, 2); - assignmnetTab.getTable().setColumnExpandRatio(SOFTWARE_MODULE_NAME, 2); - assignmnetTab.getTable().setColumnExpandRatio(DISCARD, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - assignmnetTab.getTable().setColumnAlignment(DISCARD, Align.CENTER); - return assignmnetTab; - - } - - @SuppressWarnings("unchecked") - private IndexedContainer getSWAssignmentsTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(DIST_NAME, String.class, ""); - contactContainer.addContainerProperty(SOFTWARE_MODULE_NAME, String.class, ""); - contactContainer.addContainerProperty(DIST_ID_NAME, DistributionSetIdName.class, ""); - contactContainer.addContainerProperty(SOFTWARE_MODULE_ID_NAME, SoftwareModuleIdName.class, ""); - - final Map> assignedList = manageDistUIState - .getAssignedList(); - - assignedList.forEach((distIdname, softIdNameSet) -> softIdNameSet.forEach(softIdName -> { - final String itemId = HawkbitCommonUtil.concatStrings("|||", distIdname.getId().toString(), - softIdName.getId().toString()); - final Item saveTblitem = contactContainer.addItem(itemId); - - saveTblitem.getItemProperty(DIST_NAME).setValue(distIdname.getName().concat(":" + distIdname.getVersion())); - - saveTblitem.getItemProperty(SOFTWARE_MODULE_NAME).setValue(softIdName.getName()); - - saveTblitem.getItemProperty(DIST_ID_NAME).setValue(distIdname); - saveTblitem.getItemProperty(SOFTWARE_MODULE_ID_NAME).setValue(softIdName); - })); - return contactContainer; - } - - private void saveAllAssignments(final ConfirmationTab tab) { - manageDistUIState.getAssignedList().forEach((distIdName, softIdNameSet) -> { - final List softIds = softIdNameSet.stream().map(softIdName -> softIdName.getId()) - .collect(Collectors.toList()); - distributionSetManagement.assignSoftwareModules(distIdName.getId(), softIds); - - }); - - int count = 0; - for (final Entry> entry : manageDistUIState - .getAssignedList().entrySet()) { - count += entry.getValue().size(); - } - addToConsolitatedMsg(FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.software.assignment", new Object[] { count })); - manageDistUIState.getAssignedList().clear(); - manageDistUIState.getConsolidatedDistSoftwarewList().clear(); - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.SAVED_ASSIGNMENTS); - } - - private void discardAllSWAssignments(final ConfirmationTab tab) { - removeCurrentTab(tab); - manageDistUIState.getAssignedList().clear(); - manageDistUIState.getConsolidatedDistSoftwarewList().clear(); - setActionMessage(i18n.getMessage("message.assign.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS); - } - - private void discardSWAssignment(final String discardSW, final Object itemId, final ConfirmationTab tab) { - - final Item rowitem = tab.getTable().getContainerDataSource().getItem(discardSW); - final DistributionSetIdName discardDistIdName = (DistributionSetIdName) rowitem.getItemProperty(DIST_ID_NAME) - .getValue(); - final SoftwareModuleIdName discardSoftIdName = (SoftwareModuleIdName) rowitem - .getItemProperty(SOFTWARE_MODULE_ID_NAME).getValue(); - - final Set softIdNameSet = manageDistUIState.getAssignedList().get(discardDistIdName); - manageDistUIState.getAssignedList().get(discardDistIdName).remove(discardSoftIdName); - softIdNameSet.remove(discardSoftIdName); - tab.getTable().getContainerDataSource().removeItem(itemId); - if (softIdNameSet.isEmpty()) { - manageDistUIState.getAssignedList().remove(discardDistIdName); - } - final Map> map = manageDistUIState.getConsolidatedDistSoftwarewList() - .get(discardDistIdName); - map.keySet().forEach(typeId -> map.get(typeId).remove(discardSoftIdName)); - - final int assigCount = tab.getTable().getContainerDataSource().size(); - if (0 == assigCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ASSIGNMENT); - } - - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEventDiscard(final SaveActionWindowEvent saveActionWindowEvent) { - if (saveActionWindowEvent == SaveActionWindowEvent.DELETE_ALL_SOFWARE) { - getSWAssignmentsTableContainer(); - } - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java index da4f9a730..c6b9902d5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java @@ -11,13 +11,25 @@ package org.eclipse.hawkbit.ui.distributions.smtable; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractSoftwareModuleDetails; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; +import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.window.WindowMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.UI; +import com.vaadin.ui.Window; + /** * Implementation of software module details block using generic abstract * details style . @@ -28,14 +40,19 @@ public class SwModuleDetails extends AbstractSoftwareModuleDetails { private final ManageDistUIState manageDistUIState; + private final ArtifactDetailsLayout artifactDetailsLayout; + + private Button artifactDetailsButton; + SwModuleDetails(final VaadinMessageSource i18n, final UIEventBus eventBus, final SpPermissionChecker permissionChecker, final SoftwareModuleAddUpdateWindow softwareModuleAddUpdateWindow, final ManageDistUIState manageDistUIState, final SoftwareModuleManagement softwareManagement, - final SwMetadataPopupLayout swMetadataPopupLayout) { + final SwMetadataPopupLayout swMetadataPopupLayout, final ArtifactDetailsLayout artifactDetailsLayout) { super(i18n, eventBus, permissionChecker, null, softwareManagement, swMetadataPopupLayout, softwareModuleAddUpdateWindow); this.manageDistUIState = manageDistUIState; + this.artifactDetailsLayout = artifactDetailsLayout; restoreState(); } @@ -55,4 +72,65 @@ public class SwModuleDetails extends AbstractSoftwareModuleDetails { manageDistUIState.getLastSelectedSoftwareModule().orElse(null)); } + @Override + protected void createComponents() { + super.createComponents(); + createShowArtifactDetailsButton(); + } + + @Override + protected void buildLayout() { + super.buildLayout(); + getNameEditLayout().addComponent(artifactDetailsButton); + getNameEditLayout().setComponentAlignment(artifactDetailsButton, Alignment.TOP_RIGHT); + } + + private Button createShowArtifactDetailsButton() { + artifactDetailsButton = SPUIComponentProvider.getButton("", "", "", null, false, FontAwesome.FILE_O, + SPUIButtonStyleNoBorder.class); + artifactDetailsButton.setDescription(getI18n().getMessage("tooltip.artifact.icon")); + artifactDetailsButton.addClickListener(event -> showArtifactDetailsWindow(getSelectedBaseEntity())); + return artifactDetailsButton; + } + + private void showArtifactDetailsWindow(final SoftwareModule softwareModule) { + final Window artifactDtlsWindow = new Window(); + artifactDtlsWindow.setCaption(HawkbitCommonUtil + .getArtifactoryDetailsLabelId(softwareModule.getName() + "." + softwareModule.getVersion())); + artifactDtlsWindow.setCaptionAsHtml(true); + artifactDtlsWindow.setClosable(true); + artifactDtlsWindow.setResizable(true); + artifactDtlsWindow.setImmediate(true); + artifactDtlsWindow.setWindowMode(WindowMode.NORMAL); + artifactDtlsWindow.setModal(true); + artifactDtlsWindow.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); + + artifactDetailsLayout.setFullWindowMode(false); + artifactDetailsLayout.populateArtifactDetails(softwareModule); + artifactDetailsLayout.getArtifactDetailsTable().setWidth(700, Unit.PIXELS); + artifactDetailsLayout.getArtifactDetailsTable().setHeight(500, Unit.PIXELS); + artifactDtlsWindow.setContent(artifactDetailsLayout.getArtifactDetailsTable()); + + artifactDtlsWindow.addWindowModeChangeListener(event -> { + if (event.getWindowMode() == WindowMode.MAXIMIZED) { + artifactDtlsWindow.setSizeFull(); + artifactDetailsLayout.setFullWindowMode(true); + artifactDetailsLayout.createMaxArtifactDetailsTable(); + artifactDetailsLayout.getMaxArtifactDetailsTable().setWidth(100, Unit.PERCENTAGE); + artifactDetailsLayout.getMaxArtifactDetailsTable().setHeight(100, Unit.PERCENTAGE); + artifactDtlsWindow.setContent(artifactDetailsLayout.getMaxArtifactDetailsTable()); + } else { + artifactDtlsWindow.setSizeUndefined(); + artifactDtlsWindow.setContent(artifactDetailsLayout.getArtifactDetailsTable()); + } + }); + UI.getCurrent().addWindow(artifactDtlsWindow); + } + + @Override + protected void populateData(final SoftwareModule selectedBaseEntity) { + super.populateData(selectedBaseEntity); + artifactDetailsButton.setEnabled(selectedBaseEntity != null); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java index 10a8c34a9..198f40778 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java @@ -14,20 +14,16 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.RefreshSoftwareModuleByFilterEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.ManagementEntityState; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; @@ -35,7 +31,6 @@ import org.eclipse.hawkbit.ui.push.SoftwareModuleUpdatedEventContainer; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -53,15 +48,10 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; -import com.vaadin.shared.ui.window.WindowMode; -import com.vaadin.ui.Button; -import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.JavaScript; import com.vaadin.ui.Table; import com.vaadin.ui.UI; -import com.vaadin.ui.Window; /** * Implementation of software module table using generic abstract table styles . @@ -76,22 +66,14 @@ public class SwModuleTable extends AbstractNamedVersionTable { private final DistributionsViewClientCriterion distributionsViewClientCriterion; - private final ArtifactDetailsLayout artifactDetailsLayout; - - private final SwMetadataPopupLayout swMetadataPopupLayout; - SwModuleTable(final UIEventBus eventBus, final VaadinMessageSource i18n, final UINotification uiNotification, final ManageDistUIState manageDistUIState, final SoftwareModuleManagement softwareManagement, final DistributionsViewClientCriterion distributionsViewClientCriterion, - final ArtifactManagement artifactManagement, final SwMetadataPopupLayout swMetadataPopupLayout, - final ArtifactUploadState artifactUploadState) { - super(eventBus, i18n, uiNotification); + final SpPermissionChecker permChecker) { + super(eventBus, i18n, uiNotification, permChecker); this.manageDistUIState = manageDistUIState; this.softwareModuleManagement = softwareManagement; this.distributionsViewClientCriterion = distributionsViewClientCriterion; - this.artifactDetailsLayout = new ArtifactDetailsLayout(i18n, eventBus, artifactUploadState, uiNotification, - artifactManagement, softwareManagement); - this.swMetadataPopupLayout = swMetadataPopupLayout; addNewContainerDS(); setColumnProperties(); @@ -135,16 +117,14 @@ public class SwModuleTable extends AbstractNamedVersionTable { final List visibleItemIds = (List) getVisibleItemIds(); handleSelectedAndUpdatedSoftwareModules(eventContainer.getEvents()); eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId())) - .filter(Objects::nonNull) - .forEach(event -> updateSoftwareModuleInTable(event.getEntity())); + .filter(Objects::nonNull).forEach(event -> updateSoftwareModuleInTable(event.getEntity())); } private void handleSelectedAndUpdatedSoftwareModules(final List events) { manageDistUIState.getLastSelectedSoftwareModule() .ifPresent(lastSelectedModuleId -> events.stream() - .filter(event -> lastSelectedModuleId.equals(event.getEntityId())) - .filter(Objects::nonNull).findAny() - .ifPresent(lastEvent -> eventBus.publish(this, + .filter(event -> lastSelectedModuleId.equals(event.getEntityId())).filter(Objects::nonNull) + .findAny().ifPresent(lastEvent -> getEventBus().publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, lastEvent.getEntity())))); } @@ -165,7 +145,8 @@ public class SwModuleTable extends AbstractNamedVersionTable { final BeanQueryFactory swQF = new BeanQueryFactory<>(SwModuleBeanQuery.class); swQF.setQueryConfiguration(queryConfiguration); - return new LazyQueryContainer(new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, "swId"), swQF); + return new LazyQueryContainer( + new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_SWM_ID), swQF); } private Map prepareQueryConfigFilters() { @@ -177,13 +158,12 @@ public class SwModuleTable extends AbstractNamedVersionTable { manageDistUIState.getLastSelectedDistribution() .ifPresent(id -> queryConfig.put(SPUIDefinitions.ORDER_BY_DISTRIBUTION, id)); return queryConfig; - } @Override protected void addContainerProperties(final Container container) { final LazyQueryContainer lazyContainer = (LazyQueryContainer) container; - lazyContainer.addContainerProperty("nameAndVersion", String.class, null, false, false); + lazyContainer.addContainerProperty(SPUILabelDefinitions.NAME_VERSION, String.class, null, false, false); lazyContainer.addContainerProperty(SPUILabelDefinitions.VAR_ID, Long.class, null, false, false); lazyContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, "", false, true); lazyContainer.addContainerProperty(SPUILabelDefinitions.VAR_VERSION, String.class, null, false, false); @@ -198,34 +178,6 @@ public class SwModuleTable extends AbstractNamedVersionTable { lazyContainer.addContainerProperty(SPUILabelDefinitions.VAR_SOFT_TYPE_ID, Long.class, null, false, true); } - @Override - protected void addCustomGeneratedColumns() { - addGeneratedColumn(SPUILabelDefinitions.ARTIFACT_ICON, new ColumnGenerator() { - - private static final long serialVersionUID = 1L; - - @Override - public Object generateCell(final Table source, final Object itemId, final Object columnId) { - final HorizontalLayout iconLayout = new HorizontalLayout(); - // add artifactory details popup - final String nameVersionStr = getNameAndVerion(itemId); - final Button showArtifactDtlsBtn = createShowArtifactDtlsButton(nameVersionStr); - final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr); - showArtifactDtlsBtn.addClickListener(event -> showArtifactDetailsWindow((Long) itemId, nameVersionStr)); - manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId)); - iconLayout.addComponent(showArtifactDtlsBtn); - iconLayout.addComponent(manageMetaDataBtn); - return iconLayout; - } - }); - - } - - @Override - protected boolean isFirstRowSelectedOnLoad() { - return manageDistUIState.getSelectedSoftwareModules().isEmpty(); - } - @Override protected Object getItemIdToSelect() { return manageDistUIState.getSelectedSoftwareModules().isEmpty() ? null @@ -239,16 +191,23 @@ public class SwModuleTable extends AbstractNamedVersionTable { @Override protected void publishSelectedEntityEvent(final SoftwareModule selectedLastEntity) { - eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); + getEventBus().publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); } @Override protected void setLastSelectedEntityId(final Long selectedLastEntityId) { + if (selectedLastEntityId == null) { + return; + } manageDistUIState.setLastSelectedSoftwareModule(selectedLastEntityId); } @Override protected void setManagementEntityStateValues(final Set values, final Long lastId) { + final ManagementEntityState managementEntityState = getManagementEntityState(); + if (managementEntityState == null) { + return; + } manageDistUIState.setLastSelectedSoftwareModule(lastId); manageDistUIState.setSelectedSoftwareModules(values); } @@ -260,16 +219,15 @@ public class SwModuleTable extends AbstractNamedVersionTable { @Override protected ManagementEntityState getManagementEntityState() { - return null; + return manageDistUIState; } @Override protected List getTableVisibleColumns() { final List columnList = super.getTableVisibleColumns(); if (isMaximized()) { - columnList.add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, i18n.getMessage("header.vendor"), 0.1F)); - } else { - columnList.add(new TableColumn(SPUILabelDefinitions.ARTIFACT_ICON, "", 0.1F)); + columnList + .add(new TableColumn(SPUILabelDefinitions.VAR_VENDOR, getI18n().getMessage("header.vendor"), 0.1F)); } return columnList; } @@ -334,91 +292,56 @@ public class SwModuleTable extends AbstractNamedVersionTable { return null; } - private Button createShowArtifactDtlsButton(final String nameVersionStr) { - final Button showArtifactDtlsBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.SW_TABLE_ATRTIFACT_DETAILS_ICON + "." + nameVersionStr, "", "", null, false, - FontAwesome.FILE_O, SPUIButtonStyleSmallNoBorder.class); - showArtifactDtlsBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON); - showArtifactDtlsBtn.setDescription(i18n.getMessage("tooltip.artifact.icon")); - return showArtifactDtlsBtn; - } - - private Button createManageMetadataButton(final String nameVersionStr) { - final Button manageMetadataBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, - FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); - manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON); - manageMetadataBtn.setDescription(i18n.getMessage("tooltip.metadata.icon")); - return manageMetadataBtn; - } - - private String getNameAndVerion(final Object itemId) { - final Item item = getItem(itemId); - final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); - final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); - return name + "." + version; - } - @Override @SuppressWarnings("unchecked") protected void updateEntity(final SoftwareModule baseEntity, final Item item) { final String swNameVersion = HawkbitCommonUtil.concatStrings(":", baseEntity.getName(), baseEntity.getVersion()); item.getItemProperty(SPUILabelDefinitions.NAME_VERSION).setValue(swNameVersion); - item.getItemProperty("swId").setValue(baseEntity.getId()); + item.getItemProperty(SPUILabelDefinitions.VAR_SWM_ID).setValue(baseEntity.getId()); item.getItemProperty(SPUILabelDefinitions.VAR_VENDOR).setValue(baseEntity.getVendor()); item.getItemProperty(SPUILabelDefinitions.VAR_COLOR).setValue(baseEntity.getType().getColour()); super.updateEntity(baseEntity, item); } - private void showArtifactDetailsWindow(final Long itemId, final String nameVersionStr) { - final Window artifactDtlsWindow = new Window(); - artifactDtlsWindow.setCaption(HawkbitCommonUtil.getArtifactoryDetailsLabelId(nameVersionStr)); - artifactDtlsWindow.setCaptionAsHtml(true); - artifactDtlsWindow.setClosable(true); - artifactDtlsWindow.setResizable(true); - artifactDtlsWindow.setImmediate(true); - artifactDtlsWindow.setWindowMode(WindowMode.NORMAL); - artifactDtlsWindow.setModal(true); - artifactDtlsWindow.addStyleName(SPUIStyleDefinitions.CONFIRMATION_WINDOW_CAPTION); - - artifactDetailsLayout.setFullWindowMode(false); - artifactDetailsLayout.populateArtifactDetails(itemId, nameVersionStr); - /* Now add table to the window */ - artifactDetailsLayout.getArtifactDetailsTable().setWidth(700, Unit.PIXELS); - artifactDetailsLayout.getArtifactDetailsTable().setHeight(500, Unit.PIXELS); - artifactDtlsWindow.setContent(artifactDetailsLayout.getArtifactDetailsTable()); - - /* Create maximized view of the table */ - artifactDtlsWindow.addWindowModeChangeListener( - - event -> { - if (event.getWindowMode() == WindowMode.MAXIMIZED) { - artifactDtlsWindow.setSizeFull(); - artifactDetailsLayout.setFullWindowMode(true); - artifactDetailsLayout.createMaxArtifactDetailsTable(); - artifactDetailsLayout.getMaxArtifactDetailsTable().setWidth(100, Unit.PERCENTAGE); - artifactDetailsLayout.getMaxArtifactDetailsTable().setHeight(100, Unit.PERCENTAGE); - artifactDtlsWindow.setContent(artifactDetailsLayout.getMaxArtifactDetailsTable()); - } else { - artifactDtlsWindow.setSizeUndefined(); - artifactDtlsWindow.setContent(artifactDetailsLayout.getArtifactDetailsTable()); - } - }); - /* display the window */ - UI.getCurrent().addWindow(artifactDtlsWindow); - - } - @Override protected void setDataAvailable(final boolean available) { manageDistUIState.setNoDataAvilableSwModule(!available); - } - private void showMetadataDetails(final Long itemId) { - softwareModuleManagement.get(itemId) - .ifPresent(swmodule -> UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, null))); + @Override + protected void handleOkDelete(final List entitiesToDelete) { + softwareModuleManagement.delete(entitiesToDelete); + getEventBus().publish(this, new SoftwareModuleEvent(BaseEntityEventType.REMOVE_ENTITY, entitiesToDelete)); + getNotification().displaySuccess(getI18n().getMessage("message.delete.success", + entitiesToDelete.size() + " " + getI18n().getMessage("caption.software.module") + "(s)")); + manageDistUIState.getSelectedSoftwareModules().clear(); + } + + @Override + protected String getEntityType() { + return getI18n().getMessage("upload.swModuleTable.header"); + } + + @Override + protected Set getSelectedEntities() { + return manageDistUIState.getSelectedSoftwareModules(); + } + + @Override + protected String getEntityId(final Object itemId) { + final String entityId = String.valueOf( + getContainerDataSource().getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_SWM_ID).getValue()); + return "softwareModule." + entityId; + } + + @Override + protected String getDeletedEntityName(final Long entityId) { + final Optional softwareModule = softwareModuleManagement.get(entityId); + if (softwareModule.isPresent()) { + return softwareModule.get().getName() + ":" + softwareModule.get().getVersion(); + } + return ""; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java index 969def956..5b5182db7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java @@ -13,6 +13,7 @@ import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; @@ -42,16 +43,18 @@ public class SwModuleTableLayout extends AbstractTableLayout { softwareModuleManagement, entityFactory, permChecker); this.swModuleTable = new SwModuleTable(eventBus, i18n, uiNotification, manageDistUIState, - softwareModuleManagement, distributionsViewClientCriterion, artifactManagement, swMetadataPopupLayout, - artifactUploadState); + softwareModuleManagement, distributionsViewClientCriterion, permChecker); final SoftwareModuleAddUpdateWindow softwareModuleAddUpdateWindow = new SoftwareModuleAddUpdateWindow(i18n, uiNotification, eventBus, softwareModuleManagement, softwareModuleTypeManagement, entityFactory, swModuleTable); + final ArtifactDetailsLayout artifactDetailsLayout = new ArtifactDetailsLayout(i18n, eventBus, + artifactUploadState, uiNotification, artifactManagement, softwareModuleManagement); + super.init( new SwModuleTableHeader(i18n, permChecker, eventBus, manageDistUIState, softwareModuleAddUpdateWindow), swModuleTable, new SwModuleDetails(i18n, eventBus, permChecker, softwareModuleAddUpdateWindow, - manageDistUIState, softwareModuleManagement, swMetadataPopupLayout)); + manageDistUIState, softwareModuleManagement, swMetadataPopupLayout, artifactDetailsLayout)); } public SwModuleTable getSwModuleTable() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterHeader.java deleted file mode 100644 index 8a0ba80f0..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterHeader.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.smtype; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.artifacts.smtype.CreateUpdateSoftwareTypeLayout; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; -import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; -import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.UI; -import com.vaadin.ui.Window; - -/** - * Software Module Type filter buttons header. - */ -public class DistSMTypeFilterHeader extends AbstractFilterHeader { - private static final long serialVersionUID = -8763788280848718344L; - - private final ManageDistUIState manageDistUIState; - private final CreateUpdateSoftwareTypeLayout createUpdateSWTypeLayout; - - DistSMTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, - final UIEventBus eventBus, final ManageDistUIState manageDistUIState, final EntityFactory entityFactory, - final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement) { - super(permChecker, eventBus, i18n); - this.manageDistUIState = manageDistUIState; - this.createUpdateSWTypeLayout = new CreateUpdateSoftwareTypeLayout(i18n, entityFactory, eventBus, permChecker, - uiNotification, softwareModuleTypeManagement); - - if (hasCreateUpdatePermission()) { - createUpdateSWTypeLayout.init(); - } - } - - @Override - protected String getHideButtonId() { - return UIComponentIdProvider.SM_SHOW_FILTER_BUTTON_ID; - } - - @Override - protected boolean hasCreateUpdatePermission() { - return permChecker.hasCreateRepositoryPermission() || permChecker.hasUpdateRepositoryPermission(); - } - - @Override - protected String getTitle() { - return SPUILabelDefinitions.TYPE; - } - - @Override - protected void settingsIconClicked(final ClickEvent event) { - final Window window = createUpdateSWTypeLayout.getWindow(); - UI.getCurrent().addWindow(window); - window.setVisible(Boolean.TRUE); - } - - @Override - protected boolean dropHitsRequired() { - return false; - } - - @Override - protected void hideFilterButtonLayout() { - manageDistUIState.setSwTypeFilterClosed(true); - eventBus.publish(this, DistributionsUIEvent.HIDE_SM_FILTER_BY_TYPE); - } - - @Override - protected String getConfigureFilterButtonId() { - return SPUIDefinitions.ADD_SOFTWARE_MODULE_TYPE; - } - - @Override - protected boolean isAddTagRequired() { - return true; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtonClick.java similarity index 97% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtonClick.java index ce47cd735..ad17ba0fd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtonClick.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.distributions.smtype; +package org.eclipse.hawkbit.ui.distributions.smtype.filter; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.ui.artifacts.event.RefreshSoftwareModuleByFilterEvent; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtons.java similarity index 52% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtons.java index cc5ef13a0..f682ab1d6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterButtons.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.distributions.smtype; +package org.eclipse.hawkbit.ui.distributions.smtype.filter; import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE; import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE; @@ -14,16 +14,26 @@ import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_NAME; import static org.eclipse.hawkbit.ui.utils.UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; import java.util.Collections; +import java.util.Optional; +import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; +import org.eclipse.hawkbit.ui.artifacts.smtype.UpdateSoftwareModuleTypeLayout; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.SoftwareModuleTypeFilterHeaderEvent; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition; @@ -34,24 +44,60 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.ui.Button.ClickEvent; /** * Software Module Type filter buttons. */ public class DistSMTypeFilterButtons extends AbstractFilterButtons { - private static final long serialVersionUID = 6804534533362387433L; + private static final long serialVersionUID = 1L; private final ManageDistUIState manageDistUIState; private final DistributionsViewClientCriterion distributionsViewClientCriterion; - DistSMTypeFilterButtons(final UIEventBus eventBus, final ManageDistUIState manageDistUIState, + private final transient EntityFactory entityFactory; + + private final SpPermissionChecker permChecker; + + private final UINotification uiNotification; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param manageDistUIState + * ManageDistUIState + * @param distributionsViewClientCriterion + * DistributionsViewClientCriterion + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + */ + public DistSMTypeFilterButtons(final UIEventBus eventBus, final ManageDistUIState manageDistUIState, final DistributionsViewClientCriterion distributionsViewClientCriterion, - final SoftwareModuleTypeManagement softwareModuleTypeManagement) { - super(eventBus, new DistSMTypeFilterButtonClick(eventBus, manageDistUIState, softwareModuleTypeManagement)); + final SoftwareModuleTypeManagement softwareModuleTypeManagement, final VaadinMessageSource i18n, + final EntityFactory entityFactory, final SpPermissionChecker permChecker, + final UINotification uiNotification) { + super(eventBus, new DistSMTypeFilterButtonClick(eventBus, manageDistUIState, softwareModuleTypeManagement), + i18n); this.manageDistUIState = manageDistUIState; this.distributionsViewClientCriterion = distributionsViewClientCriterion; + this.entityFactory = entityFactory; + this.permChecker = permChecker; + this.uiNotification = uiNotification; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; } @Override @@ -109,11 +155,18 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { @EventBusListenerMethod(scope = EventScope.UI) void onEvent(final SoftwareModuleTypeEvent event) { if (isCreateOrUpdate(event) && event.getSoftwareModuleType() != null) { - refreshTypeTable(); + refreshTable(); + } + if (isUpdate(event)) { + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); } } - private boolean isCreateOrUpdate(final SoftwareModuleTypeEvent event) { + private static boolean isUpdate(final SoftwareModuleTypeEvent event) { + return event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE; + } + + private static boolean isCreateOrUpdate(final SoftwareModuleTypeEvent event) { return event.getSoftwareModuleTypeEnum() == ADD_SOFTWARE_MODULE_TYPE || event.getSoftwareModuleTypeEnum() == UPDATE_SOFTWARE_MODULE_TYPE; } @@ -121,11 +174,36 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons { @EventBusListenerMethod(scope = EventScope.UI) void onEvent(final SaveActionWindowEvent event) { if (event == SaveActionWindowEvent.SAVED_DELETE_SW_MODULE_TYPES) { - refreshTypeTable(); + refreshTable(); } } - private void refreshTypeTable() { - setContainerDataSource(createButtonsLazyQueryContainer()); + @Override + protected void addEditButtonClickListener(final ClickEvent event) { + new UpdateSoftwareModuleTypeLayout(getI18n(), entityFactory, getEventBus(), permChecker, uiNotification, + softwareModuleTypeManagement, getEntityId(event), getCloseListenerForEditAndDeleteTag( + new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR))); + } + + @Override + protected void addDeleteButtonClickListener(final ClickEvent event) { + openConfirmationWindowForDeletion(getEntityId(event), + getI18n().getMessage("caption.entity.software.module.type"), + new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + + @Override + protected void deleteEntity(final String entityToDelete) { + final Optional swmTypeToDelete = softwareModuleTypeManagement.getByName(entityToDelete); + swmTypeToDelete.ifPresent(tag -> { + if (manageDistUIState.getSoftwareModuleFilters().getSoftwareModuleType().equals(swmTypeToDelete)) { + uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityToDelete)); + removeUpdateAndDeleteColumn(); + } else { + softwareModuleTypeManagement.delete(swmTypeToDelete.get().getId()); + getEventBus().publish(this, SaveActionWindowEvent.SAVED_DELETE_SW_MODULE_TYPES); + uiNotification.displaySuccess(getI18n().getMessage("message.delete.success", entityToDelete)); + } + }); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterHeader.java new file mode 100644 index 000000000..ad13bdf2f --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterHeader.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.distributions.smtype.filter; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.artifacts.smtype.CreateSoftwareModuleTypeLayout; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.SoftwareModuleTypeFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; +import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; +import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.MenuBar.Command; + +/** + * Software Module Type filter buttons header. + */ +public class DistSMTypeFilterHeader extends AbstractFilterHeader { + + private static final long serialVersionUID = 1L; + + private final ManageDistUIState manageDistUIState; + + private final transient EntityFactory entityFactory; + + private final UINotification uiNotification; + + private final transient SoftwareModuleTypeManagement softwareModuleTypeManagement; + + private final DistSMTypeFilterButtons filterButtons; + + DistSMTypeFilterHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, + final UIEventBus eventBus, final ManageDistUIState manageDistUIState, final EntityFactory entityFactory, + final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, + final DistSMTypeFilterButtons filterButtons) { + super(permChecker, eventBus, i18n); + this.manageDistUIState = manageDistUIState; + this.entityFactory = entityFactory; + this.uiNotification = uiNotification; + this.softwareModuleTypeManagement = softwareModuleTypeManagement; + this.filterButtons = filterButtons; + } + + @Override + protected String getHideButtonId() { + return UIComponentIdProvider.SM_SHOW_FILTER_BUTTON_ID; + } + + @Override + protected String getTitle() { + return SPUILabelDefinitions.TYPE; + } + + @Override + protected boolean dropHitsRequired() { + return false; + } + + @Override + protected void hideFilterButtonLayout() { + manageDistUIState.setSwTypeFilterClosed(true); + getEventBus().publish(this, DistributionsUIEvent.HIDE_SM_FILTER_BY_TYPE); + } + + @Override + protected String getConfigureFilterButtonId() { + return UIComponentIdProvider.ADD_SOFTWARE_MODULE_TYPE; + } + + @Override + protected boolean isAddTagRequired() { + return true; + } + + @Override + protected Command getAddButtonCommand() { + return command -> new CreateSoftwareModuleTypeLayout(getI18n(), entityFactory, getEventBus(), getPermChecker(), + uiNotification, softwareModuleTypeManagement); + } + + @Override + protected Command getDeleteButtonCommand() { + return command -> { + filterButtons.addDeleteColumn(); + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected Command getUpdateButtonCommand() { + return command -> { + filterButtons.addUpdateColumn(); + getEventBus().publish(this, new SoftwareModuleTypeFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + super.cancelUpdateOrDeleteTag(event); + filterButtons.removeUpdateAndDeleteColumn(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + private void onEvent(final SoftwareModuleTypeFilterHeaderEvent event) { + processFilterHeaderEvent(event); + } + + @Override + protected String getMenuBarId() { + return UIComponentIdProvider.SOFT_MODULE_TYPE_MENU_BAR_ID; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterLayout.java similarity index 72% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterLayout.java index e5d24c7dd..156141e2b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/DistSMTypeFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtype/filter/DistSMTypeFilterLayout.java @@ -6,13 +6,12 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.distributions.smtype; +package org.eclipse.hawkbit.ui.distributions.smtype.filter; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterLayout; -import org.eclipse.hawkbit.ui.dd.criteria.DistributionsViewClientCriterion; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -26,21 +25,38 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; */ public class DistSMTypeFilterLayout extends AbstractFilterLayout { - private static final long serialVersionUID = 3042297420534417538L; + private static final long serialVersionUID = 1L; private final ManageDistUIState manageDistUIState; + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param i18n + * VaadinMessageSource + * @param permChecker + * SpPermissionChecker + * @param manageDistUIState + * ManageDistUIState + * @param entityFactory + * EntityFactory + * @param uiNotification + * UINotification + * @param softwareModuleTypeManagement + * SoftwareModuleTypeManagement + * @param filterButtons + * DistSMTypeFilterButtons + */ public DistSMTypeFilterLayout(final UIEventBus eventBus, final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final ManageDistUIState manageDistUIState, final EntityFactory entityFactory, final UINotification uiNotification, final SoftwareModuleTypeManagement softwareModuleTypeManagement, - final DistributionsViewClientCriterion distributionsViewClientCriterion) { + final DistSMTypeFilterButtons filterButtons) { super(new DistSMTypeFilterHeader(i18n, permChecker, eventBus, manageDistUIState, entityFactory, uiNotification, - softwareModuleTypeManagement), - new DistSMTypeFilterButtons(eventBus, manageDistUIState, distributionsViewClientCriterion, - softwareModuleTypeManagement)); + softwareModuleTypeManagement, filterButtons), filterButtons, eventBus); this.manageDistUIState = manageDistUIState; - restoreState(); eventBus.subscribe(this); } @@ -57,7 +73,6 @@ public class DistSMTypeFilterLayout extends AbstractFilterLayout { @Override public Boolean onLoadIsTypeFilterIsClosed() { - return manageDistUIState.isSwTypeFilterClosed(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java index 4246a832c..09a7f5008 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/state/ManageDistUIState.java @@ -201,7 +201,7 @@ public class ManageDistUIState implements ManagementEntityState, Serializable { this.noDataAvailableDist = noDataAvailableDist; } - public Map>> getConsolidatedDistSoftwarewList() { + public Map>> getConsolidatedDistSoftwareList() { return consolidatedDistSoftwarewList; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index 1453736ff..936c795b0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -20,7 +20,7 @@ import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -192,7 +192,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button private Button createBreadcrumbButton() { final Button createFilterViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); createFilterViewLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links"); createFilterViewLink.setDescription(i18n.getMessage(BREADCRUMB_CUSTOM_FILTERS)); createFilterViewLink.setCaption(i18n.getMessage(BREADCRUMB_CUSTOM_FILTERS)); @@ -314,7 +314,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton( UIComponentIdProvider.CUSTOM_FILTER_CLOSE, "", "", null, false, FontAwesome.TIMES, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); button.addClickListener(event -> closeFilterLayout()); return button; } @@ -330,7 +330,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button private Button createSaveButton() { saveButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CUSTOM_FILTER_SAVE_ICON, UIComponentIdProvider.CUSTOM_FILTER_SAVE_ICON, "Save", null, false, FontAwesome.SAVE, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); saveButton.addClickListener(this); saveButton.setEnabled(false); return saveButton; @@ -338,7 +338,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button private Button createSearchIcon() { searchIcon = SPUIComponentProvider.getButton(UIComponentIdProvider.FILTER_SEARCH_ICON_ID, "", "", null, false, - FontAwesome.SEARCH, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.SEARCH, SPUIButtonStyleNoBorder.class); searchIcon.addClickListener(event -> onSearchIconClick()); searchIcon.setEnabled(false); searchIcon.setData(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/DistributionSetSelectWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/DistributionSetSelectWindow.java index 2b777c683..4e1e5e2c7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/DistributionSetSelectWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/DistributionSetSelectWindow.java @@ -61,8 +61,9 @@ public class DistributionSetSelectWindow private CheckBox checkBox; private Long tfqId; - DistributionSetSelectWindow(final VaadinMessageSource i18n, final UIEventBus eventBus, final TargetManagement targetManagement, - final TargetFilterQueryManagement targetFilterQueryManagement, final ManageDistUIState manageDistUIState) { + DistributionSetSelectWindow(final VaadinMessageSource i18n, final UIEventBus eventBus, + final TargetManagement targetManagement, final TargetFilterQueryManagement targetFilterQueryManagement, + final ManageDistUIState manageDistUIState) { this.i18n = i18n; this.dsTable = new DistributionSetSelectTable(i18n, eventBus, manageDistUIState); this.eventBus = eventBus; @@ -260,8 +261,7 @@ public class DistributionSetSelectWindow if (targetsCount == 0) { mainTextLabel = new Label(i18n.getMessage("message.confirm.assign.consequences.none")); } else { - mainTextLabel = new Label( - i18n.getMessage("message.confirm.assign.consequences.text", targetsCount)); + mainTextLabel = new Label(i18n.getMessage("message.confirm.assign.consequences.text", targetsCount)); } layout.addComponent(mainTextLabel); @@ -272,8 +272,9 @@ public class DistributionSetSelectWindow buttonsLayout.addStyleName("actionButtonsMargin"); layout.addComponent(buttonsLayout); - okButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SAVE_BUTTON, i18n.getMessage("button.ok"), "", "", - true, FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class); + okButton = SPUIComponentProvider.getButton(UIComponentIdProvider.SAVE_BUTTON, + i18n.getMessage(SPUIDefinitions.BUTTON_OK), "", "", true, FontAwesome.SAVE, + SPUIButtonStyleNoBorderWithIcon.class); okButton.setSizeUndefined(); okButton.addStyleName("default-color"); okButton.addClickListener(this); @@ -282,7 +283,8 @@ public class DistributionSetSelectWindow buttonsLayout.setExpandRatio(okButton, 1.0F); final Button cancelButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_BUTTON, - i18n.getMessage("button.cancel"), "", "", true, FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class); + i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), "", "", true, FontAwesome.TIMES, + SPUIButtonStyleNoBorderWithIcon.class); cancelButton.setSizeUndefined(); cancelButton.addStyleName("default-color"); cancelButton.addClickListener(this); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java index ce9876b10..fbbe5f772 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java @@ -21,7 +21,6 @@ import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.footer.TargetFilterCountMessageLabel; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.springframework.beans.factory.annotation.Autowired; @@ -171,7 +170,6 @@ public class FilterManagementView extends VerticalLayout implements View { private HorizontalLayout addTargetFilterMessageLabel() { final HorizontalLayout messageLabelLayout = new HorizontalLayout(); messageLabelLayout.addComponent(targetFilterCountMessageLabel); - messageLabelLayout.addStyleName(SPUIStyleDefinitions.FOOTER_LAYOUT); return messageLabelLayout; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java index 133809cd8..47cc2f6a2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterHeader.java @@ -13,7 +13,7 @@ import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -109,7 +109,7 @@ public class TargetFilterHeader extends VerticalLayout { private Button createAddButton() { final Button button = SPUIComponentProvider.getButton(UIComponentIdProvider.TARGET_FILTER_ADD_ICON_ID, "", "", - null, false, FontAwesome.PLUS, SPUIButtonStyleSmallNoBorder.class); + null, false, FontAwesome.PLUS, SPUIButtonStyleNoBorder.class); button.addClickListener(event -> addNewFilter()); return button; } @@ -137,7 +137,7 @@ public class TargetFilterHeader extends VerticalLayout { private SPUIButton createSearchResetIcon() { final SPUIButton button = (SPUIButton) SPUIComponentProvider.getButton( UIComponentIdProvider.TARGET_FILTER_TBL_SEARCH_RESET_ID, "", "", null, false, FontAwesome.SEARCH, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); button.addClickListener(event -> onSearchResetClick()); return button; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java index e3507ee8f..1a0d7f35c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterTable.java @@ -20,7 +20,7 @@ import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.components.ProxyDistribution; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; @@ -55,7 +55,7 @@ import com.vaadin.ui.themes.ValoTheme; */ public class TargetFilterTable extends Table { - private static final long serialVersionUID = -4307487829435474759L; + private static final long serialVersionUID = 1L; private final VaadinMessageSource i18n; @@ -157,7 +157,7 @@ public class TargetFilterTable extends Table { new TableColumn(SPUILabelDefinitions.VAR_MODIFIED_DATE, i18n.getMessage("header.modifiedDate"), 0.2F)); columnList.add(new TableColumn(SPUILabelDefinitions.AUTO_ASSIGN_DISTRIBUTION_SET, i18n.getMessage("header.auto.assignment.ds"), 0.1F)); - columnList.add(new TableColumn(SPUIDefinitions.CUSTOM_FILTER_DELETE, i18n.getMessage("header.delete"), 0.1F)); + columnList.add(new TableColumn(SPUIDefinitions.DELETE, i18n.getMessage("header.delete"), 0.1F)); return columnList; } @@ -172,7 +172,7 @@ public class TargetFilterTable extends Table { final String tfName = (String) row.getItemProperty(SPUILabelDefinitions.NAME).getValue(); final Button deleteIcon = SPUIComponentProvider.getButton(getDeleteIconId(tfName), "", SPUILabelDefinitions.DELETE_CUSTOM_FILTER, ValoTheme.BUTTON_TINY + " " + "blueicon", true, - FontAwesome.TRASH_O, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TRASH_O, SPUIButtonStyleNoBorder.class); deleteIcon.setData(itemId); deleteIcon.addClickListener(this::onDelete); return deleteIcon; @@ -186,8 +186,9 @@ public class TargetFilterTable extends Table { private void onDelete(final ClickEvent event) { /* Display the confirmation */ final ConfirmationDialog confirmDialog = new ConfirmationDialog( - i18n.getMessage("caption.filter.delete.confirmbox"), i18n.getMessage("message.delete.filter.confirm"), - i18n.getMessage("button.ok"), i18n.getMessage("button.cancel"), ok -> { + i18n.getMessage("caption.entity.delete.action.confirmbox"), + i18n.getMessage("message.delete.filter.confirm"), i18n.getMessage(SPUIDefinitions.BUTTON_OK), + i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (ok) { final Long rowId = (Long) ((Button) event.getComponent()).getData(); final String deletedFilterName = targetFilterQueryManagement.get(rowId).get().getName(); @@ -208,8 +209,7 @@ public class TargetFilterTable extends Table { } protected void addCustomGeneratedColumns() { - addGeneratedColumn(SPUIDefinitions.CUSTOM_FILTER_DELETE, - (source, itemId, columnId) -> getDeleteButton((Long) itemId)); + addGeneratedColumn(SPUIDefinitions.DELETE, (source, itemId, columnId) -> getDeleteButton((Long) itemId)); addGeneratedColumn(SPUILabelDefinitions.NAME, (source, itemId, columnId) -> customFilterDetailButton((Long) itemId)); @@ -224,7 +224,7 @@ public class TargetFilterTable extends Table { final String tfName = (String) row1.getItemProperty(SPUILabelDefinitions.NAME).getValue(); final Button updateIcon = SPUIComponentProvider.getButton(getDetailLinkId(tfName), tfName, - SPUILabelDefinitions.UPDATE_CUSTOM_FILTER, null, false, null, SPUIButtonStyleSmallNoBorder.class); + SPUILabelDefinitions.UPDATE_CUSTOM_FILTER, null, false, null, SPUIButtonStyleNoBorder.class); updateIcon.setData(tfName); updateIcon.addStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link"); updateIcon.addClickListener(this::onClickOfDetailButton); @@ -239,12 +239,10 @@ public class TargetFilterTable extends Table { Button updateIcon; if (distSet == null) { updateIcon = SPUIComponentProvider.getButton(buttonId, i18n.getMessage("button.no.auto.assignment"), - i18n.getMessage("button.auto.assignment.desc"), null, false, null, - SPUIButtonStyleSmallNoBorder.class); + i18n.getMessage("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleNoBorder.class); } else { updateIcon = SPUIComponentProvider.getButton(buttonId, distSet.getNameVersion(), - i18n.getMessage("button.auto.assignment.desc"), null, false, null, - SPUIButtonStyleSmallNoBorder.class); + i18n.getMessage("button.auto.assignment.desc"), null, false, null, SPUIButtonStyleNoBorder.class); } updateIcon.addClickListener(this::onClickOfDistributionSetButton); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java index b24441976..d55f441ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java @@ -12,7 +12,7 @@ import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -25,19 +25,19 @@ import com.vaadin.ui.Label; import com.vaadin.ui.UI; /** - * Count message label which display current filter details and details - * on pinning. + * Count message label which display current filter details and details on + * pinning. */ public class TargetFilterCountMessageLabel extends Label { - private static final long serialVersionUID = -7188528790042766877L; + private static final long serialVersionUID = 1L; private final FilterManagementUIState filterManagementUIState; private final VaadinMessageSource i18n; - public TargetFilterCountMessageLabel(final FilterManagementUIState filterManagementUIState, final VaadinMessageSource i18n, - final UIEventBus eventBus) { + public TargetFilterCountMessageLabel(final FilterManagementUIState filterManagementUIState, + final VaadinMessageSource i18n, final UIEventBus eventBus) { this.filterManagementUIState = filterManagementUIState; this.i18n = i18n; @@ -52,12 +52,12 @@ public class TargetFilterCountMessageLabel extends Label { || custFUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK || custFUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW || custFUIEvent == CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON) { - UI.getCurrent().access(() -> displayTargetFilterMessage()); + UI.getCurrent().access(this::displayTargetFilterMessage); } } private void applyStyle() { - addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); + addStyleName(SPUIStyleDefinitions.SP_LABEL_MESSAGE_STYLE); setContentMode(ContentMode.HTML); setId(UIComponentIdProvider.COUNT_LABEL); } @@ -65,15 +65,15 @@ public class TargetFilterCountMessageLabel extends Label { private void displayTargetFilterMessage() { long totalTargets = 0; if (filterManagementUIState.isCreateFilterViewDisplayed() || filterManagementUIState.isEditViewDisplayed()) { - if (null != filterManagementUIState.getFilterQueryValue()) { + if (filterManagementUIState.getFilterQueryValue() != null) { totalTargets = filterManagementUIState.getTargetsCountAll().get(); } final StringBuilder targetMessage = new StringBuilder(i18n.getMessage("label.target.filtered.total")); if (filterManagementUIState.getTargetsTruncated() != null) { // set the icon setIcon(FontAwesome.INFO_CIRCLE); - setDescription(i18n.getMessage("label.target.filter.truncated", filterManagementUIState.getTargetsTruncated(), - SPUIDefinitions.MAX_TABLE_ENTRIES)); + setDescription(i18n.getMessage("label.target.filter.truncated", + filterManagementUIState.getTargetsTruncated(), SPUIDefinitions.MAX_TABLE_ENTRIES)); } else { setIcon(null); @@ -86,9 +86,7 @@ public class TargetFilterCountMessageLabel extends Label { targetMessage.append(i18n.getMessage("label.filter.shown")); targetMessage.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } - setCaption(targetMessage.toString()); } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTagLayout.java similarity index 59% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTagLayout.java index d64b36894..0b81a129c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTagLayout.java @@ -22,9 +22,9 @@ import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; @@ -37,13 +37,11 @@ import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; -import com.vaadin.ui.ComboBox; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; -import com.vaadin.ui.OptionGroup; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -54,63 +52,65 @@ import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** - * Abstract class for create/update target tag layout. + * Abstract class for tag layout. * * @param + * entity class */ -public abstract class AbstractCreateUpdateTagLayout extends CustomComponent +public abstract class AbstractTagLayout extends CustomComponent implements ColorChangeListener, ColorSelector { - private static final long serialVersionUID = 4229177824620576456L; + private static final long serialVersionUID = 1L; + private static final String TAG_NAME_DYNAMIC_STYLE = "new-tag-name"; + private static final String TAG_DESC_DYNAMIC_STYLE = "new-tag-desc"; - protected static final String TAG_DYNAMIC_STYLE = "tag-color-preview"; - protected static final String MESSAGE_ERROR_MISSING_TAGNAME = "message.error.missing.tagname"; - protected static final int MAX_TAGS = 500; + private static final String TAG_DYNAMIC_STYLE = "tag-color-preview"; - protected VaadinMessageSource i18n; + private static final String MESSAGE_ERROR_MISSING_TAGNAME = "message.error.missing.tagname"; - protected transient EntityFactory entityFactory; + private static final int MAX_TAGS = 500; - protected transient EventBus.UIEventBus eventBus; + private final VaadinMessageSource i18n; - protected SpPermissionChecker permChecker; + private transient EntityFactory entityFactory; - protected UINotification uiNotification; + private transient EventBus.UIEventBus eventBus; + + private final SpPermissionChecker permChecker; + + private final UINotification uiNotification; private final FormLayout formLayout = new FormLayout(); - protected String createTagStr; - protected String updateTagStr; - protected Label comboLabel; - protected CommonDialogWindow window; + private CommonDialogWindow window; - protected Label colorLabel; - protected TextField tagName; - protected TextArea tagDesc; - protected Button tagColorPreviewBtn; - protected OptionGroup optiongroup; - protected ComboBox tagNameComboBox; + private Label colorLabel; - protected VerticalLayout comboLayout; - protected ColorPickerLayout colorPickerLayout; - protected GridLayout mainLayout; - protected VerticalLayout contentLayout; + private TextField tagName; - protected boolean tagPreviewBtnClicked; + private TextArea tagDesc; + + private Button tagColorPreviewBtn; + + private ColorPickerLayout colorPickerLayout; + + private GridLayout mainLayout; + + private VerticalLayout contentLayout; + + private boolean tagPreviewBtnClicked; private String colorPicked; - protected String tagNameValue; - protected String tagDescValue; + + private HorizontalLayout colorLabelLayout; /** * Constructor for AbstractCreateUpdateTagLayout * * @param i18n * I18N - * @param tagManagement - * TagManagement * @param entityFactory * EntityFactory * @param eventBus @@ -120,13 +120,14 @@ public abstract class AbstractCreateUpdateTagLayout exten * @param uiNotification * UINotification */ - public AbstractCreateUpdateTagLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + public AbstractTagLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification) { this.i18n = i18n; this.entityFactory = entityFactory; this.eventBus = eventBus; this.permChecker = permChecker; this.uiNotification = uiNotification; + init(); } /** @@ -137,23 +138,18 @@ public abstract class AbstractCreateUpdateTagLayout exten @Override public void saveOrUpdate() { - if (isUpdateAction()) { - updateEntity(findEntityByName().orElse(null)); - return; - } - - createEntity(); + saveEntity(); } @Override public boolean canWindowSaveOrUpdate() { - return isUpdateAction() || !isDuplicate(); - + return isDeleteAction() || (isUpdateAction() || !isDuplicate()); } - private boolean isUpdateAction() { - return !optiongroup.getValue().equals(createTagStr); - } + } + + protected boolean isDeleteAction() { + return false; } /** @@ -163,57 +159,37 @@ public abstract class AbstractCreateUpdateTagLayout exten UI.getCurrent().removeWindow(window); } - /** - * Populate target name combo. - */ - protected abstract void populateTagNameCombo(); - - protected abstract void setTagDetails(final String tagSelected); - /** * Init the layout. */ - public void init() { + protected void init() { setSizeUndefined(); createRequiredComponents(); buildLayout(); addListeners(); - if (doSubscribeToEventBus()) { - eventBus.subscribe(this); - } + eventBus.subscribe(this); + openConfigureWindow(); } - /** - * Subscribes the view to the eventBus. Method has to be overriden (return - * false) if the view does not contain any listener to avoid Vaadin blowing - * up our logs with warnings. - */ - protected boolean doSubscribeToEventBus() { - return true; - } + protected abstract Optional findEntityByName(); + + protected abstract String getWindowCaption(); + + protected abstract void saveEntity(); protected void createRequiredComponents() { - - createTagStr = i18n.getMessage("label.create.tag"); - updateTagStr = i18n.getMessage("label.update.tag"); - comboLabel = new LabelBuilder().name(i18n.getMessage("label.choose.tag")).buildLabel(); colorLabel = new LabelBuilder().name(i18n.getMessage("label.choose.tag.color")).buildLabel(); - colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); + colorLabel.addStyleName(SPUIStyleDefinitions.COLOR_LABEL_STYLE); - tagName = new TextFieldBuilder(NamedEntity.NAME_MAX_SIZE).caption(i18n.getMessage("textfield.name")) + tagName = new TextFieldBuilder(getTagNameSize()).caption(i18n.getMessage("textfield.name")) .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME).required(true, i18n) - .id(SPUIDefinitions.NEW_TARGET_TAG_NAME).buildTextComponent(); + .prompt(i18n.getMessage("textfield.name")).immediate(true).id(getTagNameId()).buildTextComponent(); - tagDesc = new TextAreaBuilder(NamedEntity.DESCRIPTION_MAX_SIZE) - .caption(i18n.getMessage("textfield.description")) + tagDesc = new TextAreaBuilder(getTagDescSize()).caption(i18n.getMessage("textfield.description")) .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC) - .id(SPUIDefinitions.NEW_TARGET_TAG_DESC).buildTextComponent(); + .prompt(i18n.getMessage("textfield.description")).id(getTagDescId()).buildTextComponent(); - tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", null, null, false, "", - i18n.getMessage("label.combobox.tag")); - tagNameComboBox.addStyleName(SPUIDefinitions.FILTER_TYPE_COMBO_STYLE); - tagNameComboBox.setImmediate(true); - tagNameComboBox.setId(UIComponentIdProvider.DIST_TAG_COMBO); + tagDesc.setNullRepresentation(""); tagColorPreviewBtn = new Button(); tagColorPreviewBtn.setId(UIComponentIdProvider.TAG_COLOR_PREVIEW_ID); @@ -221,24 +197,27 @@ public abstract class AbstractCreateUpdateTagLayout exten tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } - protected void buildLayout() { + protected abstract String getTagDescId(); + protected abstract String getTagNameId(); + + protected abstract int getTagDescSize(); + + protected abstract int getTagNameSize(); + + protected void buildLayout() { mainLayout = new GridLayout(3, 2); mainLayout.setSpacing(true); - comboLayout = new VerticalLayout(); colorPickerLayout = new ColorPickerLayout(); ColorPickerHelper.setRgbSliderValues(colorPickerLayout); contentLayout = new VerticalLayout(); - final HorizontalLayout colorLabelLayout = new HorizontalLayout(); + colorLabelLayout = new HorizontalLayout(); colorLabelLayout.setMargin(false); colorLabelLayout.addComponents(colorLabel, tagColorPreviewBtn); - formLayout.addComponent(optiongroup); - formLayout.addComponent(comboLayout); formLayout.addComponent(tagName); formLayout.addComponent(tagDesc); - formLayout.addStyleName("form-lastrow"); formLayout.setSizeFull(); contentLayout.addComponent(formLayout); @@ -262,125 +241,26 @@ public abstract class AbstractCreateUpdateTagLayout exten colorPickerLayout.getColorSelect().addColorChangeListener(this); colorPickerLayout.getSelPreview().addColorChangeListener(this); tagColorPreviewBtn.addClickListener(event -> previewButtonClicked()); - tagNameComboBox.addValueChangeListener(this::tagNameChosen); slidersValueChangeListeners(); } - /** - * Open color picker on click of preview button. Auto select the color based - * on target tag if already selected. - */ - private void previewButtonClicked() { - if (!tagPreviewBtnClicked) { - final String selectedOption = (String) optiongroup.getValue(); - if (selectedOption == null) { - return; - } - - if (tagNameComboBox.getValue() == null) { - colorPickerLayout - .setSelectedColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } else { - colorPickerLayout.setSelectedColor(getColorForColorPicker()); - } - } - - tagPreviewBtnClicked = !tagPreviewBtnClicked; - colorPickerLayout.setVisible(tagPreviewBtnClicked); + protected Color getColorForColorPicker() { + return ColorPickerConstants.START_COLOR; } - protected abstract Color getColorForColorPicker(); - - private void tagNameChosen(final ValueChangeEvent event) { - final String tagSelected = (String) event.getProperty().getValue(); - if (null != tagSelected) { - setTagDetails(tagSelected); - } else { - resetTagNameField(); - } - window.setOrginaleValues(); - } - - protected void resetTagNameField() { - tagName.setEnabled(false); - tagName.clear(); - tagDesc.clear(); - restoreComponentStyles(); - colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); - colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); - tagPreviewBtnClicked = false; - } - - /** - * Listener for option group - Create tag/Update. - * - * @param event - * ValueChangeEvent - */ - protected void optionValueChanged(final ValueChangeEvent event) { - - if (updateTagStr.equals(event.getProperty().getValue())) { - tagName.clear(); - tagDesc.clear(); - tagName.setEnabled(false); - populateTagNameCombo(); - // show target name combo - comboLayout.addComponent(comboLabel); - comboLayout.addComponent(tagNameComboBox); - } else { - tagName.setEnabled(true); - tagName.clear(); - tagDesc.clear(); - // hide target name combo - comboLayout.removeComponent(comboLabel); - comboLayout.removeComponent(tagNameComboBox); - } - // close the color picker layout - tagPreviewBtnClicked = false; - // reset the selected color - Set default color - restoreComponentStyles(); - getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); - colorPickerLayout.getSelPreview() - .setColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - window.setOrginaleValues(); - } - - /** - * reset the components. - */ - protected void reset() { + protected void resetFields() { tagName.setEnabled(true); tagName.clear(); tagDesc.clear(); restoreComponentStyles(); - - // hide target name combo - comboLayout.removeComponent(comboLabel); - comboLayout.removeComponent(tagNameComboBox); - - // Default green color - colorPickerLayout.setVisible(false); colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; + disableFields(); } - /** - * On change of color in color picker ,change RGB sliders, components border - * color and color of preview button. - */ - @Override - public void colorChanged(final ColorChangeEvent event) { - setColor(event.getColor()); - for (final ColorSelector select : colorPickerLayout.getSelectors()) { - if (!event.getSource().equals(select) && select.equals(this) - && !select.getColor().equals(colorPickerLayout.getSelectedColor())) { - select.setColor(colorPickerLayout.getSelectedColor()); - } - } - ColorPickerHelper.setRgbSliderValues(colorPickerLayout); - getPreviewButtonColor(event.getColor().getCSS()); - createDynamicStyleForComponents(tagName, tagDesc, event.getColor().getCSS()); + protected void disableFields() { + // can be overwritten } /** @@ -404,7 +284,6 @@ public abstract class AbstractCreateUpdateTagLayout exten */ protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc, final String taregtTagColor) { - tagName.removeStyleName(SPUIDefinitions.TAG_NAME); tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC); getTargetDynamicStyles(taregtTagColor); @@ -423,15 +302,33 @@ public abstract class AbstractCreateUpdateTagLayout exten getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); } - /** - * Get target style - Dynamically as per the color picked, cannot be done - * from the static css. - * - * @param colorPickedPreview - */ - private static void getTargetDynamicStyles(final String colorPickedPreview) { - Page.getCurrent().getJavaScript() - .execute(HawkbitCommonUtil.changeToNewSelectedPreviewColor(colorPickedPreview)); + protected void setColorToComponents(final Color newColor) { + setColor(newColor); + colorPickerLayout.getColorSelect().setColor(newColor); + getPreviewButtonColor(newColor.getCSS()); + createDynamicStyleForComponents(tagName, tagDesc, newColor.getCSS()); + } + + protected void displaySuccess(final String tagName) { + uiNotification.displaySuccess(i18n.getMessage("message.save.success", tagName)); + } + + protected void displayValidationError(final String errorMessage) { + uiNotification.displayValidationError(errorMessage); + } + + protected void setTagColor(final Color selectedColor, final String previewColor) { + getColorPickerLayout().setSelectedColor(selectedColor); + getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); + getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); + createDynamicStyleForComponents(tagName, tagDesc, previewColor); + getPreviewButtonColor(previewColor); + } + + protected abstract boolean isUpdateAction(); + + protected boolean isDuplicate() { + return isDuplicateByName(); } @Override @@ -447,168 +344,55 @@ public abstract class AbstractCreateUpdateTagLayout exten colorPickerLayout.setSelectedColor(color); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); final String colorPickedPreview = colorPickerLayout.getSelPreview().getColor().getCSS(); - if (tagName.isEnabled() && null != colorPickerLayout.getColorSelect()) { + if (colorPickerLayout.getColorSelect() != null) { createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview); colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - - } - - /** - * create option group with Create tag/Update tag based on permissions. - */ - protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { - - optiongroup = new OptionGroup("Select Action"); - optiongroup.setId(UIComponentIdProvider.OPTION_GROUP); - optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL); - optiongroup.addStyleName("custom-option-group"); - optiongroup.setNullSelectionAllowed(false); - - if (hasCreatePermission) { - optiongroup.addItem(createTagStr); - } - if (hasUpdatePermission) { - optiongroup.addItem(updateTagStr); - } - - setOptionGroupDefaultValue(hasCreatePermission, hasUpdatePermission); - } - - protected void setOptionGroupDefaultValue(final boolean hasCreatePermission, final boolean hasUpdatePermission) { - - if (hasCreatePermission) { - optiongroup.select(createTagStr); - } - if (hasUpdatePermission && !hasCreatePermission) { - optiongroup.select(updateTagStr); - } } public ColorPickerLayout getColorPickerLayout() { return colorPickerLayout; } - public CommonDialogWindow getWindow() { - reset(); + /** + * Creates the window to create or update a tag or type + * + * @return the created window + */ + public CommonDialogWindow createWindow() { window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(getWindowCaption()).content(this) .cancelButtonClickListener(event -> discard()).layout(mainLayout).i18n(i18n) .saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow(); return window; } - /** - * Value change listeners implementations of sliders. - */ - private void slidersValueChangeListeners() { - colorPickerLayout.getRedSlider().addValueChangeListener(new ValueChangeListener() { - private static final long serialVersionUID = -8336732888800920839L; - - @Override - public void valueChange(final ValueChangeEvent event) { - final double red = (Double) event.getProperty().getValue(); - final Color newColor = new Color((int) red, colorPickerLayout.getSelectedColor().getGreen(), - colorPickerLayout.getSelectedColor().getBlue()); - setColorToComponents(newColor); + @Override + public void colorChanged(final ColorChangeEvent event) { + setColor(event.getColor()); + for (final ColorSelector select : colorPickerLayout.getSelectors()) { + if (!event.getSource().equals(select) && select.equals(this) + && !select.getColor().equals(colorPickerLayout.getSelectedColor())) { + select.setColor(colorPickerLayout.getSelectedColor()); } - }); - colorPickerLayout.getGreenSlider().addValueChangeListener(new ValueChangeListener() { - private static final long serialVersionUID = 1236358037766775663L; - - @Override - public void valueChange(final ValueChangeEvent event) { - final double green = (Double) event.getProperty().getValue(); - final Color newColor = new Color(colorPickerLayout.getSelectedColor().getRed(), (int) green, - colorPickerLayout.getSelectedColor().getBlue()); - setColorToComponents(newColor); - } - }); - colorPickerLayout.getBlueSlider().addValueChangeListener(new ValueChangeListener() { - private static final long serialVersionUID = 8466370763686043947L; - - @Override - public void valueChange(final ValueChangeEvent event) { - final double blue = (Double) event.getProperty().getValue(); - final Color newColor = new Color(colorPickerLayout.getSelectedColor().getRed(), - colorPickerLayout.getSelectedColor().getGreen(), (int) blue); - setColorToComponents(newColor); - } - }); + } + ColorPickerHelper.setRgbSliderValues(colorPickerLayout); + getPreviewButtonColor(event.getColor().getCSS()); + createDynamicStyleForComponents(tagName, tagDesc, event.getColor().getCSS()); } - protected void setColorToComponents(final Color newColor) { - setColor(newColor); - colorPickerLayout.getColorSelect().setColor(newColor); - getPreviewButtonColor(newColor.getCSS()); - createDynamicStyleForComponents(tagName, tagDesc, newColor.getCSS()); - } - - /** - * Create new tag. - */ - protected void createNewTag() { - colorPicked = ColorPickerHelper.getColorPickedString(colorPickerLayout.getSelPreview()); - tagNameValue = tagName.getValue(); - tagDescValue = tagDesc.getValue(); - } - - protected void displaySuccess(final String tagName) { - uiNotification.displaySuccess(i18n.getMessage("message.save.success", new Object[] { tagName })); - } - - protected void displayValidationError(final String errorMessage) { - uiNotification.displayValidationError(errorMessage); - } - - protected void setTagColor(final Color selectedColor, final String previewColor) { - getColorPickerLayout().setSelectedColor(selectedColor); - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); - createDynamicStyleForComponents(tagName, tagDesc, previewColor); - getPreviewButtonColor(previewColor); - } - - private boolean isDuplicateByName() { - final Optional existingType = findEntityByName(); - existingType.ifPresent(type -> uiNotification.displayValidationError( - i18n.getMessage("message.tag.duplicate.check", new Object[] { type.getName() }))); - - return existingType.isPresent(); - } - - protected boolean isDuplicate() { - return isDuplicateByName(); - } - - public String getColorPicked() { + protected String getColorPicked() { return colorPicked; } - public void setColorPicked(final String colorPicked) { + protected void setColorPicked(final String colorPicked) { this.colorPicked = colorPicked; } - public String getTagNameValue() { - return tagNameValue; - } - - public void setTagNameValue(final String tagNameValue) { - this.tagNameValue = tagNameValue; - } - - public String getTagDescValue() { - return tagDescValue; - } - - public void setTagDescValue(final String tagDescValue) { - this.tagDescValue = tagDescValue; - } - - public FormLayout getFormLayout() { + protected FormLayout getFormLayout() { return formLayout; } - public GridLayout getMainLayout() { + protected GridLayout getMainLayout() { return mainLayout; } @@ -620,12 +404,166 @@ public abstract class AbstractCreateUpdateTagLayout exten public void removeColorChangeListener(final ColorChangeListener listener) { } - protected abstract Optional findEntityByName(); + protected static String getTagNameDynamicStyle() { + return TAG_NAME_DYNAMIC_STYLE; + } - protected abstract String getWindowCaption(); + protected static String getTagDescDynamicStyle() { + return TAG_DESC_DYNAMIC_STYLE; + } - protected abstract void updateEntity(E entity); + protected static String getTagDynamicStyle() { + return TAG_DYNAMIC_STYLE; + } - protected abstract void createEntity(); + protected static String getMessageErrorMissingTagname() { + return MESSAGE_ERROR_MISSING_TAGNAME; + } + + protected static int getMaxTags() { + return MAX_TAGS; + } + + protected VaadinMessageSource getI18n() { + return i18n; + } + + protected EntityFactory getEntityFactory() { + return entityFactory; + } + + protected EventBus.UIEventBus getEventBus() { + return eventBus; + } + + protected SpPermissionChecker getPermChecker() { + return permChecker; + } + + protected UINotification getUiNotification() { + return uiNotification; + } + + protected Label getColorLabel() { + return colorLabel; + } + + protected TextField getTagName() { + return tagName; + } + + protected TextArea getTagDesc() { + return tagDesc; + } + + protected Button getTagColorPreviewBtn() { + return tagColorPreviewBtn; + } + + protected VerticalLayout getContentLayout() { + return contentLayout; + } + + protected boolean isTagPreviewBtnClicked() { + return tagPreviewBtnClicked; + } + + protected HorizontalLayout getColorLabelLayout() { + return colorLabelLayout; + } + + protected void setTagName(final TextField tagName) { + this.tagName = tagName; + } + + protected void setTagDesc(final TextArea tagDesc) { + this.tagDesc = tagDesc; + } + + protected void setTagColorPreviewBtn(final Button tagColorPreviewBtn) { + this.tagColorPreviewBtn = tagColorPreviewBtn; + } + + /** + * Open color picker on click of preview button. Auto select the color based + * on target tag if already selected. + */ + private void previewButtonClicked() { + if (!tagPreviewBtnClicked) { + colorPickerLayout + .setSelectedColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); + } + + tagPreviewBtnClicked = !tagPreviewBtnClicked; + colorPickerLayout.setVisible(tagPreviewBtnClicked); + } + + /** + * Get target style - Dynamically as per the color picked, cannot be done + * from the static css. + * + * @param colorPickedPreview + */ + private static void getTargetDynamicStyles(final String colorPickedPreview) { + Page.getCurrent().getJavaScript() + .execute(HawkbitCommonUtil.changeToNewSelectedPreviewColor(colorPickedPreview)); + } + + /** + * Value change listeners implementations of sliders. + */ + private void slidersValueChangeListeners() { + colorPickerLayout.getRedSlider().addValueChangeListener(new ValueChangeListener() { + private static final long serialVersionUID = 1L; + + @Override + public void valueChange(final ValueChangeEvent event) { + final double red = (Double) event.getProperty().getValue(); + final Color newColor = new Color((int) red, colorPickerLayout.getSelectedColor().getGreen(), + colorPickerLayout.getSelectedColor().getBlue()); + setColorToComponents(newColor); + } + }); + colorPickerLayout.getGreenSlider().addValueChangeListener(new ValueChangeListener() { + private static final long serialVersionUID = 1L; + + @Override + public void valueChange(final ValueChangeEvent event) { + final double green = (Double) event.getProperty().getValue(); + final Color newColor = new Color(colorPickerLayout.getSelectedColor().getRed(), (int) green, + colorPickerLayout.getSelectedColor().getBlue()); + setColorToComponents(newColor); + } + }); + colorPickerLayout.getBlueSlider().addValueChangeListener(new ValueChangeListener() { + private static final long serialVersionUID = 1L; + + @Override + public void valueChange(final ValueChangeEvent event) { + final double blue = (Double) event.getProperty().getValue(); + final Color newColor = new Color(colorPickerLayout.getSelectedColor().getRed(), + colorPickerLayout.getSelectedColor().getGreen(), (int) blue); + setColorToComponents(newColor); + } + }); + } + + private boolean isDuplicateByName() { + final Optional existingType = findEntityByName(); + existingType.ifPresent(type -> uiNotification + .displayValidationError(i18n.getMessage("message.tag.duplicate.check", type.getName()))); + return existingType.isPresent(); + } + + private void openConfigureWindow() { + createWindow(); + UI.getCurrent().addWindow(window); + window.setModal(true); + window.setVisible(Boolean.TRUE); + } + + protected CommonDialogWindow getWindow() { + return window; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTypeLayout.java similarity index 50% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTypeLayout.java index d6823cfbd..f83f1b8d1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractTypeLayout.java @@ -15,211 +15,70 @@ import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; -import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; -import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.Button; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.components.colorpicker.ColorChangeEvent; import com.vaadin.ui.components.colorpicker.ColorSelector; +import com.vaadin.ui.themes.ValoTheme; /** - * Superclass defining common properties and methods for creating/updating - * types. + * Superclass defining common properties and methods for creating types. + * + * @param + * entity */ -public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { +public abstract class AbstractTypeLayout extends AbstractTagLayout { - private static final long serialVersionUID = 5732904956185988397L; + private static final long serialVersionUID = 1L; - protected TextField typeKey; + private TextField typeKey; private static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; + private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; - public CreateUpdateTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + */ + public AbstractTypeLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification) { super(i18n, entityFactory, eventBus, permChecker, uiNotification); } - @Override - protected boolean doSubscribeToEventBus() { - return false; - } - - @Override - protected void addListeners() { - super.addListeners(); - optiongroup.addValueChangeListener(this::optionValueChanged); - } - - @Override - protected void createRequiredComponents() { - - createTagStr = i18n.getMessage("label.create.type"); - updateTagStr = i18n.getMessage("label.update.type"); - comboLabel = new LabelBuilder().name(i18n.getMessage("label.choose.type")).buildLabel(); - colorLabel = new LabelBuilder().name(i18n.getMessage("label.choose.type.color")).buildLabel(); - colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); - - tagNameComboBox = SPUIComponentProvider.getComboBox(i18n.getMessage("label.combobox.type"), "", null, null, - false, "", i18n.getMessage("label.combobox.type")); - tagNameComboBox.setId(SPUIDefinitions.NEW_DISTRIBUTION_SET_TYPE_NAME_COMBO); - tagNameComboBox.addStyleName(SPUIDefinitions.FILTER_TYPE_COMBO_STYLE); - tagNameComboBox.setImmediate(true); - tagNameComboBox.setPageLength(SPUIDefinitions.DIST_TYPE_SIZE); - - tagColorPreviewBtn = new Button(); - tagColorPreviewBtn.setId(UIComponentIdProvider.TAG_COLOR_PREVIEW_ID); - getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); - tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); - - createOptionGroup(permChecker.hasCreateRepositoryPermission(), permChecker.hasUpdateRepositoryPermission()); - } - - @Override - protected void setColorToComponents(final Color newColor) { - - super.setColorToComponents(newColor); - createDynamicStyleForComponents(tagName, typeKey, tagDesc, newColor.getCSS()); - } - - /** - * Set tag name and desc field border color based on chosen color. - * - * @param tagName - * @param tagDesc - * @param taregtTagColor - */ - private void createDynamicStyleForComponents(final TextField tagName, final TextField typeKey, - final TextArea typeDesc, final String typeTagColor) { - - tagName.removeStyleName(SPUIDefinitions.TYPE_NAME); - typeKey.removeStyleName(SPUIDefinitions.TYPE_KEY); - typeDesc.removeStyleName(SPUIDefinitions.TYPE_DESC); - getDynamicStyles(typeTagColor); - tagName.addStyleName(TYPE_NAME_DYNAMIC_STYLE); - typeKey.addStyleName(TYPE_NAME_DYNAMIC_STYLE); - typeDesc.addStyleName(TYPE_DESC_DYNAMIC_STYLE); - } - - /** - * Get target style - Dynamically as per the color picked, cannot be done - * from the static css. - * - * @param colorPickedPreview - */ - private void getDynamicStyles(final String colorPickedPreview) { - - Page.getCurrent().getJavaScript() - .execute(HawkbitCommonUtil.changeToNewSelectedPreviewColor(colorPickedPreview)); - } - - /** - * reset the components. - */ - @Override - protected void reset() { - - super.reset(); - typeKey.clear(); - restoreComponentStyles(); - setOptionGroupDefaultValue(permChecker.hasCreateRepositoryPermission(), - permChecker.hasUpdateRepositoryPermission()); - } - - /** - * Listener for option group - Create tag/Update. - * - * @param event - * ValueChangeEvent - */ - @Override - protected void optionValueChanged(final ValueChangeEvent event) { - - if (updateTagStr.equals(event.getProperty().getValue())) { - tagName.clear(); - tagDesc.clear(); - typeKey.clear(); - typeKey.setEnabled(false); - tagName.setEnabled(false); - populateTagNameCombo(); - comboLayout.addComponent(comboLabel); - comboLayout.addComponent(tagNameComboBox); - } else { - typeKey.setEnabled(true); - tagName.setEnabled(true); - tagName.clear(); - tagDesc.clear(); - typeKey.clear(); - comboLayout.removeComponent(comboLabel); - comboLayout.removeComponent(tagNameComboBox); - } - restoreComponentStyles(); - getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); - getColorPickerLayout().getSelPreview() - .setColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.components.colorpicker.ColorSelector#setColor(com.vaadin. - * shared.ui.colorpicker .Color) - */ @Override public void setColor(final Color color) { - if (color == null) { return; } getColorPickerLayout().setSelectedColor(color); getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); final String colorPickedPreview = getColorPickerLayout().getSelPreview().getColor().getCSS(); - if (tagName.isEnabled() && null != getColorPickerLayout().getColorSelect()) { - createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); + if (getTagName().isEnabled() && null != getColorPickerLayout().getColorSelect()) { + createDynamicStyleForComponents(getTagName(), typeKey, getTagDesc(), colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } } - /** - * reset the tag name and tag description component border color. - */ - @Override - protected void restoreComponentStyles() { - super.restoreComponentStyles(); - typeKey.removeStyleName(TYPE_NAME_DYNAMIC_STYLE); - typeKey.addStyleName(SPUIDefinitions.TYPE_KEY); - } - - protected void setColorPickerComponentsColor(final String color) { - - if (null == color) { - getColorPickerLayout() - .setSelectedColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); - createDynamicStyleForComponents(tagName, typeKey, tagDesc, ColorPickerConstants.DEFAULT_COLOR); - getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); - } else { - getColorPickerLayout().setSelectedColor(ColorPickerHelper.rgbToColorConverter(color)); - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); - createDynamicStyleForComponents(tagName, typeKey, tagDesc, color); - getPreviewButtonColor(color); - } - } - @Override public void colorChanged(final ColorChangeEvent event) { setColor(event.getColor()); @@ -231,15 +90,58 @@ public abstract class CreateUpdateTypeLayout extends Abst } ColorPickerHelper.setRgbSliderValues(getColorPickerLayout()); getPreviewButtonColor(event.getColor().getCSS()); - createDynamicStyleForComponents(tagName, typeKey, tagDesc, event.getColor().getCSS()); + createDynamicStyleForComponents(getTagName(), typeKey, getTagDesc(), event.getColor().getCSS()); } - private boolean isDuplicateByKey() { - final Optional existingType = findEntityByKey(); + @Override + protected void buildLayout() { + super.buildLayout(); + ColorPickerHelper.setRgbSliderValues(getColorPickerLayout()); + getFormLayout().addComponent(typeKey); + } - existingType.ifPresent(type -> uiNotification.displayValidationError(getDuplicateKeyErrorMessage(type))); + @Override + protected void createRequiredComponents() { + super.createRequiredComponents(); + typeKey = new TextFieldBuilder(getTypeKeySize()).id(getTypeKeyId()) + .caption(getI18n().getMessage("textfield.key")) + .styleName(ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY).required(true, getI18n()) + .prompt(getI18n().getMessage("textfield.key")).immediate(true).buildTextComponent(); + getColorLabel().setValue(getI18n().getMessage("label.choose.type.color")); + } - return existingType.isPresent(); + protected abstract String getTypeKeyId(); + + protected abstract int getTypeKeySize(); + + @Override + protected void setColorToComponents(final Color newColor) { + super.setColorToComponents(newColor); + createDynamicStyleForComponents(getTagName(), typeKey, getTagDesc(), newColor.getCSS()); + } + + @Override + protected void restoreComponentStyles() { + super.restoreComponentStyles(); + typeKey.removeStyleName(TYPE_NAME_DYNAMIC_STYLE); + typeKey.addStyleName(SPUIDefinitions.TYPE_KEY); + } + + protected void setColorPickerComponentsColor(final String color) { + if (color == null) { + getColorPickerLayout() + .setSelectedColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); + getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); + getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); + createDynamicStyleForComponents(getTagName(), typeKey, getTagDesc(), ColorPickerConstants.DEFAULT_COLOR); + getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); + } else { + getColorPickerLayout().setSelectedColor(ColorPickerHelper.rgbToColorConverter(color)); + getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); + getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); + createDynamicStyleForComponents(getTagName(), typeKey, getTagDesc(), color); + getPreviewButtonColor(color); + } } @Override @@ -247,18 +149,41 @@ public abstract class CreateUpdateTypeLayout extends Abst return isDuplicateByKey() || super.isDuplicate(); } + @Override + protected void resetFields() { + super.resetFields(); + typeKey.clear(); + typeKey.setEnabled(true); + } + protected abstract Optional findEntityByKey(); protected abstract String getDuplicateKeyErrorMessage(E existingType); - @Override - protected void populateTagNameCombo() { - // is implemented in the inherited class + private static void createDynamicStyleForComponents(final TextField tagName, final TextField typeKey, + final TextArea typeDesc, final String typeTagColor) { + tagName.removeStyleName(SPUIDefinitions.TYPE_NAME); + typeKey.removeStyleName(SPUIDefinitions.TYPE_KEY); + typeDesc.removeStyleName(SPUIDefinitions.TYPE_DESC); + getDynamicStyles(typeTagColor); + tagName.addStyleName(TYPE_NAME_DYNAMIC_STYLE); + typeKey.addStyleName(TYPE_NAME_DYNAMIC_STYLE); + typeDesc.addStyleName(TYPE_DESC_DYNAMIC_STYLE); } - @Override - protected void setTagDetails(final String tagSelected) { - // is implemented in the inherited class + private static void getDynamicStyles(final String colorPickedPreview) { + Page.getCurrent().getJavaScript() + .execute(HawkbitCommonUtil.changeToNewSelectedPreviewColor(colorPickedPreview)); + } + + private boolean isDuplicateByKey() { + final Optional existingType = findEntityByKey(); + existingType.ifPresent(type -> getUiNotification().displayValidationError(getDuplicateKeyErrorMessage(type))); + return existingType.isPresent(); + } + + public TextField getTypeKey() { + return typeKey; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/UpdateTag.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/UpdateTag.java new file mode 100644 index 000000000..47da8c2ce --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/UpdateTag.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.layouts; + +/** + * Interface which is implemented in tags and types layout classes for updating + * a tag or type. + */ +@FunctionalInterface +public interface UpdateTag { + + /** + * Provides the update tag or type dialog with the tag or type information + * + * @param selectedTagName + * the name of the selected tag + */ + void setTagDetails(final String selectedTagName); + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java similarity index 80% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java index b021a743c..4cd56b4ae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/CountMessageLabel.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.footer; +package org.eclipse.hawkbit.ui.management; import java.util.List; import java.util.Optional; @@ -22,7 +22,7 @@ import org.eclipse.hawkbit.ui.management.state.TargetTableFilters; import org.eclipse.hawkbit.ui.management.targettable.TargetTable; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -38,7 +38,8 @@ import com.vaadin.ui.Label; * pinning. */ public class CountMessageLabel extends Label { - private static final long serialVersionUID = -1533826352473259653L; + + private static final long serialVersionUID = 1L; private final transient TargetManagement targetManagement; @@ -77,12 +78,12 @@ public class CountMessageLabel extends Label { * TenantAwareEvent Listener to show the message count. * * @param event + * ManagementUIEvent which describes the action to execute */ @EventBusListenerMethod(scope = EventScope.UI) public void onEvent(final ManagementUIEvent event) { if (event == ManagementUIEvent.TARGET_TABLE_FILTER || event == ManagementUIEvent.SHOW_COUNT_MESSAGE) { displayTargetCountStatus(); - } } @@ -92,7 +93,6 @@ public class CountMessageLabel extends Label { || TargetComponentEvent.REFRESH_TARGETS == event.getTargetComponentEvent()) { displayTargetCountStatus(); } - } /** @@ -112,21 +112,17 @@ public class CountMessageLabel extends Label { } } - /** - * - */ private void applyStyle() { - /* Create label for Targets count message displaying below the table */ - addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); + addStyleName(SPUIStyleDefinitions.SP_LABEL_MESSAGE_STYLE); setContentMode(ContentMode.HTML); setId(UIComponentIdProvider.COUNT_LABEL); } private void displayTargetCountStatus() { - final TargetTableFilters targFilParams = managementUIState.getTargetTableFilters(); + final TargetTableFilters targetFilterParams = managementUIState.getTargetTableFilters(); final StringBuilder message = getTotalTargetMessage(); - if (targFilParams.hasFilter()) { + if (targetFilterParams.hasFilter()) { message.append(HawkbitCommonUtil.SP_STRING_PIPE); message.append(i18n.getMessage("label.filter.targets")); if (managementUIState.getTargetsTruncated() != null) { @@ -143,13 +139,13 @@ public class CountMessageLabel extends Label { final String custom = i18n.getMessage("label.filter.custom"); final StringBuilder filterMesgBuf = new StringBuilder(i18n.getMessage("label.filter")); filterMesgBuf.append(" "); - filterMesgBuf.append(getStatusMsg(targFilParams.getClickedStatusTargetTags(), status)); - filterMesgBuf.append(getOverdueStateMsg(targFilParams.isOverdueFilterEnabled(), overdue)); - filterMesgBuf - .append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags)); - filterMesgBuf.append(targFilParams.getSearchText().map(search -> text).orElse(" ")); - filterMesgBuf.append(targFilParams.getDistributionSet().map(set -> dists).orElse(" ")); - filterMesgBuf.append(targFilParams.getTargetFilterQuery().map(query -> custom).orElse(" ")); + filterMesgBuf.append(getStatusMsg(targetFilterParams.getClickedStatusTargetTags(), status)); + filterMesgBuf.append(getOverdueStateMsg(targetFilterParams.isOverdueFilterEnabled(), overdue)); + filterMesgBuf.append( + getTagsMsg(targetFilterParams.isNoTagSelected(), targetFilterParams.getClickedTargetTags(), tags)); + filterMesgBuf.append(targetFilterParams.getSearchText().map(search -> text).orElse(" ")); + filterMesgBuf.append(targetFilterParams.getDistributionSet().map(set -> dists).orElse(" ")); + filterMesgBuf.append(targetFilterParams.getTargetFilterQuery().map(query -> custom).orElse(" ")); final String filterMesageChk = filterMesgBuf.toString().trim(); String filterMesage = filterMesageChk; if (filterMesage.endsWith(",")) { @@ -170,7 +166,6 @@ public class CountMessageLabel extends Label { private StringBuilder getTotalTargetMessage() { if (managementUIState.getTargetsTruncated() != null) { - // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.getMessage("label.target.filter.truncated", managementUIState.getTargetsTruncated(), SPUIDefinitions.MAX_TABLE_ENTRIES)); @@ -185,56 +180,27 @@ public class CountMessageLabel extends Label { return message; } - /** - * Display message. - * - * @param distId - * as dist ID - */ private void displayCountLabel(final Long distId) { final Long targetsWithAssigedDsCount = targetManagement.countByAssignedDistributionSet(distId); final Long targetsWithInstalledDsCount = targetManagement.countByInstalledDistributionSet(distId); final StringBuilder message = new StringBuilder(i18n.getMessage("label.target.count")); message.append(""); - message.append(i18n.getMessage("label.assigned.count", new Object[] { targetsWithAssigedDsCount })); + message.append(i18n.getMessage("label.assigned.count", targetsWithAssigedDsCount)); message.append(", "); - message.append(i18n.getMessage("label.installed.count", new Object[] { targetsWithInstalledDsCount })); + message.append(i18n.getMessage("label.installed.count", targetsWithInstalledDsCount)); message.append(""); setValue(message.toString()); } - /** - * Get Status Message. - * - * @param status - * as status - * @return String as msg. - */ private static String getStatusMsg(final List status, final String param) { return status.isEmpty() ? " " : param; } - /** - * Get Overdue State Message. - * - * @param overdueState - * as flag - * @return String as msg. - */ private static String getOverdueStateMsg(final boolean overdueState, final String param) { return !overdueState ? " " : param; } - /** - * Get Tags Message. - * - * @param noTargetTagSelected - * @param tags - * as tags - * @return String as msg. - */ private static String getTagsMsg(final Boolean noTargetTagSelected, final List tags, final String param) { - return tags.isEmpty() && (noTargetTagSelected == null || !noTargetTagSelected.booleanValue()) - ? " " : param; + return tags.isEmpty() && (noTargetTagSelected == null || !noTargetTagSelected.booleanValue()) ? " " : param; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java index b48ae3556..6629cff3e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java @@ -36,17 +36,16 @@ import org.eclipse.hawkbit.ui.management.actionhistory.ActionStatusLayout; import org.eclipse.hawkbit.ui.management.actionhistory.ActionStatusMsgGrid; import org.eclipse.hawkbit.ui.management.actionhistory.ActionStatusMsgLayout; import org.eclipse.hawkbit.ui.management.dstable.DistributionTableLayout; -import org.eclipse.hawkbit.ui.management.dstag.DistributionTagLayout; +import org.eclipse.hawkbit.ui.management.dstag.filter.DistributionTagButtons; +import org.eclipse.hawkbit.ui.management.dstag.filter.DistributionTagLayout; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; -import org.eclipse.hawkbit.ui.management.footer.DeleteActionsLayout; import org.eclipse.hawkbit.ui.management.state.DistributionTableFilters; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.targettable.TargetTable; import org.eclipse.hawkbit.ui.management.targettable.TargetTableLayout; -import org.eclipse.hawkbit.ui.management.targettag.CreateUpdateTargetTagLayoutWindow; -import org.eclipse.hawkbit.ui.management.targettag.TargetTagFilterLayout; +import org.eclipse.hawkbit.ui.management.targettag.filter.TargetTagFilterLayout; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; import org.eclipse.hawkbit.ui.push.DistributionSetCreatedEventContainer; import org.eclipse.hawkbit.ui.push.DistributionSetDeletedEventContainer; @@ -111,20 +110,19 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW private final DistributionTableLayout distributionTableLayout; - private final DeleteActionsLayout deleteAndActionsLayout; - private GridLayout mainLayout; private final DeploymentViewMenuItem deploymentViewMenuItem; + private CountMessageLabel countMessageLabel; + @Autowired - DeploymentView(final UIEventBus eventbus, final SpPermissionChecker permChecker, final VaadinMessageSource i18n, + DeploymentView(final UIEventBus eventBus, final SpPermissionChecker permChecker, final VaadinMessageSource i18n, final UINotification uiNotification, final ManagementUIState managementUIState, - final DeploymentManagement deploymentManagement, final UIEventBus eventBus, - final DistributionTableFilters distFilterParameters, + final DeploymentManagement deploymentManagement, final DistributionTableFilters distFilterParameters, final DistributionSetManagement distributionSetManagement, final DistributionSetTypeManagement distributionSetTypeManagement, final TargetManagement targetManagement, - final EntityFactory entityFactory, final UiProperties uiproperties, + final EntityFactory entityFactory, final UiProperties uiProperties, final ManagementViewClientCriterion managementViewClientCriterion, final TargetTagManagement targetTagManagement, final DistributionSetTagManagement distributionSetTagManagement, @@ -144,22 +142,18 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW managementUIState); this.actionStatusLayout = new ActionStatusLayout(i18n, eventBus, managementUIState); this.actionStatusMsgLayout = new ActionStatusMsgLayout(i18n, eventBus, managementUIState); - final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout = new CreateUpdateTargetTagLayoutWindow( - i18n, targetTagManagement, entityFactory, eventBus, permChecker, uiNotification); - this.targetTagFilterLayout = new TargetTagFilterLayout(i18n, createUpdateTargetTagLayout, managementUIState, + this.targetTagFilterLayout = new TargetTagFilterLayout(i18n, managementUIState, managementViewClientCriterion, permChecker, eventBus, uiNotification, entityFactory, - targetFilterQueryManagement); + targetFilterQueryManagement, targetTagManagement); final TargetTable targetTable = new TargetTable(eventBus, i18n, uiNotification, targetManagement, managementUIState, permChecker, managementViewClientCriterion, distributionSetManagement, - targetTagManagement); + targetTagManagement, deploymentManagement, uiProperties); + this.countMessageLabel = new CountMessageLabel(eventBus, targetManagement, i18n, managementUIState, + targetTable); - this.targetTableLayout = new TargetTableLayout(eventbus, targetTable, targetManagement, entityFactory, i18n, - eventBus, uiNotification, managementUIState, managementViewClientCriterion, deploymentManagement, - uiproperties, permChecker, uiNotification, targetTagManagement, distributionSetManagement, - uiExecutor); - this.deleteAndActionsLayout = new DeleteActionsLayout(i18n, permChecker, eventBus, uiNotification, - targetTagManagement, distributionSetTagManagement, managementViewClientCriterion, managementUIState, - targetManagement, targetTable, deploymentManagement, distributionSetManagement, uiproperties); + this.targetTableLayout = new TargetTableLayout(eventBus, targetTable, targetManagement, entityFactory, i18n, + uiNotification, managementUIState, managementViewClientCriterion, deploymentManagement, + uiProperties, permChecker, targetTagManagement, distributionSetManagement, uiExecutor); actionHistoryLayout.registerDetails(((ActionStatusGrid) actionStatusLayout.getGrid()).getDetailsSupport()); actionStatusLayout @@ -170,22 +164,22 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW this.actionStatusMsgLayout = null; this.targetTagFilterLayout = null; this.targetTableLayout = null; - this.deleteAndActionsLayout = null; } if (permChecker.hasReadRepositoryPermission()) { - this.distributionTagLayout = new DistributionTagLayout(eventbus, managementUIState, i18n, permChecker, - eventBus, distributionSetTagManagement, entityFactory, uiNotification, distFilterParameters, - distributionSetManagement, managementViewClientCriterion); + final DistributionTagButtons distributionTagButtons = new DistributionTagButtons(eventBus, + managementUIState, entityFactory, i18n, uiNotification, permChecker, distFilterParameters, + distributionSetManagement, managementViewClientCriterion, distributionSetTagManagement); + this.distributionTagLayout = new DistributionTagLayout(eventBus, managementUIState, i18n, permChecker, + distributionSetTagManagement, entityFactory, uiNotification, distributionTagButtons); this.distributionTableLayout = new DistributionTableLayout(i18n, eventBus, permChecker, managementUIState, distributionSetManagement, distributionSetTypeManagement, managementViewClientCriterion, entityFactory, uiNotification, distributionSetTagManagement, targetTagManagement, systemManagement, - targetManagement, deploymentManagement); + targetManagement, deploymentManagement, uiProperties); } else { this.distributionTagLayout = null; this.distributionTableLayout = null; } - } @PostConstruct @@ -251,11 +245,10 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW } private void buildLayout() { - // Build only if user has both permissions if (permChecker.hasTargetReadPermission() || permChecker.hasReadRepositoryPermission()) { setSizeFull(); createMainLayout(); - addComponents(mainLayout); + addComponent(mainLayout, 0); setExpandRatio(mainLayout, 1); } } @@ -266,6 +259,7 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW mainLayout.setSizeFull(); mainLayout.setSpacing(true); mainLayout.setRowExpandRatio(0, 1F); + mainLayout.setStyleName("fullSize"); } private void layoutWidgets() { @@ -281,60 +275,41 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW private void displayAllWidgets() { mainLayout.setColumns(5); - mainLayout.setRows(2); + mainLayout.setRows(1); mainLayout.addComponent(targetTagFilterLayout, 0, 0); mainLayout.addComponent(targetTableLayout, 1, 0); mainLayout.addComponent(distributionTableLayout, 2, 0); mainLayout.addComponent(distributionTagLayout, 3, 0); mainLayout.addComponent(actionHistoryLayout, 4, 0); + showTargetCount(); mainLayout.setColumnExpandRatio(0, 0F); mainLayout.setColumnExpandRatio(1, 0.275F); mainLayout.setColumnExpandRatio(2, 0.275F); mainLayout.setColumnExpandRatio(3, 0F); mainLayout.setColumnExpandRatio(4, 0.45F); - if (showFooterLayout()) { - mainLayout.addComponent(deleteAndActionsLayout, 1, 1, 2, 1); - mainLayout.setComponentAlignment(deleteAndActionsLayout, Alignment.BOTTOM_CENTER); - } + } + + private void showTargetCount() { + addComponent(countMessageLabel); } private void displayDistributionWidgetsOnly() { mainLayout.setColumns(2); - mainLayout.setRows(2); + mainLayout.setRows(1); mainLayout.addComponent(distributionTableLayout, 0, 0); mainLayout.addComponent(distributionTagLayout, 1, 0); mainLayout.setColumnExpandRatio(0, 1F); - if (showFooterLayout()) { - mainLayout.addComponent(deleteAndActionsLayout, 0, 1); - mainLayout.setComponentAlignment(deleteAndActionsLayout, Alignment.BOTTOM_CENTER); - } - } - - private Boolean showFooterLayout() { - if (permChecker.hasTargetReadPermission() - || (permChecker.hasDeleteRepositoryPermission() || permChecker.hasDeleteTargetPermission()) - || hasDeploymentPermission()) { - return true; - } - return false; - } - - private boolean hasDeploymentPermission() { - return permChecker.hasReadRepositoryPermission() && permChecker.hasUpdateTargetPermission(); } private void displayTargetWidgetsOnly() { mainLayout.setColumns(3); - mainLayout.setRows(2); + mainLayout.setRows(1); mainLayout.addComponent(targetTagFilterLayout, 0, 0); mainLayout.addComponent(targetTableLayout, 1, 0); mainLayout.addComponent(actionHistoryLayout, 2, 0); + showTargetCount(); mainLayout.setColumnExpandRatio(1, 0.4F); mainLayout.setColumnExpandRatio(2, 0.6F); - if (showFooterLayout()) { - mainLayout.addComponent(deleteAndActionsLayout, 1, 1); - mainLayout.setComponentAlignment(deleteAndActionsLayout, Alignment.BOTTOM_CENTER); - } } private void maximizeTargetTable() { @@ -343,7 +318,7 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW mainLayout.removeComponent(distributionTagLayout); } mainLayout.removeComponent(actionHistoryLayout); - mainLayout.removeComponent(deleteAndActionsLayout); + removeComponent(countMessageLabel); mainLayout.setColumnExpandRatio(1, 1F); mainLayout.setColumnExpandRatio(2, 0F); mainLayout.setColumnExpandRatio(3, 0F); @@ -355,8 +330,8 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW mainLayout.removeComponent(targetTagFilterLayout); mainLayout.removeComponent(targetTableLayout); mainLayout.removeComponent(actionHistoryLayout); + removeComponent(countMessageLabel); } - mainLayout.removeComponent(deleteAndActionsLayout); mainLayout.setColumnExpandRatio(0, 0F); mainLayout.setColumnExpandRatio(1, 0F); mainLayout.setColumnExpandRatio(2, 1F); @@ -364,6 +339,7 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW } private void maximizeActionHistory() { + removeComponent(countMessageLabel); mainLayout.removeAllComponents(); mainLayout.setColumns(3); mainLayout.setRows(1); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java index 6838a3dbf..e5640200b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java @@ -57,8 +57,6 @@ public class ActionHistoryGrid extends AbstractGrid { private static final long serialVersionUID = 4324796883957831443L; private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryGrid.class); - private static final String BUTTON_CANCEL = "button.cancel"; - private static final String BUTTON_OK = "button.ok"; private static final double FIXED_PIX_MIN = 25; private static final double FIXED_PIX_MAX = 32; @@ -306,7 +304,7 @@ public class ActionHistoryGrid extends AbstractGrid { /* Display the confirmation */ final ConfirmationDialog confirmDialog = new ConfirmationDialog( i18n.getMessage("caption.force.action.confirmbox"), i18n.getMessage("message.force.action.confirm"), - i18n.getMessage(BUTTON_OK), i18n.getMessage(BUTTON_CANCEL), ok -> { + i18n.getMessage(SPUIDefinitions.BUTTON_OK), i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (!ok) { return; } @@ -329,8 +327,8 @@ public class ActionHistoryGrid extends AbstractGrid { /* Display the confirmation */ final ConfirmationDialog confirmDialog = new ConfirmationDialog( i18n.getMessage("caption.forcequit.action.confirmbox"), - i18n.getMessage("message.forcequit.action.confirm"), i18n.getMessage(BUTTON_OK), - i18n.getMessage(BUTTON_CANCEL), ok -> { + i18n.getMessage("message.forcequit.action.confirm"), i18n.getMessage(SPUIDefinitions.BUTTON_OK), + i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (!ok) { return; } @@ -360,7 +358,7 @@ public class ActionHistoryGrid extends AbstractGrid { final ConfirmationDialog confirmDialog = new ConfirmationDialog( i18n.getMessage("caption.cancel.action.confirmbox"), i18n.getMessage("message.cancel.action.confirm"), - i18n.getMessage(BUTTON_OK), i18n.getMessage(BUTTON_CANCEL), ok -> { + i18n.getMessage(SPUIDefinitions.BUTTON_OK), i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (!ok) { return; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index d42a932b4..bffc3218c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -336,24 +336,23 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private CommonDialogWindow getWindow(final Long editDistId) { final SaveDialogCloseListener saveDialogCloseListener; - String captionId; + String caption; resetComponents(); populateDistSetTypeNameCombo(); if (editDistId == null) { saveDialogCloseListener = new CreateOnCloseDialogListener(); - captionId = UIComponentIdProvider.DIST_ADD_CAPTION; + caption = i18n.getMessage("caption.create.new", i18n.getMessage("caption.distribution")); } else { saveDialogCloseListener = new UpdateOnCloseDialogListener(editDistId); - captionId = UIComponentIdProvider.DIST_UPDATE_CAPTION; + caption = i18n.getMessage("caption.update", i18n.getMessage("caption.distribution")); populateValuesOfDistribution(editDistId); } - return new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(i18n.getMessage(captionId)).content(this) - .layout(formLayout).i18n(i18n).saveDialogCloseListener(saveDialogCloseListener) - .buildCommonDialogWindow(); + return new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(caption).content(this).layout(formLayout) + .i18n(i18n).saveDialogCloseListener(saveDialogCloseListener).buildCommonDialogWindow(); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index bb9599999..1bcff488e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -23,25 +23,36 @@ import java.util.stream.Collectors; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent; +import org.eclipse.hawkbit.repository.exception.InvalidMaintenanceScheduleException; +import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; +import org.eclipse.hawkbit.repository.model.RepositoryModelConstants; import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.UiProperties; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; +import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.entity.TargetIdName; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent; import org.eclipse.hawkbit.ui.management.event.RefreshDistributionTableByFilterEvent; +import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout.ActionTypeOption; +import org.eclipse.hawkbit.ui.management.miscs.MaintenanceWindowLayout; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.targettable.TargetTable; import org.eclipse.hawkbit.ui.push.DistributionSetUpdatedEventContainer; @@ -54,6 +65,8 @@ import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.eclipse.hawkbit.ui.view.filter.OnlyEventsFromDeploymentViewFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -72,10 +85,13 @@ import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Link; import com.vaadin.ui.Table; import com.vaadin.ui.UI; +import com.vaadin.ui.themes.ValoTheme; /** * Distribution set table which is shown on the Deployment View. @@ -84,6 +100,8 @@ public class DistributionTable extends AbstractNamedVersionTable event.getEntityId().equals(lastSelectedDsIdName)) - .filter(Objects::nonNull).findAny().ifPresent(event -> eventBus.publish(this, + .filter(Objects::nonNull).findAny().ifPresent(event -> getEventBus().publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity()))); - } private static boolean allOfThemAffectCompletedSetsThatAreNotVisible(final List events, @@ -172,7 +195,6 @@ public class DistributionTable extends AbstractNamedVersionTable id.equals(managementUIState.getLastSelectedDsIdName()))) { managementUIState.setLastSelectedEntityId(null); } - return true; } @@ -248,6 +270,7 @@ public class DistributionTable extends AbstractNamedVersionTable queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); managementUIState.getDistributionTableFilters().getPinnedTarget() .ifPresent(value -> queryConfig.put(SPUIDefinitions.ORDER_BY_PINNED_TARGET, value)); + final List list = new ArrayList<>(); queryConfig.put(SPUIDefinitions.FILTER_BY_NO_TAG, managementUIState.getDistributionTableFilters().isNoTagSelected()); @@ -265,42 +288,7 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button) getPinButton(itemId)); - iconLayout.addComponent(manageMetaDataBtn); - return iconLayout; - } - }); - } - - private String getNameAndVerion(final Object itemId) { - final Item item = getItem(itemId); - final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); - final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); - return name + "." + version; - } - - private Button createManageMetadataButton(final String nameVersionStr) { - final Button manageMetadataBtn = SPUIComponentProvider.getButton( - UIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, - FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); - manageMetadataBtn.addStyleName(SPUIStyleDefinitions.ARTIFACT_DTLS_ICON); - manageMetadataBtn.addStyleName(SPUIStyleDefinitions.DS_METADATA_ICON); - manageMetadataBtn.setDescription(i18n.getMessage("tooltip.metadata.icon")); - return manageMetadataBtn; - } - - @Override - protected boolean isFirstRowSelectedOnLoad() { - return managementUIState.getSelectedDsIdName().isEmpty(); + addGeneratedColumn(SPUILabelDefinitions.PIN_COLUMN, (source, itemId, columnId) -> getPinButton(itemId)); } @Override @@ -315,7 +303,8 @@ public class DistributionTable extends AbstractNamedVersionTable= 1 && managementUIState.getDistributionTableFilters().isNoTagSelected()) { refreshFilter(); } @@ -404,16 +393,14 @@ public class DistributionTable extends AbstractNamedVersionTable targetIdSet = targetTable.getDeletedEntityByTransferable(transferable); - + final Set targetIdSet = targetTable.getSelectedEntitiesByTransferable(transferable); + selectDraggedEntities(targetTable, targetIdSet); final AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails) event.getTargetDetails(); - final Object distItemId = dropData.getItemIdOver(); assignTargetToDs(getItem(distItemId), targetManagement.get(targetIdSet)); - } - private void assignTargetToDs(final Item item, final Collection targetDetailsList) { + private void assignTargetToDs(final Item item, final List targetDetailsList) { if (item == null || item.getItemProperty("id") == null) { return; } if (targetDetailsList.isEmpty()) { - getNotification().displayWarning(i18n.getMessage("targets.not.exists")); + getNotification().displayWarning(getI18n().getMessage(TARGETS_NOT_EXISTS)); return; } final Long distId = (Long) item.getItemProperty("id").getValue(); + selectDroppedEntities(distId); final Optional findDistributionSetById = distributionSetManagement.get(distId); if (!findDistributionSetById.isPresent()) { - notification.displayWarning(i18n.getMessage("distributionset.not.exists")); + getNotification().displayWarning(getI18n().getMessage(DISTRIBUTIONSET_NOT_EXISTS)); return; } - showOrHidePopupAndNotification(validate(targetDetailsList, findDistributionSetById.get())); + addNewDistributionToAssignmentList(targetDetailsList, findDistributionSetById.get()); + openConfirmationWindowForAssignment(findDistributionSetById.get().getName(), targetDetailsList); + } + + private void addNewDistributionToAssignmentList(final List targetDetailsList, + final DistributionSet distributionSet) { + String pendingActionMessage = null; + final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distributionSet); + + for (final Target target : targetDetailsList) { + final TargetIdName key = new TargetIdName(target); + if (managementUIState.getAssignedList().keySet().contains(key) + && managementUIState.getAssignedList().get(key).equals(distributionSetIdName)) { + pendingActionMessage = getPendingActionMessage(pendingActionMessage, target.getControllerId(), + HawkbitCommonUtil.getDistributionNameAndVersion(distributionSetIdName.getName(), + distributionSetIdName.getVersion())); + getNotification().displayValidationError(pendingActionMessage); + } else { + managementUIState.getAssignedList().put(key, distributionSetIdName); + } + } + } + + private void openConfirmationWindowForAssignment(final String distributionNameToAssign, + final List targetDetailsList) { + final String confirmQuestion = createConfirmationQuestionForAssignment(distributionNameToAssign, + targetDetailsList); + createConfirmationWindowForAssignment(confirmQuestion); + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + private void createConfirmationWindowForAssignment(final String confirmQuestion) { + confirmDialog = new ConfirmationDialog(getI18n().getMessage(CAPTION_ENTITY_ASSIGN_ACTION_CONFIRMBOX), + confirmQuestion, getI18n().getMessage(SPUIDefinitions.BUTTON_OK), + getI18n().getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { + if (ok && isMaintenanceWindowValid()) { + saveAllAssignments(); + } else { + managementUIState.getAssignedList().clear(); + } + }, createAssignmentTab(), UIComponentIdProvider.DIST_SET_TO_TARGET_ASSIGNMENT_CONFIRM_ID); + } + + private String createConfirmationQuestionForAssignment(final String distributionNameToAssign, + final List targetDetailsList) { + if (targetDetailsList.size() == 1) { + return getI18n().getMessage(MESSAGE_CONFIRM_ASSIGN_ENTITY, distributionNameToAssign, "target", + targetDetailsList.get(0).getName()); + } else { + return getI18n().getMessage(MESSAGE_CONFIRM_ASSIGN_MULTIPLE_ENTITIES, targetDetailsList.size(), "targets", + distributionNameToAssign); + } + } + + private boolean isMaintenanceWindowValid() { + if (maintenanceWindowLayout.isEnabled()) { + try { + MaintenanceScheduleHelper.validateMaintenanceSchedule(maintenanceWindowLayout.getMaintenanceSchedule(), + maintenanceWindowLayout.getMaintenanceDuration(), + maintenanceWindowLayout.getMaintenanceTimeZone()); + } catch (final InvalidMaintenanceScheduleException e) { + LOG.error("Maintenance window is not valid", e); + getNotification().displayValidationError(e.getMessage()); + return false; + } + } + return true; + } + + private void saveAllAssignments() { + final Set itemIds = managementUIState.getAssignedList().keySet(); + Long distId; + List targetIdSetList; + List tempIdList; + final ActionType actionType = ((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout + .getActionTypeOptionGroup().getValue()).getActionType(); + final long forcedTimeStamp = (((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout + .getActionTypeOptionGroup().getValue()) == ActionTypeOption.AUTO_FORCED) + ? actionTypeOptionGroupLayout.getForcedTimeDateField().getValue().getTime() + : RepositoryModelConstants.NO_FORCE_TIME; + + final Map> saveAssignedList = Maps.newHashMapWithExpectedSize(itemIds.size()); + + for (final TargetIdName itemId : itemIds) { + final DistributionSetIdName distitem = managementUIState.getAssignedList().get(itemId); + distId = distitem.getId(); + + if (saveAssignedList.containsKey(distId)) { + targetIdSetList = saveAssignedList.get(distId); + } else { + targetIdSetList = new ArrayList<>(); + } + targetIdSetList.add(itemId); + saveAssignedList.put(distId, targetIdSetList); + } + + final String maintenanceSchedule = maintenanceWindowLayout.getMaintenanceSchedule(); + final String maintenanceDuration = maintenanceWindowLayout.getMaintenanceDuration(); + final String maintenanceTimeZone = maintenanceWindowLayout.getMaintenanceTimeZone(); + + for (final Map.Entry> mapEntry : saveAssignedList.entrySet()) { + tempIdList = saveAssignedList.get(mapEntry.getKey()); + final DistributionSetAssignmentResult distributionSetAssignmentResult = deploymentManagement + .assignDistributionSet(mapEntry.getKey(), + tempIdList.stream().map(t -> maintenanceWindowLayout.isEnabled() + ? new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp, + maintenanceSchedule, maintenanceDuration, maintenanceTimeZone) + : new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp)) + .collect(Collectors.toList())); + + if (distributionSetAssignmentResult.getAssigned() > 0) { + getNotification().displaySuccess(getI18n().getMessage("message.target.assignment", + distributionSetAssignmentResult.getAssigned())); + } + if (distributionSetAssignmentResult.getAlreadyAssigned() > 0) { + getNotification().displaySuccess(getI18n().getMessage("message.target.alreadyAssigned", + distributionSetAssignmentResult.getAlreadyAssigned())); + } + } + resfreshPinnedDetails(saveAssignedList); + + managementUIState.getAssignedList().clear(); + getNotification().displaySuccess(getI18n().getMessage("message.target.ds.assign.success")); + getEventBus().publish(this, SaveActionWindowEvent.SAVED_ASSIGNMENTS); + } + + private void resfreshPinnedDetails(final Map> saveAssignedList) { + final Optional pinnedDist = managementUIState.getTargetTableFilters().getPinnedDistId(); + final Optional pinnedTarget = managementUIState.getDistributionTableFilters().getPinnedTarget(); + + if (pinnedDist.isPresent()) { + if (saveAssignedList.keySet().contains(pinnedDist.get())) { + getEventBus().publish(this, PinUnpinEvent.PIN_DISTRIBUTION); + } + } else if (pinnedTarget.isPresent()) { + final Set assignedTargetIds = managementUIState.getAssignedList().keySet(); + if (assignedTargetIds.contains(pinnedTarget.get())) { + getEventBus().publish(this, PinUnpinEvent.PIN_TARGET); + } + } + } + + private ConfirmationTab createAssignmentTab() { + final ConfirmationTab assignmentTab = new ConfirmationTab(); + actionTypeOptionGroupLayout.selectDefaultOption(); + assignmentTab.addComponent(actionTypeOptionGroupLayout); + assignmentTab.addComponent(enableMaintenanceWindowLayout()); + initMaintenanceWindow(); + assignmentTab.addComponent(maintenanceWindowLayout); + return assignmentTab; + } + + private HorizontalLayout enableMaintenanceWindowLayout() { + final HorizontalLayout layout = new HorizontalLayout(); + layout.addComponent(enableMaintenanceWindowControl()); + layout.addComponent(maintenanceWindowHelpLinkControl()); + return layout; + } + + private CheckBox enableMaintenanceWindowControl() { + final CheckBox enableMaintenanceWindow = new CheckBox( + getI18n().getMessage("caption.maintenancewindow.enabled")); + enableMaintenanceWindow.setId(UIComponentIdProvider.MAINTENANCE_WINDOW_ENABLED_ID); + enableMaintenanceWindow.addStyleName(ValoTheme.CHECKBOX_SMALL); + enableMaintenanceWindow.addStyleName("dist-window-maintenance-window-enable"); + enableMaintenanceWindow.addValueChangeListener(event -> { + final Boolean isMaintenanceWindowEnabled = enableMaintenanceWindow.getValue(); + maintenanceWindowLayout.setVisible(isMaintenanceWindowEnabled); + maintenanceWindowLayout.setEnabled(isMaintenanceWindowEnabled); + enableSaveButton(!isMaintenanceWindowEnabled); + maintenanceWindowLayout.clearAllControls(); + }); + return enableMaintenanceWindow; + } + + private Link maintenanceWindowHelpLinkControl() { + final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView(); + return SPUIComponentProvider.getHelpLink(maintenanceWindowHelpUrl); + } + + private void initMaintenanceWindow() { + maintenanceWindowLayout.setVisible(false); + maintenanceWindowLayout.setEnabled(false); + maintenanceWindowLayout.getScheduleControl() + .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onScheduleChange(event))); + maintenanceWindowLayout.getDurationControl() + .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onDurationChange(event))); + } + + private void enableSaveButton(final boolean enabled) { + confirmDialog.getOkButton().setEnabled(enabled); } @Override @@ -469,56 +646,29 @@ public class DistributionTable extends AbstractNamedVersionTable targetDetailsList, final DistributionSet distributionSet) { - String pendingActionMessage = null; - final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distributionSet); - - for (final Target target : targetDetailsList) { - final TargetIdName key = new TargetIdName(target); - if (managementUIState.getAssignedList().keySet().contains(key) - && managementUIState.getAssignedList().get(key).equals(distributionSetIdName)) { - pendingActionMessage = getPendingActionMessage(pendingActionMessage, target.getControllerId(), - HawkbitCommonUtil.getDistributionNameAndVersion(distributionSetIdName.getName(), - distributionSetIdName.getVersion())); - } else { - managementUIState.getAssignedList().put(key, distributionSetIdName); - } - } - return pendingActionMessage; - } - private String getPendingActionMessage(final String message, final String controllerId, final String distNameVersion) { - String pendActionMsg = i18n.getMessage("message.target.assigned.pending"); + String pendActionMsg = getI18n().getMessage("message.target.assigned.pending"); if (null == message) { - pendActionMsg = i18n.getMessage("message.dist.pending.action", + pendActionMsg = getI18n().getMessage("message.dist.pending.action", new Object[] { controllerId, distNameVersion }); } return pendActionMsg; } - private void showOrHidePopupAndNotification(final String message) { - if (null != managementUIState.getAssignedList() && !managementUIState.getAssignedList().isEmpty()) { - eventBus.publish(this, ManagementUIEvent.UPDATE_COUNT); - } - if (null != message) { - notification.displayValidationError(message); - } - } - private void updateDistributionInTable(final DistributionSet editedDs) { final Item item = getContainerDataSource().getItem(editedDs.getId()); if (item == null) { @@ -536,11 +686,9 @@ public class DistributionTable extends AbstractNamedVersionTable { final Long installedDistId = deploymentManagement.getInstalledDistributionSet(controllerId) @@ -569,8 +717,8 @@ public class DistributionTable extends AbstractNamedVersionTable ds = distributionSetManagement.get((Long) itemId); - if (!ds.isPresent()) { - notification.displayWarning(i18n.getMessage("distributionset.not.exists")); - return; + @Override + protected void handleOkDelete(final List entitiesToDelete) { + distributionSetManagement.delete(entitiesToDelete); + getEventBus().publish(this, new DistributionTableEvent(BaseEntityEventType.REMOVE_ENTITY, entitiesToDelete)); + getNotification().displaySuccess(getI18n().getMessage("message.delete.success", + entitiesToDelete.size() + " " + getI18n().getMessage("distribution.details.header") + "(s)")); + managementUIState.getTargetTableFilters().getPinnedDistId() + .ifPresent(distId -> unPinDeletedDS(entitiesToDelete, distId)); + managementUIState.getSelectedDsIdName().clear(); + } + + private void unPinDeletedDS(final Collection deletedDsIds, final Long pinnedDsId) { + if (deletedDsIds.contains(pinnedDsId)) { + managementUIState.getTargetTableFilters().setPinnedDistId(null); + getEventBus().publish(this, PinUnpinEvent.UNPIN_DISTRIBUTION); } - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds.get(), null)); + } + + @Override + protected String getEntityType() { + return getI18n().getMessage("distribution.details.header"); + } + + @Override + protected Set getSelectedEntities() { + return managementUIState.getSelectedDsIdName(); + } + + @Override + protected String getEntityId(final Object itemId) { + final String entityId = String.valueOf( + getContainerDataSource().getItem(itemId).getItemProperty(SPUILabelDefinitions.DIST_ID).getValue()); + return "distributionSet." + entityId; + } + + @Override + protected String getDeletedEntityName(final Long entityId) { + final Optional distribution = distributionSetManagement.get(entityId); + if (distribution.isPresent()) { + return distribution.get().getName(); + } + return ""; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java index a5b97bd01..23c4cc58f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout; @@ -41,7 +42,8 @@ public class DistributionTableLayout extends AbstractTableLayout { + + private static final long serialVersionUID = 1L; + + private final transient DistributionSetTagManagement distributionSetTagManagement; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param distributionSetTagManagement + * DistributionSetTagManagement + */ + public AbstractDistributionSetTagLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final DistributionSetTagManagement distributionSetTagManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification); + this.distributionSetTagManagement = distributionSetTagManagement; + } + + @Override + protected Optional findEntityByName() { + return distributionSetTagManagement.getByName(getTagName().getValue()); + } + + public DistributionSetTagManagement getDistributionSetTagManagement() { + return distributionSetTagManagement; + } + + @Override + protected int getTagNameSize() { + return DistributionSetTag.NAME_MAX_SIZE; + } + + @Override + protected int getTagDescSize() { + return DistributionSetTag.DESCRIPTION_MAX_SIZE; + } + + @Override + protected String getTagNameId() { + return UIComponentIdProvider.NEW_DISTRIBUTION_TAG_NAME; + } + + @Override + protected String getTagDescId() { + return UIComponentIdProvider.NEW_DISTRIBUTION_TAG_DESC; + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateDistributionSetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateDistributionSetTagLayout.java new file mode 100644 index 000000000..0d0100b75 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateDistributionSetTagLayout.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.dstag; + +import org.eclipse.hawkbit.repository.DistributionSetTagManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.util.StringUtils; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Layout for pop-up window which is created when creating a distribution set + * tag on the Deployment View. + */ +public class CreateDistributionSetTagLayout extends AbstractDistributionSetTagLayout { + + private static final long serialVersionUID = 1L; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param distributionSetTagManagement + * DistributionSetTagManagement + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + */ + public CreateDistributionSetTagLayout(final VaadinMessageSource i18n, + final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, distributionSetTagManagement); + } + + @Override + protected void saveEntity() { + createNewTag(); + } + + private void createNewTag() { + if (!StringUtils.isEmpty(getTagName().getValue())) { + setColorPicked(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); + String colour = ColorPickerConstants.START_COLOR.getCSS(); + if (!StringUtils.isEmpty(getColorPicked())) { + colour = getColorPicked(); + } + final DistributionSetTag newDistTag = getDistributionSetTagManagement().create(getEntityFactory().tag() + .create().name(getTagName().getValue()).description(getTagDesc().getValue()).colour(colour)); + getEventBus().publish(this, new DistributionSetTagTableEvent(BaseEntityEventType.ADD_ENTITY, newDistTag)); + displaySuccess(newDistTag.getName()); + } else { + displayValidationError(getI18n().getMessage(getMessageErrorMissingTagname())); + } + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.create.new", getI18n().getMessage("caption.tag")); + } + + @Override + protected boolean isUpdateAction() { + return false; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java deleted file mode 100644 index 051ef8893..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.dstag; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import org.eclipse.hawkbit.repository.DistributionSetTagManagement; -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.builder.TagUpdate; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.RefreshableContainer; -import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; -import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.data.domain.PageRequest; -import org.springframework.util.StringUtils; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.UI; - -/** - * Class for Create/Update Tag Layout of distribution set - */ -public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdateTagLayout - implements RefreshableContainer { - - private static final long serialVersionUID = 1L; - - private static final String TARGET_TAG_NAME_DYNAMIC_STYLE = "new-target-tag-name"; - private static final String MSG_TEXTFIELD_NAME = "textfield.name"; - - private final transient DistributionSetTagManagement distributionSetTagManagement; - - CreateUpdateDistributionTagLayoutWindow(final VaadinMessageSource i18n, - final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, - final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification) { - super(i18n, entityFactory, eventBus, permChecker, uiNotification); - this.distributionSetTagManagement = distributionSetTagManagement; - } - - @Override - protected boolean doSubscribeToEventBus() { - return false; - } - - /** - * @return the color which should be selected in the color-picker component. - */ - @Override - protected Color getColorForColorPicker() { - return ColorPickerHelper.rgbToColorConverter(distributionSetTagManagement - .getByName(tagNameComboBox.getValue().toString()).map(DistributionSetTag::getColour) - .filter(Objects::nonNull).orElse(ColorPickerConstants.DEFAULT_COLOR)); - - } - - /** - * update tag. - */ - protected void updateExistingTag(final Tag targetObj) { - final TagUpdate update = entityFactory.tag().update(targetObj.getId()).name(tagName.getValue()) - .description(tagDesc.getValue()); - - distributionSetTagManagement.update(update); - eventBus.publish(this, - new DistributionSetTagTableEvent(BaseEntityEventType.UPDATED_ENTITY, (DistributionSetTag) targetObj)); - uiNotification.displaySuccess(i18n.getMessage("message.update.success", new Object[] { targetObj.getName() })); - - } - - @Override - protected void populateTagNameCombo() { - if (tagNameComboBox == null) { - return; - } - - tagNameComboBox.removeAllItems(); - final List distTagNameList = distributionSetTagManagement - .findAll(new PageRequest(0, MAX_TAGS)).getContent(); - distTagNameList.forEach(value -> tagNameComboBox.addItem(value.getName())); - } - - @Override - protected void addListeners() { - super.addListeners(); - optiongroup.addValueChangeListener(this::optionValueChanged); - } - - @Override - protected void createEntity() { - createNewTag(); - - } - - @Override - protected void updateEntity(final DistributionSetTag entity) { - updateExistingTag(findEntityByName() - .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName.getValue()))); - } - - @Override - protected Optional findEntityByName() { - return distributionSetTagManagement.getByName(tagName.getValue()); - } - - /** - * Create new tag. - */ - @Override - protected void createNewTag() { - super.createNewTag(); - String colour = ColorPickerConstants.START_COLOR.getCSS(); - if (!StringUtils.isEmpty(getColorPicked())) { - colour = getColorPicked(); - } - - final DistributionSetTag newDistTag = distributionSetTagManagement - .create(entityFactory.tag().create().name(tagNameValue).description(tagDescValue).colour(colour)); - eventBus.publish(this, new DistributionSetTagTableEvent(BaseEntityEventType.ADD_ENTITY, newDistTag)); - displaySuccess(newDistTag.getName()); - resetDistTagValues(); - } - - /** - * RESET. - */ - @Override - public void discard() { - super.discard(); - resetDistTagValues(); - } - - /** - * RESET. - */ - private void resetDistTagValues() { - tagName.removeStyleName(TARGET_TAG_NAME_DYNAMIC_STYLE); - tagName.addStyleName(SPUIDefinitions.NEW_TARGET_TAG_NAME); - tagName.setValue(""); - tagName.setInputPrompt(i18n.getMessage(MSG_TEXTFIELD_NAME)); - setColor(ColorPickerConstants.START_COLOR); - getWindow().setVisible(false); - tagPreviewBtnClicked = false; - UI.getCurrent().removeWindow(getWindow()); - } - - /** - * Select tag & set tag name & tag desc values corresponding to selected - * tag. - * - * @param distTagSelected - * as the selected tag from combo - */ - @Override - public void setTagDetails(final String distTagSelected) { - tagName.setValue(distTagSelected); - final Optional selectedDistTag = distributionSetTagManagement.getByName(distTagSelected); - if (selectedDistTag.isPresent()) { - tagDesc.setValue(selectedDistTag.get().getDescription()); - if (null == selectedDistTag.get().getColour()) { - setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); - } else { - setTagColor(ColorPickerHelper.rgbToColorConverter(selectedDistTag.get().getColour()), - selectedDistTag.get().getColour()); - } - } - } - - @Override - protected void createRequiredComponents() { - super.createRequiredComponents(); - createOptionGroup(permChecker.hasCreateRepositoryPermission(), permChecker.hasUpdateRepositoryPermission()); - } - - @Override - protected void reset() { - - super.reset(); - setOptionGroupDefaultValue(permChecker.hasCreateRepositoryPermission(), - permChecker.hasUpdateRepositoryPermission()); - } - - @Override - protected String getWindowCaption() { - return i18n.getMessage("caption.add.tag"); - } - - @Override - public void refreshContainer() { - populateTagNameCombo(); - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagHeader.java deleted file mode 100644 index d9bf31256..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagHeader.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.dstag; - -import org.eclipse.hawkbit.repository.DistributionSetTagManagement; -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; -import org.eclipse.hawkbit.ui.components.RefreshableContainer; -import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; -import org.eclipse.hawkbit.ui.management.state.ManagementUIState; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.UI; -import com.vaadin.ui.Window; - -/** - * - * - */ -public class DistributionTagHeader extends AbstractFilterHeader implements RefreshableContainer { - - private static final long serialVersionUID = -1439667766337270066L; - - private final ManagementUIState managementUIState; - private final CreateUpdateDistributionTagLayoutWindow createORUpdateDistributionTagLayout; - - DistributionTagHeader(final VaadinMessageSource i18n, final ManagementUIState managementUIState, - final SpPermissionChecker permChecker, final UIEventBus eventBus, - final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, - final UINotification uiNotification) { - super(permChecker, eventBus, i18n); - this.managementUIState = managementUIState; - this.createORUpdateDistributionTagLayout = new CreateUpdateDistributionTagLayoutWindow(i18n, - distributionSetTagManagement, entityFactory, eventBus, permChecker, uiNotification); - if (hasCreateUpdatePermission()) { - createORUpdateDistributionTagLayout.init(); - } - } - - @Override - protected String getHideButtonId() { - return "hide.distribution.tags"; - } - - @Override - protected boolean hasCreateUpdatePermission() { - return permChecker.hasCreateRepositoryPermission() || permChecker.hasUpdateRepositoryPermission(); - } - - @Override - protected String getTitle() { - return i18n.getMessage("header.filter.tag", new Object[] {}); - } - - @Override - protected void settingsIconClicked(final ClickEvent event) { - final Window addUpdateWindow = createORUpdateDistributionTagLayout.getWindow(); - UI.getCurrent().addWindow(addUpdateWindow); - addUpdateWindow.setModal(true); - addUpdateWindow.setVisible(Boolean.TRUE); - } - - @Override - protected boolean dropHitsRequired() { - return true; - } - - @Override - protected void hideFilterButtonLayout() { - managementUIState.setDistTagFilterClosed(true); - eventBus.publish(this, ManagementUIEvent.HIDE_DISTRIBUTION_TAG_LAYOUT); - } - - @Override - protected String getConfigureFilterButtonId() { - return UIComponentIdProvider.ADD_DISTRIBUTION_TAG; - } - - @Override - protected boolean isAddTagRequired() { - return true; - } - - @Override - public void refreshContainer() { - createORUpdateDistributionTagLayout.refreshContainer(); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/UpdateDistributionSetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/UpdateDistributionSetTagLayout.java new file mode 100644 index 000000000..051b918f1 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/UpdateDistributionSetTagLayout.java @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.dstag; + +import java.util.Optional; + +import org.eclipse.hawkbit.repository.DistributionSetTagManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.builder.TagUpdate; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.layouts.UpdateTag; +import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +import com.vaadin.ui.Window.CloseListener; + +/** + * Layout for the pop-up window which is created when updating a distribution + * set tag on the Deployment View. + * + */ +public class UpdateDistributionSetTagLayout extends AbstractDistributionSetTagLayout implements UpdateTag { + + private static final long serialVersionUID = 1L; + + private final String selectedTagName; + + private final CloseListener closeListener; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param distributionSetTagManagement + * DistributionSetTagManagement + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param selectedTagName + * name of the selected distribution set tag to update + * @param closeListener + * CloseListener + */ + public UpdateDistributionSetTagLayout(final VaadinMessageSource i18n, + final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final String selectedTagName, final CloseListener closeListener) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, distributionSetTagManagement); + this.selectedTagName = selectedTagName; + this.closeListener = closeListener; + initUpdatePopup(); + } + + private void initUpdatePopup() { + setTagDetails(selectedTagName); + getWindow().addCloseListener(closeListener); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.update", getI18n().getMessage("caption.tag")); + } + + @Override + protected void saveEntity() { + updateExistingTag(findEntityByName() + .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, getTagName().getValue()))); + } + + private void updateExistingTag(final Tag targetObj) { + final TagUpdate update = getEntityFactory().tag().update(targetObj.getId()).name(getTagName().getValue()) + .description(getTagDesc().getValue()) + .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); + getDistributionSetTagManagement().update(update); + getEventBus().publish(this, + new DistributionSetTagTableEvent(BaseEntityEventType.UPDATED_ENTITY, (DistributionSetTag) targetObj)); + getUiNotification().displaySuccess(getI18n().getMessage("message.update.success", targetObj.getName())); + } + + @Override + public void setTagDetails(final String selectedEntity) { + final Optional selectedDistTag = getDistributionSetTagManagement() + .getByName(selectedEntity); + selectedDistTag.ifPresent(tag -> { + getTagName().setValue(tag.getName()); + getTagName().setEnabled(false); + getTagDesc().setValue(selectedDistTag.get().getDescription()); + if (selectedDistTag.get().getColour() == null) { + setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + } else { + setTagColor(ColorPickerHelper.rgbToColorConverter(selectedDistTag.get().getColour()), + selectedDistTag.get().getColour()); + } + getWindow().setOrginaleValues(); + }); + } + + @Override + protected boolean isUpdateAction() { + return true; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagBeanQuery.java similarity index 98% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagBeanQuery.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagBeanQuery.java index edf3e032e..e9866eda9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagBeanQuery.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.dstag; +package org.eclipse.hawkbit.ui.management.dstag.filter; import java.util.List; import java.util.Map; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java similarity index 97% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java index 101a98a3b..9e4e9d26e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtonClick.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.dstag; +package org.eclipse.hawkbit.ui.management.dstag.filter; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterMultiButtonClick; import org.eclipse.hawkbit.ui.management.event.RefreshDistributionTableByFilterEvent; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java similarity index 61% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java index b8b54e606..cfde7f2c3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagButtons.java @@ -6,17 +6,24 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.dstag; +package org.eclipse.hawkbit.ui.management.dstag.filter; import java.util.Collections; +import java.util.Optional; import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.event.DistributionSetTagFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; -import org.eclipse.hawkbit.ui.components.RefreshableContainer; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; +import org.eclipse.hawkbit.ui.management.dstag.UpdateDistributionSetTagLayout; +import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTagDropEvent; import org.eclipse.hawkbit.ui.management.state.DistributionTableFilters; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; @@ -33,36 +40,48 @@ import org.vaadin.spring.events.EventBus.UIEventBus; import com.vaadin.data.Item; import com.vaadin.event.dd.DropHandler; +import com.vaadin.ui.Button.ClickEvent; /** * Class for defining the tag buttons of the distribution sets on the Deployment * View. */ -public class DistributionTagButtons extends AbstractFilterButtons implements RefreshableContainer { +public class DistributionTagButtons extends AbstractFilterButtons { private static final long serialVersionUID = 1L; - private static final String NO_TAG = "NO TAG"; - private final DistributionTagDropEvent spDistTagDropEvent; private final ManagementUIState managementUIState; private final transient EntityFactory entityFactory; - DistributionTagButtons(final UIEventBus eventBus, final ManagementUIState managementUIState, - final EntityFactory entityFactory, final VaadinMessageSource i18n, final UINotification notification, + private final VaadinMessageSource i18n; + + private final SpPermissionChecker permChecker; + + private final UINotification uiNotification; + + private final transient DistributionSetTagManagement distributionSetTagManagement; + + public DistributionTagButtons(final UIEventBus eventBus, final ManagementUIState managementUIState, + final EntityFactory entityFactory, final VaadinMessageSource i18n, final UINotification uiNotification, final SpPermissionChecker permChecker, final DistributionTableFilters distFilterParameters, final DistributionSetManagement distributionSetManagement, - final ManagementViewClientCriterion managementViewClientCriterion) { - super(eventBus, new DistributionTagButtonClick(eventBus, managementUIState)); - this.spDistTagDropEvent = new DistributionTagDropEvent(i18n, notification, permChecker, distFilterParameters, + final ManagementViewClientCriterion managementViewClientCriterion, + final DistributionSetTagManagement distributionSetTagManagement) { + super(eventBus, new DistributionTagButtonClick(eventBus, managementUIState), i18n); + this.spDistTagDropEvent = new DistributionTagDropEvent(i18n, uiNotification, permChecker, distFilterParameters, distributionSetManagement, eventBus, managementViewClientCriterion); this.managementUIState = managementUIState; this.entityFactory = entityFactory; + this.i18n = i18n; + this.permChecker = permChecker; + this.uiNotification = uiNotification; + this.distributionSetTagManagement = distributionSetTagManagement; if (permChecker.hasReadRepositoryPermission()) { - addNewTag(entityFactory.tag().create().name(NO_TAG).build()); + addNewTag(entityFactory.tag().create().name(SPUIDefinitions.NO_TAG).build()); } } @@ -101,7 +120,7 @@ public class DistributionTagButtons extends AbstractFilterButtons implements Ref @Override protected String createButtonId(final String name) { - if (NO_TAG.equals(name)) { + if (SPUIDefinitions.NO_TAG.equals(name)) { return UIComponentIdProvider.NO_TAG_DISTRIBUTION_SET; } return name; @@ -130,10 +149,39 @@ public class DistributionTagButtons extends AbstractFilterButtons implements Ref } @Override - public void refreshContainer() { + public void refreshTable() { ((LazyQueryContainer) getContainerDataSource()).refresh(); removeGeneratedColumn(FILTER_BUTTON_COLUMN); - addNewTag(entityFactory.tag().create().name(NO_TAG).build()); + removeUpdateAndDeleteColumn(); + addNewTag(entityFactory.tag().create().name(SPUIDefinitions.NO_TAG).build()); addColumn(); } + + @Override + protected void addEditButtonClickListener(final ClickEvent event) { + new UpdateDistributionSetTagLayout(i18n, distributionSetTagManagement, entityFactory, getEventBus(), + permChecker, uiNotification, getEntityId(event), getCloseListenerForEditAndDeleteTag( + new DistributionSetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR))); + } + + @Override + protected void addDeleteButtonClickListener(final ClickEvent event) { + openConfirmationWindowForDeletion(getEntityId(event), i18n.getMessage("caption.entity.distribution.tag"), + new DistributionSetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + + @Override + protected void deleteEntity(final String entityToDelete) { + final Optional tagToDelete = distributionSetTagManagement.getByName(entityToDelete); + tagToDelete.ifPresent(tag -> { + if (managementUIState.getDistributionTableFilters().getDistSetTags().contains(entityToDelete)) { + uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityToDelete)); + removeUpdateAndDeleteColumn(); + } else { + distributionSetTagManagement.delete(entityToDelete); + getEventBus().publish(this, new DistributionSetTagTableEvent(BaseEntityEventType.REMOVE_ENTITY, tag)); + uiNotification.displaySuccess(i18n.getMessage("message.delete.success", entityToDelete)); + } + }); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagFilterHeader.java new file mode 100644 index 000000000..b758d4ba7 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagFilterHeader.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.dstag.filter; + +import org.eclipse.hawkbit.repository.DistributionSetTagManagement; +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.event.DistributionSetTagFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; +import org.eclipse.hawkbit.ui.management.dstag.CreateDistributionSetTagLayout; +import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; +import org.eclipse.hawkbit.ui.management.state.ManagementUIState; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; + +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.MenuBar.Command; + +/** + * Table header for filtering distribution set tags + * + */ +public class DistributionTagFilterHeader extends AbstractFilterHeader { + + private static final long serialVersionUID = 1L; + + private final ManagementUIState managementUIState; + + private final transient EntityFactory entityFactory; + + private final UINotification uiNotification; + + private final transient DistributionSetTagManagement distributionSetTagManagement; + + private final DistributionTagButtons distributionTagButtons; + + DistributionTagFilterHeader(final VaadinMessageSource i18n, final ManagementUIState managementUIState, + final SpPermissionChecker permChecker, final UIEventBus eventBus, + final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, + final UINotification uiNotification, final DistributionTagButtons distributionTagButtons) { + super(permChecker, eventBus, i18n); + this.entityFactory = entityFactory; + this.managementUIState = managementUIState; + this.uiNotification = uiNotification; + this.distributionSetTagManagement = distributionSetTagManagement; + this.distributionTagButtons = distributionTagButtons; + } + + @Override + protected String getHideButtonId() { + return "hide.distribution.tags"; + } + + @Override + protected String getTitle() { + return getI18n().getMessage("header.filter.tag"); + } + + @Override + protected boolean dropHitsRequired() { + return true; + } + + @Override + protected void hideFilterButtonLayout() { + managementUIState.setDistTagFilterClosed(true); + getEventBus().publish(this, ManagementUIEvent.HIDE_DISTRIBUTION_TAG_LAYOUT); + } + + @Override + protected String getConfigureFilterButtonId() { + return UIComponentIdProvider.ADD_DISTRIBUTION_TAG; + } + + @Override + protected boolean isAddTagRequired() { + return true; + } + + @Override + protected Command getAddButtonCommand() { + return command -> new CreateDistributionSetTagLayout(getI18n(), distributionSetTagManagement, entityFactory, + getEventBus(), getPermChecker(), uiNotification); + } + + @Override + protected Command getDeleteButtonCommand() { + return command -> { + distributionTagButtons.addDeleteColumn(); + getEventBus().publish(this, new DistributionSetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected Command getUpdateButtonCommand() { + return command -> { + distributionTagButtons.addUpdateColumn(); + getEventBus().publish(this, new DistributionSetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + @Override + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + super.cancelUpdateOrDeleteTag(event); + distributionTagButtons.removeUpdateAndDeleteColumn(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + private void onEvent(final DistributionSetTagFilterHeaderEvent event) { + processFilterHeaderEvent(event); + } + + @Override + protected String getMenuBarId() { + return UIComponentIdProvider.DIST_TAG_MENU_BAR_ID; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagLayout.java similarity index 56% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagLayout.java index fc28b4c95..63f2c75e1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/filter/DistributionTagLayout.java @@ -6,21 +6,17 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.dstag; +package org.eclipse.hawkbit.ui.management.dstag.filter; -import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; -import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; +import org.eclipse.hawkbit.ui.common.event.DistributionSetTagFilterHeaderEvent; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterLayout; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.RefreshableContainer; -import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; -import org.eclipse.hawkbit.ui.management.state.DistributionTableFilters; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; @@ -29,30 +25,46 @@ import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; /** - * + * Layout for Distribution Tags * */ public class DistributionTagLayout extends AbstractFilterLayout implements RefreshableContainer { - private static final long serialVersionUID = 4363033587261057567L; + private static final long serialVersionUID = 1L; private final ManagementUIState managementUIState; - public DistributionTagLayout(final UIEventBus eventbus, final ManagementUIState managementUIState, - final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param managementUIState + * ManagementUIState + * @param i18n + * VaadinMessageSource + * @param permChecker + * SpPermissionChecker + * @param distributionSetTagManagement + * DistributionSetTagManagement + * @param entityFactory + * EntityFactory + * @param uiNotification + * UINotification + * @param distributionTagButtons + * DistributionTagButtons + */ + public DistributionTagLayout(final UIEventBus eventBus, final ManagementUIState managementUIState, + final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final DistributionSetTagManagement distributionSetTagManagement, final EntityFactory entityFactory, - final UINotification uiNotification, final DistributionTableFilters distFilterParameters, - final DistributionSetManagement distributionSetManagement, - final ManagementViewClientCriterion managementViewClientCriterion) { + final UINotification uiNotification, final DistributionTagButtons distributionTagButtons) { - super(new DistributionTagHeader(i18n, managementUIState, permChecker, eventBus, distributionSetTagManagement, - entityFactory, uiNotification), - new DistributionTagButtons(eventBus, managementUIState, entityFactory, i18n, uiNotification, - permChecker, distFilterParameters, distributionSetManagement, managementViewClientCriterion)); + super(new DistributionTagFilterHeader(i18n, managementUIState, permChecker, eventBus, distributionSetTagManagement, + entityFactory, uiNotification, distributionTagButtons), distributionTagButtons, eventBus); this.managementUIState = managementUIState; restoreState(); - eventbus.subscribe(this); + eventBus.subscribe(this); } @EventBusListenerMethod(scope = EventScope.UI) @@ -69,11 +81,8 @@ public class DistributionTagLayout extends AbstractFilterLayout implements Refre @EventBusListenerMethod(scope = EventScope.UI) void onDistributionSetTagTableEvent(final DistributionSetTagTableEvent distributionSetTagTableEvent) { - if (BaseEntityEventType.ADD_ENTITY != distributionSetTagTableEvent.getEventType() - && BaseEntityEventType.REMOVE_ENTITY != distributionSetTagTableEvent.getEventType()) { - return; - } refreshContainer(); + getEventBus().publish(this, new DistributionSetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); } @Override @@ -83,16 +92,7 @@ public class DistributionTagLayout extends AbstractFilterLayout implements Refre @Override public void refreshContainer() { - final AbstractFilterButtons filterButtons = getFilterButtons(); - if (filterButtons instanceof RefreshableContainer) { - ((RefreshableContainer) filterButtons).refreshContainer(); - } - - final AbstractFilterHeader filterHeader = getFilterHeader(); - if (filterHeader instanceof RefreshableContainer) { - ((RefreshableContainer) filterHeader).refreshContainer(); - } - + getFilterButtons().refreshTable(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java index 1c474cdde..ff524961b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTagDropEvent.java @@ -135,7 +135,7 @@ public class DistributionTagDropEvent implements DropHandler { final TableTransferable transferable = (TableTransferable) event.getTransferable(); final AbstractTable source = (AbstractTable) transferable.getSourceComponent(); - final Set distSelected = source.getDeletedEntityByTransferable(transferable); + final Set distSelected = source.getSelectedEntitiesByTransferable(transferable); final String distTagName = HawkbitCommonUtil.removePrefix(targetDetails.getTarget().getId(), SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java deleted file mode 100644 index c65cef749..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java +++ /dev/null @@ -1,427 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.footer; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.DeploymentManagement; -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTagManagement; -import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.TargetTagManagement; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.UiProperties; -import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; -import org.eclipse.hawkbit.ui.common.entity.TargetIdName; -import org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout; -import org.eclipse.hawkbit.ui.common.table.AbstractTable; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; -import org.eclipse.hawkbit.ui.management.event.BulkUploadPopupEvent; -import org.eclipse.hawkbit.ui.management.event.DistributionSetTagTableEvent; -import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; -import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent; -import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; -import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; -import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent; -import org.eclipse.hawkbit.ui.management.state.ManagementUIState; -import org.eclipse.hawkbit.ui.management.targettable.TargetTable; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; -import org.vaadin.spring.events.EventScope; -import org.vaadin.spring.events.annotation.EventBusListenerMethod; - -import com.vaadin.event.dd.DragAndDropEvent; -import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; -import com.vaadin.ui.Component; -import com.vaadin.ui.DragAndDropWrapper; -import com.vaadin.ui.Label; -import com.vaadin.ui.Table; -import com.vaadin.ui.Table.TableTransferable; -import com.vaadin.ui.UI; - -/** - * Layout for the action button footer on the Deployment View. - */ -public class DeleteActionsLayout extends AbstractDeleteActionsLayout { - - private static final long serialVersionUID = 1L; - - private final transient DistributionSetTagManagement distributionSetTagManagement; - - private final transient TargetTagManagement targetTagManagement; - - private final ManagementViewClientCriterion managementViewClientCriterion; - - private final ManagementUIState managementUIState; - - private final ManagementConfirmationWindowLayout managementConfirmationWindowLayout; - - private final CountMessageLabel countMessageLabel; - - private final transient TargetManagement targetManagement; - - private final transient DistributionSetManagement distributionSetManagement; - - public DeleteActionsLayout(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, - final UIEventBus eventBus, final UINotification notification, final TargetTagManagement targetTagManagement, - final DistributionSetTagManagement distributionSetTagManagement, - final ManagementViewClientCriterion managementViewClientCriterion, - final ManagementUIState managementUIState, final TargetManagement targetManagement, - final TargetTable targetTable, final DeploymentManagement deploymentManagement, - final DistributionSetManagement distributionSetManagement, final UiProperties uiProperties) { - super(i18n, permChecker, eventBus, notification); - this.distributionSetTagManagement = distributionSetTagManagement; - this.targetTagManagement = targetTagManagement; - this.managementViewClientCriterion = managementViewClientCriterion; - this.managementUIState = managementUIState; - this.managementConfirmationWindowLayout = new ManagementConfirmationWindowLayout(i18n, eventBus, - managementUIState, targetManagement, deploymentManagement, distributionSetManagement, uiProperties, - notification); - this.countMessageLabel = new CountMessageLabel(eventBus, targetManagement, i18n, managementUIState, - targetTable); - this.targetManagement = targetManagement; - this.distributionSetManagement = distributionSetManagement; - init(); - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final ManagementUIEvent event) { - if (event == ManagementUIEvent.UPDATE_COUNT) { - UI.getCurrent().access(this::updateActionCount); - } - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final SaveActionWindowEvent event) { - if (event != null) { - UI.getCurrent().access(() -> { - if (!hasUnsavedActions()) { - closeUnsavedActionsWindow(); - final String message = managementConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - } - updateActionCount(); - }); - } - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final BulkUploadPopupEvent event) { - if (BulkUploadPopupEvent.MINIMIZED == event) { - UI.getCurrent().access(this::enableBulkUploadStatusButton); - } else if (BulkUploadPopupEvent.CLOSED == event) { - UI.getCurrent().access(this::hideBulkUploadStatusButton); - } - } - - @EventBusListenerMethod(scope = EventScope.UI) - void onEvent(final TargetTableEvent event) { - if (!managementUIState.isTargetTableMaximized()) { - if (TargetComponentEvent.BULK_TARGET_CREATED == event.getTargetComponentEvent()) { - this.getUI() - .access(() -> setUploadStatusButtonCaption(managementUIState.getTargetTableFilters() - .getBulkUpload().getFailedUploadCount() - + managementUIState.getTargetTableFilters().getBulkUpload().getSucessfulUploadCount())); - } else if (TargetComponentEvent.BULK_UPLOAD_COMPLETED == event.getTargetComponentEvent()) { - this.getUI().access(this::updateUploadBtnIconToComplete); - } else if (TargetComponentEvent.BULK_TARGET_UPLOAD_STARTED == event.getTargetComponentEvent()) { - this.getUI().access(this::updateUploadBtnIconToProgressIndicator); - } - } - } - - @Override - protected boolean hasDeletePermission() { - return permChecker.hasDeleteRepositoryPermission() || permChecker.hasDeleteTargetPermission(); - } - - @Override - protected boolean hasUpdatePermission() { - return permChecker.hasUpdateTargetPermission() && permChecker.hasReadRepositoryPermission(); - } - - @Override - protected String getDeleteAreaLabel() { - return i18n.getMessage("label.components.drop.area"); - } - - @Override - protected String getDeleteAreaId() { - return UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID; - } - - @Override - protected AcceptCriterion getDeleteLayoutAcceptCriteria() { - return managementViewClientCriterion; - } - - @Override - protected void processDroppedComponent(final DragAndDropEvent event) { - final Component source = event.getTransferable().getSourceComponent(); - if (!DeleteActionsLayoutHelper.isComponentDeletable(source)) { - notification.displayValidationError(i18n.getMessage("message.cannot.delete")); - } else { - processDeletion(event, source); - } - } - - private void processDeletion(final DragAndDropEvent event, final Component source) { - if (DeleteActionsLayoutHelper.isTargetTable(source) && canTargetBeDeleted()) { - addInDeleteTargetList((Table) source, (TableTransferable) event.getTransferable()); - updateActionCount(); - } else if (DeleteActionsLayoutHelper.isDistributionTable(source) && canDSBeDeleted()) { - addInDeleteDistributionList((Table) source, (TableTransferable) event.getTransferable()); - updateActionCount(); - } else if (DeleteActionsLayoutHelper.isTargetTag(source) && canTargetBeDeleted() - && tagNotInUSeInBulkUpload(source)) { - deleteTargetTag(source); - } else if (DeleteActionsLayoutHelper.isDistributionTag(source) && canDSBeDeleted()) { - deleteDistributionTag(source); - } - } - - private boolean tagNotInUSeInBulkUpload(final Component source) { - final String tagName = HawkbitCommonUtil.removePrefix(source.getId(), SPUIDefinitions.TARGET_TAG_ID_PREFIXS); - if (managementUIState.getTargetTableFilters().getBulkUpload().getAssignedTagNames().contains(tagName)) { - notification.displayValidationError(i18n.getMessage("message.tag.use.bulk.upload", tagName)); - return false; - } - return true; - } - - @Override - protected void restoreActionCount() { - updateActionCount(); - } - - @Override - protected void unsavedActionsWindowClosed() { - final String message = managementConfirmationWindowLayout.getConsolidatedMessage(); - if (message != null && message.length() > 0) { - notification.displaySuccess(message); - } - } - - @Override - protected Component getUnsavedActionsWindowContent() { - managementConfirmationWindowLayout.initialize(); - return managementConfirmationWindowLayout; - } - - @Override - protected boolean hasUnsavedActions() { - return !managementUIState.getDeletedDistributionList().isEmpty() - || !managementUIState.getDeletedTargetList().isEmpty() - || !managementUIState.getAssignedList().isEmpty(); - } - - @Override - protected boolean hasCountMessage() { - return permChecker.hasTargetReadPermission(); - } - - @Override - protected Label getCountMessageLabel() { - return countMessageLabel; - } - - private void deleteDistributionTag(final Component source) { - final String tagName = HawkbitCommonUtil.removePrefix(source.getId(), - SPUIDefinitions.DISTRIBUTION_TAG_ID_PREFIXS); - if (managementUIState.getDistributionTableFilters().getDistSetTags().contains(tagName)) { - notification.displayValidationError(i18n.getMessage("message.tag.delete", tagName)); - } else { - distributionSetTagManagement.delete(tagName); - - if (source instanceof DragAndDropWrapper) { - final Long id = DeleteActionsLayoutHelper.getDistributionTagId((DragAndDropWrapper) source); - eventBus.publish(this, - new DistributionSetTagTableEvent(BaseEntityEventType.REMOVE_ENTITY, Arrays.asList(id))); - } - - notification.displaySuccess(i18n.getMessage("message.delete.success", tagName)); - } - } - - private void deleteTargetTag(final Component source) { - final String tagName = HawkbitCommonUtil.removePrefix(source.getId(), SPUIDefinitions.TARGET_TAG_ID_PREFIXS); - if (managementUIState.getTargetTableFilters().getClickedTargetTags().contains(tagName)) { - notification.displayValidationError(i18n.getMessage("message.tag.delete", tagName)); - } else { - targetTagManagement.delete(tagName); - - if (source instanceof DragAndDropWrapper) { - final Long id = DeleteActionsLayoutHelper.getTargetTagId((DragAndDropWrapper) source); - eventBus.publish(this, new TargetTagTableEvent(BaseEntityEventType.REMOVE_ENTITY, Arrays.asList(id))); - } - - notification.displaySuccess(i18n.getMessage("message.delete.success", tagName)); - } - } - - private void addInDeleteDistributionList(final Table sourceTable, final TableTransferable transferable) { - final AbstractTable distTable = (AbstractTable) sourceTable; - final Set ids = distTable.getDeletedEntityByTransferable(transferable); - - final Long dsInBulkUpload = managementUIState.getTargetTableFilters().getBulkUpload().getDsNameAndVersion(); - if (isDsInUseInBulkUpload(ids, dsInBulkUpload)) { - ids.remove(dsInBulkUpload); - } - - if (ids.isEmpty()) { - return; - } - - final List findDistributionSetAllById = distributionSetManagement.get(ids); - - if (findDistributionSetAllById.isEmpty()) { - notification.displayWarning(i18n.getMessage("distributionsets.not.exists")); - return; - } - - final Set distributionIdNameSet = findDistributionSetAllById.stream() - .map(distributionSet -> new DistributionSetIdName(distributionSet)).collect(Collectors.toSet()); - - checkDeletedDistributionSets(distributionIdNameSet); - } - - private void checkDeletedDistributionSets(final Set distributionIdNameSet) { - final int existingDeletedDistributionsSize = managementUIState.getDeletedDistributionList().size(); - managementUIState.getDeletedDistributionList().addAll(distributionIdNameSet); - final int newDeletedDistributionsSize = managementUIState.getDeletedDistributionList().size(); - - showAlreadyDeletedDistributionSetNotfication(existingDeletedDistributionsSize, newDeletedDistributionsSize, - "message.dists.already.deleted"); - showPendingDeletedNotifaction(distributionIdNameSet, existingDeletedDistributionsSize, - newDeletedDistributionsSize, "message.dist.deleted.pending"); - } - - private void showPendingDeletedNotifaction(final Set currentValues, final int existingDeletedSize, - final int newDeletedSize, final String messageKey) { - if (newDeletedSize - existingDeletedSize == currentValues.size()) { - return; - } - notification.displayValidationError(i18n.getMessage(messageKey)); - } - - private void showAlreadyDeletedDistributionSetNotfication(final int existingDeletedSize, final int newDeletedSize, - final String messageKey) { - - if (newDeletedSize != existingDeletedSize) { - return; - } - notification.displayValidationError(i18n.getMessage(messageKey)); - } - - private boolean isDsInUseInBulkUpload(final Set distributionIdNameSet, final Long dsInBulkUpload) { - if (distributionIdNameSet.contains(dsInBulkUpload)) { - final Optional distributionSet = distributionSetManagement.get(dsInBulkUpload); - if (!distributionSet.isPresent()) { - notification.displayWarning(i18n.getMessage("distributionset.not.exists")); - return true; - } - notification.displayValidationError(i18n.getMessage("message.tag.use.bulk.upload", HawkbitCommonUtil - .getFormattedNameVersion(distributionSet.get().getName(), distributionSet.get().getVersion()))); - return true; - } - return false; - } - - private void addInDeleteTargetList(final Table sourceTable, final TableTransferable transferable) { - final TargetTable targetTable = (TargetTable) sourceTable; - final Set targetIdSet = targetTable.getDeletedEntityByTransferable(transferable); - final Collection findTargetAllById = targetManagement.get(targetIdSet); - if (findTargetAllById.isEmpty()) { - notification.displayWarning(i18n.getMessage("targets.not.exists")); - return; - } - - final Set targetIdNames = findTargetAllById.stream().map(target -> new TargetIdName(target)) - .collect(Collectors.toSet()); - checkDeletedTargets(targetIdNames); - } - - private void checkDeletedTargets(final Set targetIdSet) { - final int existingDeletedTargetsSize = managementUIState.getDeletedTargetList().size(); - managementUIState.getDeletedTargetList().addAll(targetIdSet); - final int newDeletedTargetsSize = managementUIState.getDeletedTargetList().size(); - - showAlreadyDeletedDistributionSetNotfication(existingDeletedTargetsSize, newDeletedTargetsSize, - "message.targets.already.deleted"); - - showPendingDeletedNotifaction(targetIdSet, existingDeletedTargetsSize, newDeletedTargetsSize, - "message.target.deleted.pending"); - } - - private void updateActionCount() { - final int count = managementUIState.getDeletedTargetList().size() - + managementUIState.getDeletedDistributionList().size() + managementUIState.getAssignedList().size(); - updateActionsCount(count); - } - - private Boolean canTargetBeDeleted() { - if (!permChecker.hasDeleteTargetPermission()) { - notification.displayValidationError( - i18n.getMessage("message.permission.insufficient", SpPermission.DELETE_TARGET)); - return false; - } - return true; - } - - private Boolean canDSBeDeleted() { - if (!permChecker.hasDeleteRepositoryPermission()) { - notification.displayValidationError( - i18n.getMessage("message.permission.insufficient", SpPermission.DELETE_REPOSITORY)); - return false; - } - return true; - } - - @Override - protected boolean hasBulkUploadPermission() { - return permChecker.hasCreateTargetPermission(); - } - - @Override - protected void showBulkUploadWindow() { - eventBus.publish(this, BulkUploadPopupEvent.MAXIMIMIZED); - } - - @Override - protected void restoreBulkUploadStatusCount() { - final int failedCount = managementUIState.getTargetTableFilters().getBulkUpload().getFailedUploadCount(); - final int successCount = managementUIState.getTargetTableFilters().getBulkUpload().getSucessfulUploadCount(); - if (failedCount != 0 || successCount != 0) { - setUploadStatusButtonCaption(failedCount + successCount); - enableBulkUploadStatusButton(); - if (Math.abs(managementUIState.getTargetTableFilters().getBulkUpload().getProgressBarCurrentValue() - - 1) < 0.00001) { - updateUploadBtnIconToComplete(); - } else { - updateUploadBtnIconToProgressIndicator(); - } - - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayoutHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayoutHelper.java deleted file mode 100644 index 3a1b909de..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayoutHelper.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.footer; - -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; - -import com.vaadin.ui.Component; -import com.vaadin.ui.DragAndDropWrapper; - -/** - * Delete actions layout helper class. - * - */ -public final class DeleteActionsLayoutHelper { - - private DeleteActionsLayoutHelper() { - - } - - static boolean isTargetTag(final Component source) { - if (source instanceof DragAndDropWrapper) { - final String wrapperData = ((DragAndDropWrapper) source).getData().toString(); - final String id = wrapperData.replace(SPUIDefinitions.TARGET_TAG_BUTTON, ""); - if (wrapperData.contains(SPUIDefinitions.TARGET_TAG_BUTTON) && !id.trim().isEmpty()) { - return true; - } - } - return false; - } - - static boolean isDistributionTag(final Component source) { - if (source instanceof DragAndDropWrapper) { - final String wrapperData = ((DragAndDropWrapper) source).getData().toString(); - final String id = wrapperData.replace(SPUIDefinitions.DISTRIBUTION_TAG_BUTTON, ""); - return wrapperData.contains(SPUIDefinitions.DISTRIBUTION_TAG_BUTTON) && !id.trim().isEmpty(); - } - return false; - } - - static Long getDistributionTagId(final DragAndDropWrapper source) { - final String wrapperData = source.getData().toString(); - final String id = wrapperData.replace(SPUIDefinitions.DISTRIBUTION_TAG_BUTTON, ""); - return Long.valueOf(id.trim()); - } - - static Long getTargetTagId(final DragAndDropWrapper source) { - final String wrapperData = source.getData().toString(); - final String id = wrapperData.replace(SPUIDefinitions.TARGET_TAG_BUTTON, ""); - return Long.valueOf(id.trim()); - } - - static boolean isTargetTable(final Component source) { - return UIComponentIdProvider.TARGET_TABLE_ID.equalsIgnoreCase(source.getId()); - } - - static boolean isDistributionTable(final Component source) { - return UIComponentIdProvider.DIST_TABLE_ID.equalsIgnoreCase(source.getId()); - } - - static Boolean isComponentDeletable(final Component source) { - return isTargetTable(source) || isDistributionTable(source) || isTargetTag(source) || isDistributionTag(source); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManagementConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManagementConfirmationWindowLayout.java deleted file mode 100644 index 68b6471b6..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManagementConfirmationWindowLayout.java +++ /dev/null @@ -1,585 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.footer; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.DeploymentManagement; -import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper; -import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.exception.InvalidMaintenanceScheduleException; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult; -import org.eclipse.hawkbit.repository.model.RepositoryModelConstants; -import org.eclipse.hawkbit.repository.model.TargetWithActionType; -import org.eclipse.hawkbit.ui.UiProperties; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout; -import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; -import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; -import org.eclipse.hawkbit.ui.common.entity.TargetIdName; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; -import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent; -import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent; -import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; -import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption; -import org.eclipse.hawkbit.ui.management.state.ManagementUIState; -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.google.common.collect.Maps; -import com.vaadin.data.Item; -import com.vaadin.data.util.IndexedContainer; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Link; -import com.vaadin.ui.Table.Align; -import com.vaadin.ui.themes.ValoTheme; - -/** - * Confirmation window for target/distributionSet delete and assignment - * operations on the Deployment View. - */ -public class ManagementConfirmationWindowLayout extends AbstractConfirmationWindowLayout { - - private static final long serialVersionUID = 1L; - - private static final String DISCARD_CHANGES = "DiscardChanges"; - - private static final String TARGET_NAME = "TargetName"; - - private static final String DISTRIBUTION_NAME = "DistributionName"; - - private static final String DIST_ID = "DistributionId"; - - private static final String TARGET_ID = "TargetId"; - - private final UiProperties uiProperties; - - private final UINotification uiNotification; - - private final ManagementUIState managementUIState; - - private final transient TargetManagement targetManagement; - - private final transient DeploymentManagement deploymentManagement; - - private final transient DistributionSetManagement distributionSetManagement; - - private final ActionTypeOptionGroupLayout actionTypeOptionGroupLayout; - - private final MaintenanceWindowLayout maintenanceWindowLayout; - - private ConfirmationTab assignmentTab; - - public ManagementConfirmationWindowLayout(final VaadinMessageSource i18n, final UIEventBus eventBus, - final ManagementUIState managementUIState, final TargetManagement targetManagement, - final DeploymentManagement deploymentManagement, final DistributionSetManagement distributionSetManagement, - final UiProperties uiProperties, final UINotification uiNotification) { - super(i18n, eventBus); - this.uiProperties = uiProperties; - this.uiNotification = uiNotification; - this.managementUIState = managementUIState; - this.targetManagement = targetManagement; - this.deploymentManagement = deploymentManagement; - this.distributionSetManagement = distributionSetManagement; - this.actionTypeOptionGroupLayout = new ActionTypeOptionGroupLayout(i18n); - this.maintenanceWindowLayout = new MaintenanceWindowLayout(i18n); - } - - @Override - protected Map getConfirmationTabs() { - final Map tabs = Maps.newHashMapWithExpectedSize(3); - if (!managementUIState.getDeletedDistributionList().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.dist.accordion.tab"), createDeletedDistributionTab()); - } - if (!managementUIState.getDeletedTargetList().isEmpty()) { - tabs.put(i18n.getMessage("caption.delete.target.accordion.tab"), createDeletedTargetTab()); - } - if (!managementUIState.getAssignedList().isEmpty()) { - tabs.put(i18n.getMessage("caption.assign.dist.accordion.tab"), createAssignmentTab()); - } - return tabs; - } - - private ConfirmationTab createAssignmentTab() { - - assignmentTab = new ConfirmationTab(); - assignmentTab.getConfirmAll().setId(UIComponentIdProvider.SAVE_ASSIGNMENT); - assignmentTab.getConfirmAll().setIcon(FontAwesome.SAVE); - assignmentTab.getConfirmAll().setCaption(i18n.getMessage("button.assign.all")); - assignmentTab.getConfirmAll().addClickListener(event -> saveAllAssignments(assignmentTab)); - - assignmentTab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - assignmentTab.getDiscardAll().setId(UIComponentIdProvider.DISCARD_ASSIGNMENT); - assignmentTab.getDiscardAll().addClickListener(event -> discardAllAssignments(assignmentTab)); - - // Add items container to the table. - assignmentTab.getTable().setContainerDataSource(getAssignmentsTableContainer()); - - // Add the discard action column - assignmentTab.getTable().addGeneratedColumn(DISCARD_CHANGES, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardAssignment((TargetIdName) itemId, assignmentTab); - return createDiscardButton(itemId, clickListener); - }); - - assignmentTab.getTable().setColumnExpandRatio(TARGET_NAME, 2); - assignmentTab.getTable().setColumnExpandRatio(DISTRIBUTION_NAME, 2); - assignmentTab.getTable().setColumnExpandRatio(DISCARD_CHANGES, 1); - assignmentTab.getTable().setVisibleColumns(TARGET_NAME, DISTRIBUTION_NAME, DISCARD_CHANGES); - assignmentTab.getTable().setColumnHeaders(i18n.getMessage("header.first.assignment.table"), - i18n.getMessage("header.second.assignment.table"), i18n.getMessage("header.third.assignment.table")); - assignmentTab.getTable().setColumnAlignment(DISCARD_CHANGES, Align.CENTER); - - actionTypeOptionGroupLayout.selectDefaultOption(); - assignmentTab.addComponent(actionTypeOptionGroupLayout, 1); - assignmentTab.addComponent(enableMaintenanceWindowLayout(), 2); - initMaintenanceWindow(); - assignmentTab.addComponent(maintenanceWindowLayout, 3); - - return assignmentTab; - - } - - private HorizontalLayout enableMaintenanceWindowLayout() { - final HorizontalLayout layout = new HorizontalLayout(); - layout.addComponent(enableMaintenanceWindowControl()); - layout.addComponent(maintenanceWindowHelpLinkControl()); - - return layout; - } - - private CheckBox enableMaintenanceWindowControl() { - final CheckBox enableMaintenanceWindow = new CheckBox(i18n.getMessage("caption.maintenancewindow.enabled")); - enableMaintenanceWindow.setId(UIComponentIdProvider.MAINTENANCE_WINDOW_ENABLED_ID); - enableMaintenanceWindow.addStyleName(ValoTheme.CHECKBOX_SMALL); - enableMaintenanceWindow.addStyleName("dist-window-maintenance-window-enable"); - enableMaintenanceWindow.addValueChangeListener(event -> { - final Boolean isMaintenanceWindowEnabled = enableMaintenanceWindow.getValue(); - maintenanceWindowLayout.setVisible(isMaintenanceWindowEnabled); - maintenanceWindowLayout.setEnabled(isMaintenanceWindowEnabled); - enableSaveButton(!isMaintenanceWindowEnabled); - maintenanceWindowLayout.clearAllControls(); - }); - - return enableMaintenanceWindow; - } - - private void enableSaveButton(final boolean enabled) { - assignmentTab.getConfirmAll().setEnabled(enabled); - } - - private Link maintenanceWindowHelpLinkControl() { - final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView(); - return SPUIComponentProvider.getHelpLink(maintenanceWindowHelpUrl); - } - - private void initMaintenanceWindow() { - maintenanceWindowLayout.setVisible(false); - maintenanceWindowLayout.setEnabled(false); - maintenanceWindowLayout.getScheduleControl() - .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onScheduleChange(event))); - maintenanceWindowLayout.getDurationControl() - .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onDurationChange(event))); - } - - private void saveAllAssignments(final ConfirmationTab tab) { - if (!isMaintenanceWindowValid()) { - return; - } - - final Set itemIds = managementUIState.getAssignedList().keySet(); - Long distId; - List targetIdSetList; - List tempIdList; - final ActionType actionType = ((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout - .getActionTypeOptionGroup().getValue()).getActionType(); - final long forcedTimeStamp = (((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout - .getActionTypeOptionGroup().getValue()) == ActionTypeOption.AUTO_FORCED) - ? actionTypeOptionGroupLayout.getForcedTimeDateField().getValue().getTime() - : RepositoryModelConstants.NO_FORCE_TIME; - - final Map> saveAssignedList = Maps.newHashMapWithExpectedSize(itemIds.size()); - - int successAssignmentCount = 0; - int duplicateAssignmentCount = 0; - for (final TargetIdName itemId : itemIds) { - final DistributionSetIdName distitem = managementUIState.getAssignedList().get(itemId); - distId = distitem.getId(); - - if (saveAssignedList.containsKey(distId)) { - targetIdSetList = saveAssignedList.get(distId); - } else { - targetIdSetList = new ArrayList<>(); - } - targetIdSetList.add(itemId); - saveAssignedList.put(distId, targetIdSetList); - } - - final String maintenanceSchedule = maintenanceWindowLayout.getMaintenanceSchedule(); - final String maintenanceDuration = maintenanceWindowLayout.getMaintenanceDuration(); - final String maintenanceTimeZone = maintenanceWindowLayout.getMaintenanceTimeZone(); - - for (final Map.Entry> mapEntry : saveAssignedList.entrySet()) { - tempIdList = saveAssignedList.get(mapEntry.getKey()); - final DistributionSetAssignmentResult distributionSetAssignmentResult = deploymentManagement - .assignDistributionSet(mapEntry.getKey(), - tempIdList.stream().map(t -> maintenanceWindowLayout.isEnabled() - ? new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp, - maintenanceSchedule, maintenanceDuration, maintenanceTimeZone) - : new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp)) - .collect(Collectors.toList())); - - if (distributionSetAssignmentResult.getAssigned() > 0) { - successAssignmentCount += distributionSetAssignmentResult.getAssigned(); - } - if (distributionSetAssignmentResult.getAlreadyAssigned() > 0) { - duplicateAssignmentCount += distributionSetAssignmentResult.getAlreadyAssigned(); - } - } - addMessage(successAssignmentCount, duplicateAssignmentCount); - resfreshPinnedDetails(saveAssignedList); - - managementUIState.getAssignedList().clear(); - setActionMessage(i18n.getMessage("message.target.ds.assign.success")); - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.SAVED_ASSIGNMENTS); - } - - // Exception squid:S1166 - the user is notified when the maintenance - // schedule validation fails - @SuppressWarnings("squid:S1166") - private boolean isMaintenanceWindowValid() { - if (maintenanceWindowLayout.isEnabled()) { - try { - MaintenanceScheduleHelper.validateMaintenanceSchedule(maintenanceWindowLayout.getMaintenanceSchedule(), - maintenanceWindowLayout.getMaintenanceDuration(), - maintenanceWindowLayout.getMaintenanceTimeZone()); - } catch (final InvalidMaintenanceScheduleException e) { - uiNotification.displayValidationError(e.getMessage()); - return false; - } - } - - return true; - } - - private void addMessage(final int successAssignmentCount, final int duplicateAssignmentCount) { - if (successAssignmentCount > 0) { - addToConsolitatedMsg(getAssigmentSuccessMessage(successAssignmentCount)); - } - if (duplicateAssignmentCount > 0) { - addToConsolitatedMsg(getDuplicateAssignmentMessage(duplicateAssignmentCount)); - } - - } - - private void resfreshPinnedDetails(final Map> saveAssignedList) { - final Optional pinnedDist = managementUIState.getTargetTableFilters().getPinnedDistId(); - final Optional pinnedTarget = managementUIState.getDistributionTableFilters().getPinnedTarget(); - - if (pinnedDist.isPresent()) { - if (saveAssignedList.keySet().contains(pinnedDist.get())) { - eventBus.publish(this, PinUnpinEvent.PIN_DISTRIBUTION); - } - } else if (pinnedTarget.isPresent()) { - final Set assignedTargetIds = managementUIState.getAssignedList().keySet(); - if (assignedTargetIds.contains(pinnedTarget.get())) { - eventBus.publish(this, PinUnpinEvent.PIN_TARGET); - } - } - - } - - private String getAssigmentSuccessMessage(final int assignedCount) { - return FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.target.assignment", assignedCount); - } - - private String getDuplicateAssignmentMessage(final int alreadyAssignedCount) { - return FontAwesome.TASKS.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.target.alreadyAssigned", alreadyAssignedCount); - } - - private void discardAllAssignments(final ConfirmationTab tab) { - removeCurrentTab(tab); - managementUIState.getAssignedList().clear(); - setActionMessage(i18n.getMessage("message.assign.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS); - } - - private void discardAssignment(final TargetIdName targetId, final ConfirmationTab tab) { - tab.getTable().getContainerDataSource().removeItem(targetId); - managementUIState.getAssignedList().remove(targetId); - final int assigCount = tab.getTable().getContainerDataSource().size(); - if (0 == assigCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ASSIGNMENT); - } - } - - private IndexedContainer getAssignmentsTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(TARGET_NAME, String.class, ""); - contactContainer.addContainerProperty(DISTRIBUTION_NAME, String.class, ""); - contactContainer.addContainerProperty(TARGET_ID, Long.class, ""); - contactContainer.addContainerProperty(DIST_ID, Long.class, ""); - final Map assignedList = managementUIState.getAssignedList(); - - for (final Map.Entry entry : assignedList.entrySet()) { - final Item saveTblitem = contactContainer.addItem(entry.getKey()); - - saveTblitem.getItemProperty(TARGET_NAME).setValue(entry.getKey().getTargetName()); - - saveTblitem.getItemProperty(DISTRIBUTION_NAME).setValue(HawkbitCommonUtil - .getDistributionNameAndVersion(entry.getValue().getName(), entry.getValue().getVersion())); - - saveTblitem.getItemProperty(TARGET_ID).setValue(entry.getKey().getTargetId()); - saveTblitem.getItemProperty(DIST_ID).setValue(entry.getValue().getId()); - } - return contactContainer; - } - - private ConfirmationTab createDeletedTargetTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - // TobeDone ? y to set caption every time?? - tab.getConfirmAll().setId(UIComponentIdProvider.TARGET_DELETE_ALL); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteAllTargets(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().addClickListener(event -> discardAllTargets(tab)); - - /* Add items container to the table. */ - tab.getTable().setContainerDataSource(getTargetModuleTableContainer()); - - /* Add the discard action column */ - tab.getTable().addGeneratedColumn(DISCARD_CHANGES, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardTargetDelete((TargetIdName) itemId, tab); - return createDiscardButton(itemId, clickListener); - - }); - - tab.getTable().setVisibleColumns(TARGET_NAME, DISCARD_CHANGES); - tab.getTable().setColumnHeaders(i18n.getMessage("header.first.deletetarget.table"), - i18n.getMessage("header.second.deletetarget.table")); - - tab.getTable().setColumnExpandRatio(TARGET_NAME, SPUIDefinitions.TARGET_DISTRIBUTION_COLUMN_WIDTH); - tab.getTable().setColumnExpandRatio(DISCARD_CHANGES, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setColumnAlignment(DISCARD_CHANGES, Align.CENTER); - return tab; - } - - private ConfirmationTab createDeletedDistributionTab() { - final ConfirmationTab tab = new ConfirmationTab(); - - // TobeDone ? y to set caption every time?? - tab.getConfirmAll().setId(UIComponentIdProvider.DIST_DELETE_ALL); - tab.getConfirmAll().setIcon(FontAwesome.TRASH_O); - tab.getConfirmAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DELETE_ALL)); - tab.getConfirmAll().addClickListener(event -> deleteAllDistributions(tab)); - - tab.getDiscardAll().setCaption(i18n.getMessage(SPUILabelDefinitions.BUTTON_DISCARD_ALL)); - tab.getDiscardAll().addClickListener(event -> discardAllDistributions(tab)); - - /* Add items container to the table. */ - tab.getTable().setContainerDataSource(getDSModuleTableContainer()); - - /* Add the discard action column */ - tab.getTable().addGeneratedColumn(DISCARD_CHANGES, (source, itemId, columnId) -> { - final ClickListener clickListener = event -> discardDSDelete((DistributionSetIdName) itemId, tab); - return createDiscardButton(itemId, clickListener); - - }); - - tab.getTable().setColumnExpandRatio(DISTRIBUTION_NAME, SPUIDefinitions.TARGET_DISTRIBUTION_COLUMN_WIDTH); - tab.getTable().setColumnExpandRatio(DISCARD_CHANGES, SPUIDefinitions.DISCARD_COLUMN_WIDTH); - tab.getTable().setVisibleColumns(DISTRIBUTION_NAME, DISCARD_CHANGES); - tab.getTable().setColumnHeaders(i18n.getMessage("header.one.deletedist.table"), - i18n.getMessage("header.second.deletedist.table")); - tab.getTable().setColumnAlignment(DISCARD_CHANGES, Align.CENTER); - return tab; - } - - private void discardDSDelete(final DistributionSetIdName discardDsIdName, final ConfirmationTab tab) { - managementUIState.getDeletedDistributionList().remove(discardDsIdName); - tab.getTable().getContainerDataSource().removeItem(discardDsIdName); - final int deleteCount = tab.getTable().size(); - if (0 == deleteCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DISTRIBUTIONS); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DELETE_DS); - } - } - - private IndexedContainer getDSModuleTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(DIST_ID, Long.class, ""); - contactContainer.addContainerProperty(DISTRIBUTION_NAME, String.class, ""); - Item item; - for (final DistributionSetIdName distIdName : managementUIState.getDeletedDistributionList()) { - item = contactContainer.addItem(distIdName); - item.getItemProperty(DIST_ID).setValue(distIdName.getId()); - - final String distName = HawkbitCommonUtil.getDistributionNameAndVersion(distIdName.getName(), - distIdName.getVersion()); - item.getItemProperty(DISTRIBUTION_NAME).setValue(distName); - } - return contactContainer; - } - - private void discardAllDistributions(final ConfirmationTab tab) { - removeCurrentTab(tab); - managementUIState.getDeletedDistributionList().clear(); - setActionMessage(i18n.getMessage("message.dist.discard.success")); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_DISTRIBUTIONS); - } - - private void deleteAllDistributions(final ConfirmationTab tab) { - final Collection deletedIds = managementUIState.getDeletedDistributionList().stream() - .map(DistributionSetIdName::getId).collect(Collectors.toList()); - - distributionSetManagement.delete(deletedIds); - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.REMOVE_ENTITY, deletedIds)); - - addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.dist.deleted", managementUIState.getDeletedDistributionList().size())); - - removeDeletedDistributionsFromAssignmentTab(); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.dist.delete.success")); - - managementUIState.getTargetTableFilters().getPinnedDistId() - .ifPresent(distId -> unPinDeletedDS(deletedIds, distId)); - managementUIState.getDeletedDistributionList().clear(); - } - - private void unPinDeletedTarget(final TargetIdName pinnedTarget) { - final Set deletedTargets = managementUIState.getDeletedTargetList(); - if (deletedTargets.contains(pinnedTarget)) { - managementUIState.getDistributionTableFilters().setPinnedTarget(null); - eventBus.publish(this, PinUnpinEvent.UNPIN_TARGET); - } - } - - private void unPinDeletedDS(final Collection deletedDsIds, final Long pinnedDsId) { - if (deletedDsIds.contains(pinnedDsId)) { - managementUIState.getTargetTableFilters().setPinnedDistId(null); - eventBus.publish(this, PinUnpinEvent.UNPIN_DISTRIBUTION); - } - } - - private void removeDeletedDistributionsFromAssignmentTab() { - for (final DistributionSetIdName distributionSetIdName : managementUIState.getDeletedDistributionList()) { - managementUIState.getAssignedList().entrySet().stream() - .forEach(entry -> removeFromAssignmentTab(entry, distributionSetIdName)); - final Collection list = managementUIState.getAssignedList().values(); - final Iterator itr = list.iterator(); - while (itr.hasNext()) { - if (itr.next().equals(distributionSetIdName)) { - itr.remove(); - } - } - } - eventBus.publish(this, SaveActionWindowEvent.SHOW_HIDE_TAB); - } - - private void removeFromAssignmentTab(final Entry entry, - final DistributionSetIdName value) { - if (Objects.equals(entry.getValue(), value)) { - assignmentTab.getTable().removeItem(entry.getKey().getTargetId()); - } - } - - private IndexedContainer getTargetModuleTableContainer() { - final IndexedContainer contactContainer = new IndexedContainer(); - contactContainer.addContainerProperty(TARGET_ID, Long.class, ""); - contactContainer.addContainerProperty(TARGET_NAME, String.class, ""); - Item item; - for (final TargetIdName targteId : managementUIState.getDeletedTargetList()) { - item = contactContainer.addItem(targteId); - item.getItemProperty(TARGET_ID).setValue(targteId.getTargetId()); - item.getItemProperty(TARGET_NAME).setValue(targteId.getTargetName()); - } - return contactContainer; - } - - private void discardTargetDelete(final TargetIdName itemId, final ConfirmationTab tab) { - managementUIState.getDeletedTargetList().remove(itemId); - tab.getTable().getContainerDataSource().removeItem(itemId); - - final int assigCount = tab.getTable().getContainerDataSource().size(); - if (0 == assigCount) { - removeCurrentTab(tab); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_TARGETS); - } else { - eventBus.publish(this, SaveActionWindowEvent.DISCARD_DELETE_TARGET); - } - } - - private void discardAllTargets(final ConfirmationTab tab) { - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.target.discard.success")); - managementUIState.getDeletedTargetList().clear(); - eventBus.publish(this, SaveActionWindowEvent.DISCARD_ALL_TARGETS); - } - - private void deleteAllTargets(final ConfirmationTab tab) { - final Set targetIdNames = managementUIState.getDeletedTargetList(); - - final Set targetIds = targetIdNames.stream().map(TargetIdName::getTargetId).collect(Collectors.toSet()); - - targetManagement.delete(targetIds); - - eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.REMOVE_ENTITY, targetIds)); - - addToConsolitatedMsg(FontAwesome.TRASH_O.getHtml() + SPUILabelDefinitions.HTML_SPACE - + i18n.getMessage("message.target.deleted", targetIds.size())); - removeCurrentTab(tab); - setActionMessage(i18n.getMessage("message.target.delete.success")); - removeDeletedTargetsFromAssignmentTab(); - - managementUIState.getDistributionTableFilters().getPinnedTarget().ifPresent(this::unPinDeletedTarget); - eventBus.publish(this, SaveActionWindowEvent.SHOW_HIDE_TAB); - managementUIState.getDeletedTargetList().clear(); - } - - private void removeDeletedTargetsFromAssignmentTab() { - for (final TargetIdName targetNameId : managementUIState.getDeletedTargetList()) { - if (managementUIState.getAssignedList().containsKey(targetNameId)) { - managementUIState.getAssignedList().remove(targetNameId); - assignmentTab.getTable().removeItem(targetNameId.getTargetId()); - } - } - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/ActionTypeOptionGroupLayout.java similarity index 95% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/ActionTypeOptionGroupLayout.java index 8a09d97e6..8c7faf3c3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/ActionTypeOptionGroupLayout.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.footer; +package org.eclipse.hawkbit.ui.management.miscs; import java.time.LocalDateTime; import java.util.Date; @@ -31,12 +31,11 @@ import com.vaadin.ui.themes.ValoTheme; /** * Action type option group layout. - * - * */ public class ActionTypeOptionGroupLayout extends HorizontalLayout { - private static final long serialVersionUID = -5624576558669213864L; + private static final long serialVersionUID = 1L; + private static final String STYLE_DIST_WINDOW_ACTIONTYPE = "dist-window-actiontype"; private final VaadinMessageSource i18n; @@ -45,6 +44,12 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { private DateField forcedTimeDateField; + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + */ public ActionTypeOptionGroupLayout(final VaadinMessageSource i18n) { this.i18n = i18n; @@ -81,7 +86,6 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { final FlexibleOptionGroupItemComponent forceItem = actionTypeOptionGroup .getItemComponent(ActionTypeOption.FORCED); forceItem.setStyleName(STYLE_DIST_WINDOW_ACTIONTYPE); - // set Id for Forced radio button. forceItem.setId("save.action.radio.forced"); addComponent(forceItem); final Label forceLabel = new Label(); @@ -106,7 +110,6 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { final FlexibleOptionGroupItemComponent autoForceItem = actionTypeOptionGroup .getItemComponent(ActionTypeOption.AUTO_FORCED); autoForceItem.setStyleName(STYLE_DIST_WINDOW_ACTIONTYPE); - // setted Id for Time Forced radio button. autoForceItem.setId(UIComponentIdProvider.ACTION_TYPE_OPTION_GROUP_SAVE_TIMEFORCED); addComponent(autoForceItem); final Label autoForceLabel = new Label(); @@ -142,6 +145,10 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { actionTypeOptionGroup.select(ActionTypeOption.FORCED); } + /** + * Enum which described the options for the action type + * + */ public enum ActionTypeOption { FORCED(ActionType.FORCED), SOFT(ActionType.SOFT), AUTO_FORCED(ActionType.TIMEFORCED); @@ -151,9 +158,6 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { this.actionType = actionType; } - /** - * @return - */ public ActionType getActionType() { return actionType; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/MaintenanceWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/MaintenanceWindowLayout.java similarity index 99% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/MaintenanceWindowLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/MaintenanceWindowLayout.java index 9cd70f3d9..8b9d7a6c7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/MaintenanceWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/miscs/MaintenanceWindowLayout.java @@ -7,7 +7,7 @@ * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.footer; +package org.eclipse.hawkbit.ui.management.miscs; import java.time.ZoneId; import java.time.ZonedDateTime; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java index 6d314e9cd..1fb45182a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/DistributionTableFilters.java @@ -27,7 +27,7 @@ import com.vaadin.spring.annotation.VaadinSessionScope; @SpringComponent public class DistributionTableFilters implements Serializable { - private static final long serialVersionUID = -5251492630546463593L; + private static final long serialVersionUID = 1L; private String searchText; @@ -37,8 +37,6 @@ public class DistributionTableFilters implements Serializable { private final List distSetTags = new ArrayList<>(); - private List clickedDistSetTags = new ArrayList<>(); - private Boolean noTagSelected = Boolean.FALSE; public void setNoTagSelected(final Boolean noTagSelected) { @@ -53,14 +51,6 @@ public class DistributionTableFilters implements Serializable { return distSetTags; } - public List getClickedDistSetTags() { - return clickedDistSetTags; - } - - public void setClickedDistSetTags(final List clickedDistSetTags) { - this.clickedDistSetTags = clickedDistSetTags; - } - public Optional getDistId() { return Optional.ofNullable(distId); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/ManagementUIState.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/ManagementUIState.java index 601349823..90c489376 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/ManagementUIState.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/ManagementUIState.java @@ -243,7 +243,7 @@ public class ManagementUIState implements ManagementEntityState, Serializable { return noDataAvilableTarget; } - public void setNoDataAvilableTarget(final boolean noDataAvilableTarget) { + public void setNoDataAvailableTarget(final boolean noDataAvilableTarget) { this.noDataAvilableTarget = noDataAvilableTarget; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetTableFilters.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetTableFilters.java index 943fafeea..d039ab454 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetTableFilters.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetTableFilters.java @@ -26,16 +26,22 @@ import com.vaadin.spring.annotation.VaadinSessionScope; @SpringComponent public class TargetTableFilters implements Serializable { - private static final long serialVersionUID = -5251492630546463593L; + private static final long serialVersionUID = 1L; private final List clickedTargetTags = new ArrayList<>(); + private final List clickedStatusTargetTags = new ArrayList<>(); + private boolean isOverdueFilterEnabled = Boolean.FALSE; private String searchText; + private DistributionSetIdName distributionSet; + private Long pinnedDistId; + private Long targetsCreatedCount; + private Float progressBarCurrentValue; private final TargetBulkUpload bulkUpload = new TargetBulkUpload(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index d54284c09..d54546f3f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -40,7 +40,7 @@ import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.TargetBulkUpload; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -390,7 +390,7 @@ public class BulkUploadHandler extends CustomComponent public void uploadStarted(final StartedEvent event) { if (!event.getFilename().endsWith(".csv")) { - new HawkbitErrorNotificationMessage(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null, + new HawkbitErrorNotificationMessage(SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null, i18n.getMessage("bulk.targets.upload"), true).show(Page.getCurrent()); LOG.error("Wrong file format for file {}", event.getFilename()); upload.interruptUpload(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 42c0cf328..4c82018b7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -150,8 +150,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window createNewWindow() { window = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW) - .caption(i18n.getMessage(UIComponentIdProvider.TARGET_ADD_CAPTION)).content(this).layout(formLayout) - .i18n(i18n).saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow(); + .caption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.target"))).content(this) + .layout(formLayout).i18n(i18n).saveDialogCloseListener(new SaveOnDialogCloseListener()) + .buildCommonDialogWindow(); return window; } @@ -171,6 +172,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } populateValuesOfTarget(target.get()); createNewWindow(); + window.setCaption(i18n.getMessage("caption.update", i18n.getMessage("caption.target"))); window.addStyleName("target-update-window"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 7fc4f9d71..14ce85254 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -22,7 +22,7 @@ import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.management.dstable.DistributionBeanQuery; import org.eclipse.hawkbit.ui.management.event.BulkUploadPopupEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; @@ -160,7 +160,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private Button getCloseButton() { final Button closeBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.BULK_UPLOAD_CLOSE_BUTTON_ID, "", - "", "", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); + "", "", true, FontAwesome.TIMES, SPUIButtonStyleNoBorder.class); closeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); closeBtn.addClickListener(event -> closePopup()); return closeBtn; @@ -168,7 +168,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private Button getMinimizeButton() { final Button minimizeBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.BULK_UPLOAD_MINIMIZE_BUTTON_ID, - "", "", "", true, FontAwesome.MINUS, SPUIButtonStyleSmallNoBorder.class); + "", "", "", true, FontAwesome.MINUS, SPUIButtonStyleNoBorder.class); minimizeBtn.addStyleName(ValoTheme.BUTTON_BORDERLESS); minimizeBtn.addClickListener(event -> minimizeWindow()); minimizeBtn.setEnabled(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java index 110feaaa7..5418a751f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java @@ -116,7 +116,7 @@ public class TargetDetails extends AbstractTableDetailsLayout { if (targetWindow == null) { return; } - targetWindow.setCaption(getI18n().getMessage(UIComponentIdProvider.TARGET_UPDATE_CAPTION)); + targetWindow.setCaption(getI18n().getMessage("caption.update", getI18n().getMessage("caption.target"))); UI.getCurrent().addWindow(targetWindow); targetWindow.setVisible(Boolean.TRUE); } @@ -270,4 +270,10 @@ public class TargetDetails extends AbstractTableDetailsLayout { // No implementation required } + @Override + protected String getMetadataButtonId() { + // No implementation required + return null; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 2f770ac41..e50a5020d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -13,6 +13,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -22,24 +23,35 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.FilterParams; +import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.event.remote.entity.RemoteEntityEvent; +import org.eclipse.hawkbit.repository.exception.InvalidMaintenanceScheduleException; +import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult; +import org.eclipse.hawkbit.repository.model.RepositoryModelConstants; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.UiProperties; +import org.eclipse.hawkbit.ui.common.ConfirmationDialog; import org.eclipse.hawkbit.ui.common.ManagementEntityState; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; +import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; import org.eclipse.hawkbit.ui.common.entity.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.entity.TargetIdName; import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent; @@ -48,6 +60,9 @@ import org.eclipse.hawkbit.ui.management.event.TargetAddUpdateWindowEvent; import org.eclipse.hawkbit.ui.management.event.TargetFilterEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout.ActionTypeOption; +import org.eclipse.hawkbit.ui.management.miscs.MaintenanceWindowLayout; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.TargetTableFilters; import org.eclipse.hawkbit.ui.push.CancelTargetAssignmentEventContainer; @@ -83,8 +98,11 @@ import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; +import com.vaadin.ui.Link; import com.vaadin.ui.Table; import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; @@ -109,7 +127,7 @@ public class TargetTable extends AbstractTable { private final transient TargetTagManagement tagManagement; - private final SpPermissionChecker permChecker; + private final transient DeploymentManagement deploymentManagement; private final ManagementViewClientCriterion managementViewClientCriterion; @@ -119,17 +137,29 @@ public class TargetTable extends AbstractTable { private boolean targetPinned; + private final UiProperties uiProperties; + + private ConfirmationDialog confirmDialog; + + private final ActionTypeOptionGroupLayout actionTypeOptionGroupLayout; + + private final MaintenanceWindowLayout maintenanceWindowLayout; + public TargetTable(final UIEventBus eventBus, final VaadinMessageSource i18n, final UINotification notification, final TargetManagement targetManagement, final ManagementUIState managementUIState, final SpPermissionChecker permChecker, final ManagementViewClientCriterion managementViewClientCriterion, - final DistributionSetManagement distributionSetManagement, final TargetTagManagement tagManagement) { - super(eventBus, i18n, notification); + final DistributionSetManagement distributionSetManagement, final TargetTagManagement tagManagement, + final DeploymentManagement deploymentManagement, final UiProperties uiProperties) { + super(eventBus, i18n, notification, permChecker); this.targetManagement = targetManagement; - this.permChecker = permChecker; this.managementViewClientCriterion = managementViewClientCriterion; this.managementUIState = managementUIState; this.distributionSetManagement = distributionSetManagement; this.tagManagement = tagManagement; + this.deploymentManagement = deploymentManagement; + this.uiProperties = uiProperties; + this.actionTypeOptionGroupLayout = new ActionTypeOptionGroupLayout(i18n); + this.maintenanceWindowLayout = new MaintenanceWindowLayout(i18n); setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator()); addNewContainerDS(); @@ -150,7 +180,6 @@ public class TargetTable extends AbstractTable { void onTargetUpdatedEvents(final TargetUpdatedEventContainer eventContainer) { @SuppressWarnings("unchecked") final List visibleItemIds = (List) getVisibleItemIds(); - if (isFilterEnabled()) { refreshTargets(); } else { @@ -163,7 +192,7 @@ public class TargetTable extends AbstractTable { private void publishTargetSelectedEntityForRefresh( final Stream> targetEntityEventStream) { targetEntityEventStream.filter(event -> isLastSelectedTarget(event.getEntityId())).filter(Objects::nonNull) - .findAny().ifPresent(event -> eventBus.publish(this, + .findAny().ifPresent(event -> getEventBus().publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity()))); } @@ -193,7 +222,7 @@ public class TargetTable extends AbstractTable { UI.getCurrent().access(() -> { if (checkFilterEvent(filterEvent)) { refreshFilter(); - eventBus.publish(this, ManagementUIEvent.TARGET_TABLE_FILTER); + getEventBus().publish(this, ManagementUIEvent.TARGET_TABLE_FILTER); } }); } @@ -279,11 +308,6 @@ public class TargetTable extends AbstractTable { (source, itemId, columnId) -> getTargetPollTime(itemId)); } - @Override - protected boolean isFirstRowSelectedOnLoad() { - return managementUIState.getSelectedTargetId().isEmpty(); - } - @Override protected Object getItemIdToSelect() { return managementUIState.getSelectedTargetId().isEmpty() ? null : managementUIState.getSelectedTargetId(); @@ -291,7 +315,7 @@ public class TargetTable extends AbstractTable { @Override protected void publishSelectedEntityEvent(final Target selectedLastEntity) { - eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); + getEventBus().publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedLastEntity)); } @Override @@ -337,17 +361,23 @@ public class TargetTable extends AbstractTable { private Map prepareQueryConfigFilters() { final Map queryConfig = Maps.newHashMapWithExpectedSize(7); - managementUIState.getTargetTableFilters().getSearchText() - .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); - managementUIState.getTargetTableFilters().getDistributionSet() - .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_DISTRIBUTION, value.getId())); - managementUIState.getTargetTableFilters().getPinnedDistId() - .ifPresent(value -> queryConfig.put(SPUIDefinitions.ORDER_BY_DISTRIBUTION, value)); - managementUIState.getTargetTableFilters().getTargetFilterQuery() - .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TARGET_FILTER_QUERY, value)); + managementUIState.getTargetTableFilters().getSearchText().ifPresent( + + value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); + managementUIState.getTargetTableFilters().getDistributionSet().ifPresent( + + value -> queryConfig.put(SPUIDefinitions.FILTER_BY_DISTRIBUTION, value.getId())); + managementUIState.getTargetTableFilters().getPinnedDistId().ifPresent( + + value -> queryConfig.put(SPUIDefinitions.ORDER_BY_DISTRIBUTION, value)); + managementUIState.getTargetTableFilters().getTargetFilterQuery().ifPresent( + + value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TARGET_FILTER_QUERY, value)); queryConfig.put(SPUIDefinitions.FILTER_BY_NO_TAG, managementUIState.getTargetTableFilters().isNoTagSelected()); - if (isFilteredByTags()) { + if ( + + isFilteredByTags()) { final List list = new ArrayList<>(); list.addAll(managementUIState.getTargetTableFilters().getClickedTargetTags()); queryConfig.put(SPUIDefinitions.FILTER_BY_TAG, list.toArray(new String[list.size()])); @@ -398,7 +428,7 @@ public class TargetTable extends AbstractTable { pinBtn.addStyleName(TARGET_PINNED); targetPinned = Boolean.TRUE; targetPinnedBtn = pinBtn; - eventBus.publish(this, PinUnpinEvent.PIN_TARGET); + getEventBus().publish(this, PinUnpinEvent.PIN_TARGET); } pinBtn.addStyleName(SPUIStyleDefinitions.TARGET_STATUS_PIN_TOGGLE); HawkbitCommonUtil.applyStatusLblStyle(this, pinBtn, itemId); @@ -442,7 +472,7 @@ public class TargetTable extends AbstractTable { /* if distribution set is pinned ,unpin target if pinned */ managementUIState.getTargetTableFilters().setPinnedDistId(null); /* on unpin of target dist table should refresh Dist table restyle */ - eventBus.publish(this, PinUnpinEvent.PIN_TARGET); + getEventBus().publish(this, PinUnpinEvent.PIN_TARGET); /* change target table styling */ styleTargetTable(); eventBtn.addStyleName(TARGET_PINNED); @@ -451,7 +481,7 @@ public class TargetTable extends AbstractTable { private void unPinTarget(final Button eventBtn) { managementUIState.getDistributionTableFilters().setPinnedTarget(null); - eventBus.publish(this, PinUnpinEvent.UNPIN_TARGET); + getEventBus().publish(this, PinUnpinEvent.UNPIN_TARGET); resetPinStyle(eventBtn); } @@ -468,7 +498,7 @@ public class TargetTable extends AbstractTable { @Override protected void onDropEventFromTable(final DragAndDropEvent event) { - dsToTargetAssignment(event); + assignDsToTarget(event); } @Override @@ -482,8 +512,8 @@ public class TargetTable extends AbstractTable { final String tagName = ((DragAndDropWrapper) (event.getTransferable().getSourceComponent())).getData() .toString(); if (tagName.equals(SPUIDefinitions.TARGET_TAG_BUTTON)) { - notification.displayValidationError( - i18n.getMessage("message.tag.cannot.be.assigned", i18n.getMessage("label.no.tag.assigned"))); + getNotification().displayValidationError(getI18n().getMessage("message.tag.cannot.be.assigned", + getI18n().getMessage("label.no.tag.assigned"))); return false; } return true; @@ -495,8 +525,8 @@ public class TargetTable extends AbstractTable { final String targTagName = HawkbitCommonUtil.removePrefix(event.getTransferable().getSourceComponent().getId(), SPUIDefinitions.TARGET_TAG_ID_PREFIXS); if (targetList.isEmpty()) { - final String actionDidNotWork = i18n.getMessage("message.action.did.not.work"); - notification.displayValidationError(actionDidNotWork); + final String actionDidNotWork = getI18n().getMessage("message.action.did.not.work"); + getNotification().displayValidationError(actionDidNotWork); return; } @@ -524,21 +554,21 @@ public class TargetTable extends AbstractTable { final List controllerIds = targetManagement.get(targetIds).stream().map(Target::getControllerId) .collect(Collectors.toList()); if (controllerIds.isEmpty()) { - notification.displayWarning(i18n.getMessage("targets.not.exists")); + getNotification().displayWarning(getI18n().getMessage("targets.not.exists")); return new TargetTagAssignmentResult(0, 0, 0, Lists.newArrayListWithCapacity(0), Lists.newArrayListWithCapacity(0), null); } final Optional tag = tagManagement.getByName(targTagName); if (!tag.isPresent()) { - notification.displayWarning(i18n.getMessage("targettag.not.exists", targTagName)); + getNotification().displayWarning(getI18n().getMessage("targettag.not.exists", targTagName)); return new TargetTagAssignmentResult(0, 0, 0, Lists.newArrayListWithCapacity(0), Lists.newArrayListWithCapacity(0), null); } final TargetTagAssignmentResult result = targetManagement.toggleTagAssignment(controllerIds, targTagName); - notification.displaySuccess(HawkbitCommonUtil.createAssignmentMessage(targTagName, result, i18n)); + getNotification().displaySuccess(HawkbitCommonUtil.createAssignmentMessage(targTagName, result, getI18n())); return result; } @@ -549,11 +579,11 @@ public class TargetTable extends AbstractTable { SPUIDefinitions.TARGET_TAG_ID_PREFIXS); if (wrapperSource.getId().startsWith(SPUIDefinitions.TARGET_TAG_ID_PREFIXS)) { if ("NO TAG".equals(tagName)) { - notification.displayValidationError(i18n.getMessage(ACTION_NOT_ALLOWED_MSG)); + getNotification().displayValidationError(getI18n().getMessage(ACTION_NOT_ALLOWED_MSG)); return false; } } else { - notification.displayValidationError(i18n.getMessage(ACTION_NOT_ALLOWED_MSG)); + getNotification().displayValidationError(getI18n().getMessage(ACTION_NOT_ALLOWED_MSG)); return false; } @@ -567,83 +597,10 @@ public class TargetTable extends AbstractTable { @Override protected List hasMissingPermissionsForDrop() { - return permChecker.hasUpdateTargetPermission() ? Collections.emptyList() + return getPermChecker().hasUpdateTargetPermission() ? Collections.emptyList() : Arrays.asList(SpPermission.UPDATE_TARGET); } - private void dsToTargetAssignment(final DragAndDropEvent event) { - final TableTransferable transferable = (TableTransferable) event.getTransferable(); - final AbstractTable source = (AbstractTable) transferable.getSourceComponent(); - final Set ids = source.getDeletedEntityByTransferable(transferable); - final AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails) event.getTargetDetails(); - final Object targetItemId = dropData.getItemIdOver(); - LOG.debug("Adding a log to check if targetItemId is null : {} ", targetItemId); - if (targetItemId == null) { - getNotification().displayWarning(i18n.getMessage("target.not.exists", "")); - return; - } - final Long targetId = (Long) targetItemId; - final Optional target = targetManagement.get(targetId); - if (!target.isPresent()) { - getNotification().displayWarning(i18n.getMessage("target.not.exists", "")); - return; - } - final TargetIdName createTargetIdName = new TargetIdName(target.get()); - - final List findDistributionSetAllById = distributionSetManagement.get(ids); - - if (findDistributionSetAllById.isEmpty()) { - notification.displayWarning(i18n.getMessage("distributionsets.not.exists")); - return; - } - - addNewTargetToAssignmentList(createTargetIdName, findDistributionSetAllById); - } - - private void addNewTargetToAssignmentList(final TargetIdName createTargetIdName, - final List findDistributionSetAllById) { - String message = null; - final Set distributionIdNameSet = findDistributionSetAllById.stream() - .map(DistributionSetIdName::new).collect(Collectors.toSet()); - - for (final DistributionSetIdName distributionNameId : distributionIdNameSet) { - if (distributionNameId != null) { - if (managementUIState.getAssignedList().keySet().contains(createTargetIdName) - && managementUIState.getAssignedList().get(createTargetIdName).equals(distributionNameId)) { - message = getPendingActionMessage(message, - HawkbitCommonUtil.getDistributionNameAndVersion(distributionNameId.getName(), - distributionNameId.getVersion()), - createTargetIdName.getControllerId()); - } else { - managementUIState.getAssignedList().put(createTargetIdName, distributionNameId); - } - } - } - showOrHidePopupAndNotification(message); - } - - /** - * Hide and show Notification Msg. - * - * @param message - * as msg - */ - private void showOrHidePopupAndNotification(final String message) { - if (null != managementUIState.getAssignedList() && !managementUIState.getAssignedList().isEmpty()) { - eventBus.publish(this, ManagementUIEvent.UPDATE_COUNT); - } - if (null != message) { - notification.displayValidationError(message); - } - } - - private String getPendingActionMessage(final String message, final String distName, final String controllerId) { - if (message == null) { - return i18n.getMessage("message.dist.pending.action", controllerId, distName); - } - return i18n.getMessage("message.target.assigned.pending"); - } - /** * To update target details in the table. * @@ -679,7 +636,6 @@ public class TargetTable extends AbstractTable { /* Update the new Name, Description and poll date */ item.getItemProperty(SPUILabelDefinitions.VAR_NAME).setValue(updatedTarget.getName()); - } } @@ -710,17 +666,15 @@ public class TargetTable extends AbstractTable { if (distPinned.equals(installedDistributionSetId)) { return SPUIDefinitions.HIGHLIGHT_GREEN; } - if (distPinned.equals(assignedDistributionSetId)) { return SPUIDefinitions.HIGHLIGHT_ORANGE; } - return null; }).orElse(null); } private String createTargetTableStyle(final Object itemId, final Object propertyId) { - if (null == propertyId) { + if (propertyId == null) { final Item item = getItem(itemId); final Long assignedDistributionSetId = (Long) item .getItemProperty(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_ID).getValue(); @@ -767,13 +721,13 @@ public class TargetTable extends AbstractTable { if (size != 0) { setData(SPUIDefinitions.DATA_AVAILABLE); } - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.REFRESH_TARGETS)); + getEventBus().publish(this, new TargetTableEvent(TargetComponentEvent.REFRESH_TARGETS)); } @Override public void refreshContainer() { super.refreshContainer(); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.REFRESH_TARGETS)); + getEventBus().publish(this, new TargetTableEvent(TargetComponentEvent.REFRESH_TARGETS)); } @SuppressWarnings("unchecked") @@ -786,7 +740,7 @@ public class TargetTable extends AbstractTable { item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(target.getUpdateStatus()); item.getItemProperty(SPUILabelDefinitions.VAR_NAME).setValue(target.getName()); item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP) - .setValue(HawkbitCommonUtil.getPollStatusToolTip(target.getPollStatus(), i18n)); + .setValue(HawkbitCommonUtil.getPollStatusToolTip(target.getPollStatus(), getI18n())); } private boolean isLastSelectedTarget(final Long targetId) { @@ -813,7 +767,7 @@ public class TargetTable extends AbstractTable { @Override protected void setDataAvailable(final boolean available) { - managementUIState.setNoDataAvilableTarget(!available); + managementUIState.setNoDataAvailableTarget(!available); } /** @@ -897,4 +851,251 @@ public class TargetTable extends AbstractTable { private boolean isFilteredByTags() { return !managementUIState.getTargetTableFilters().getClickedTargetTags().isEmpty(); } + + // Code for assignment start + private void saveAllAssignments() { + final Set itemIds = managementUIState.getAssignedList().keySet(); + Long distId; + List targetIdSetList; + List tempIdList; + final ActionType actionType = ((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout + .getActionTypeOptionGroup().getValue()).getActionType(); + final long forcedTimeStamp = (((ActionTypeOptionGroupLayout.ActionTypeOption) actionTypeOptionGroupLayout + .getActionTypeOptionGroup().getValue()) == ActionTypeOption.AUTO_FORCED) + ? actionTypeOptionGroupLayout.getForcedTimeDateField().getValue().getTime() + : RepositoryModelConstants.NO_FORCE_TIME; + + final Map> saveAssignedList = Maps.newHashMapWithExpectedSize(itemIds.size()); + + for (final TargetIdName itemId : itemIds) { + final DistributionSetIdName distitem = managementUIState.getAssignedList().get(itemId); + distId = distitem.getId(); + + if (saveAssignedList.containsKey(distId)) { + targetIdSetList = saveAssignedList.get(distId); + } else { + targetIdSetList = new ArrayList<>(); + } + targetIdSetList.add(itemId); + saveAssignedList.put(distId, targetIdSetList); + } + + final String maintenanceSchedule = maintenanceWindowLayout.getMaintenanceSchedule(); + final String maintenanceDuration = maintenanceWindowLayout.getMaintenanceDuration(); + final String maintenanceTimeZone = maintenanceWindowLayout.getMaintenanceTimeZone(); + + for (final Map.Entry> mapEntry : saveAssignedList.entrySet()) { + tempIdList = saveAssignedList.get(mapEntry.getKey()); + final DistributionSetAssignmentResult distributionSetAssignmentResult = deploymentManagement + .assignDistributionSet(mapEntry.getKey(), + tempIdList.stream().map(t -> maintenanceWindowLayout.isEnabled() + ? new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp, + maintenanceSchedule, maintenanceDuration, maintenanceTimeZone) + : new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp)) + .collect(Collectors.toList())); + + if (distributionSetAssignmentResult.getAssigned() > 0) { + getNotification().displaySuccess(getI18n().getMessage("message.target.assignment", + distributionSetAssignmentResult.getAssigned())); + } + if (distributionSetAssignmentResult.getAlreadyAssigned() > 0) { + getNotification().displaySuccess(getI18n().getMessage("message.target.alreadyAssigned", + distributionSetAssignmentResult.getAlreadyAssigned())); + } + } + resfreshPinnedDetails(saveAssignedList); + + managementUIState.getAssignedList().clear(); + getNotification().displaySuccess(getI18n().getMessage("message.target.ds.assign.success")); + getEventBus().publish(this, SaveActionWindowEvent.SAVED_ASSIGNMENTS); + } + + private void resfreshPinnedDetails(final Map> saveAssignedList) { + final Optional pinnedDist = managementUIState.getTargetTableFilters().getPinnedDistId(); + final Optional pinnedTarget = managementUIState.getDistributionTableFilters().getPinnedTarget(); + + if (pinnedDist.isPresent()) { + if (saveAssignedList.keySet().contains(pinnedDist.get())) { + getEventBus().publish(this, PinUnpinEvent.PIN_DISTRIBUTION); + } + } else if (pinnedTarget.isPresent()) { + final Set assignedTargetIds = managementUIState.getAssignedList().keySet(); + if (assignedTargetIds.contains(pinnedTarget.get())) { + getEventBus().publish(this, PinUnpinEvent.PIN_TARGET); + } + } + } + + private boolean isMaintenanceWindowValid() { + if (maintenanceWindowLayout.isEnabled()) { + try { + MaintenanceScheduleHelper.validateMaintenanceSchedule(maintenanceWindowLayout.getMaintenanceSchedule(), + maintenanceWindowLayout.getMaintenanceDuration(), + maintenanceWindowLayout.getMaintenanceTimeZone()); + } catch (final InvalidMaintenanceScheduleException e) { + LOG.error("Maintenance window is not valid", e); + getNotification().displayValidationError(e.getMessage()); + return false; + } + } + return true; + } + + private void assignDsToTarget(final DragAndDropEvent event) { + final TableTransferable transferable = (TableTransferable) event.getTransferable(); + final AbstractTable source = (AbstractTable) transferable.getSourceComponent(); + final Set ids = source.getSelectedEntitiesByTransferable(transferable); + // only one distribution can be assigned to a target + final Long idToSelect = ids.iterator().next(); + selectDraggedEntities(source, new HashSet<>(Arrays.asList(idToSelect))); + final AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails) event.getTargetDetails(); + final Object targetItemId = dropData.getItemIdOver(); + LOG.debug("Adding a log to check if targetItemId is null : {} ", targetItemId); + if (targetItemId == null) { + getNotification().displayWarning(getI18n().getMessage(TARGETS_NOT_EXISTS, "")); + return; + } + + final Long targetId = (Long) targetItemId; + selectDroppedEntities(targetId); + final Optional target = targetManagement.get(targetId); + if (!target.isPresent()) { + getNotification().displayWarning(getI18n().getMessage(TARGETS_NOT_EXISTS, "")); + return; + } + + final TargetIdName createTargetIdName = new TargetIdName(target.get()); + final List findDistributionSetById = distributionSetManagement + .get(new HashSet<>(Arrays.asList(idToSelect))); + + if (findDistributionSetById.isEmpty()) { + getNotification().displayWarning(getI18n().getMessage(DISTRIBUTIONSET_NOT_EXISTS)); + return; + } + final DistributionSet distributionSetToAssign = findDistributionSetById.get(0); + addNewTargetToAssignmentList(createTargetIdName, distributionSetToAssign); + openConfirmationWindowForAssignment(distributionSetToAssign.getName(), createTargetIdName.getTargetName()); + } + + private void openConfirmationWindowForAssignment(final String distributionNameToAssign, final String targetName) { + confirmDialog = new ConfirmationDialog(getI18n().getMessage(CAPTION_ENTITY_ASSIGN_ACTION_CONFIRMBOX), + getI18n().getMessage(MESSAGE_CONFIRM_ASSIGN_ENTITY, distributionNameToAssign, "target", targetName), + getI18n().getMessage(SPUIDefinitions.BUTTON_OK), getI18n().getMessage(SPUIDefinitions.BUTTON_CANCEL), + ok -> { + if (ok && isMaintenanceWindowValid()) { + saveAllAssignments(); + } else { + managementUIState.getAssignedList().clear(); + } + }, createAssignmentTab(), UIComponentIdProvider.DIST_SET_TO_TARGET_ASSIGNMENT_CONFIRM_ID); + UI.getCurrent().addWindow(confirmDialog.getWindow()); + confirmDialog.getWindow().bringToFront(); + } + + private ConfirmationTab createAssignmentTab() { + final ConfirmationTab assignmentTab = new ConfirmationTab(); + actionTypeOptionGroupLayout.selectDefaultOption(); + assignmentTab.addComponent(actionTypeOptionGroupLayout); + assignmentTab.addComponent(enableMaintenanceWindowLayout()); + initMaintenanceWindow(); + assignmentTab.addComponent(maintenanceWindowLayout); + return assignmentTab; + } + + private HorizontalLayout enableMaintenanceWindowLayout() { + final HorizontalLayout layout = new HorizontalLayout(); + layout.addComponent(enableMaintenanceWindowControl()); + layout.addComponent(maintenanceWindowHelpLinkControl()); + return layout; + } + + private CheckBox enableMaintenanceWindowControl() { + final CheckBox enableMaintenanceWindow = new CheckBox( + getI18n().getMessage("caption.maintenancewindow.enabled")); + enableMaintenanceWindow.setId(UIComponentIdProvider.MAINTENANCE_WINDOW_ENABLED_ID); + enableMaintenanceWindow.addStyleName(ValoTheme.CHECKBOX_SMALL); + enableMaintenanceWindow.addStyleName("dist-window-maintenance-window-enable"); + enableMaintenanceWindow.addValueChangeListener(event -> { + final Boolean isMaintenanceWindowEnabled = enableMaintenanceWindow.getValue(); + maintenanceWindowLayout.setVisible(isMaintenanceWindowEnabled); + maintenanceWindowLayout.setEnabled(isMaintenanceWindowEnabled); + enableSaveButton(!isMaintenanceWindowEnabled); + maintenanceWindowLayout.clearAllControls(); + }); + return enableMaintenanceWindow; + } + + private Link maintenanceWindowHelpLinkControl() { + final String maintenanceWindowHelpUrl = uiProperties.getLinks().getDocumentation().getMaintenanceWindowView(); + return SPUIComponentProvider.getHelpLink(maintenanceWindowHelpUrl); + } + + private void initMaintenanceWindow() { + maintenanceWindowLayout.setVisible(false); + maintenanceWindowLayout.setEnabled(false); + maintenanceWindowLayout.getScheduleControl() + .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onScheduleChange(event))); + maintenanceWindowLayout.getDurationControl() + .addTextChangeListener(event -> enableSaveButton(maintenanceWindowLayout.onDurationChange(event))); + } + + private void enableSaveButton(final boolean enabled) { + confirmDialog.getOkButton().setEnabled(enabled); + } + + private void addNewTargetToAssignmentList(final TargetIdName createTargetIdName, + final DistributionSet findDistributionSetAllById) { + final DistributionSetIdName distributionNameId = new DistributionSetIdName(findDistributionSetAllById); + managementUIState.getAssignedList().put(createTargetIdName, distributionNameId); + } + + @Override + protected void handleOkDelete(final List entitiesToDelete) { + targetManagement.delete(entitiesToDelete); + getEventBus().publish(this, new TargetTableEvent(BaseEntityEventType.REMOVE_ENTITY, entitiesToDelete)); + getNotification().displaySuccess(getI18n().getMessage("message.delete.success", + entitiesToDelete.size() + " " + getI18n().getMessage("caption.target") + "(s)")); + managementUIState.getDistributionTableFilters().getPinnedTarget().ifPresent(this::unPinDeletedTarget); + managementUIState.getSelectedTargetId().clear(); + } + + private void unPinDeletedTarget(final TargetIdName pinnedTarget) { + final Set deletedTargetIds = managementUIState.getSelectedTargetId(); + if (deletedTargetIds.contains(pinnedTarget.getTargetId())) { + managementUIState.getDistributionTableFilters().setPinnedTarget(null); + getEventBus().publish(this, PinUnpinEvent.UNPIN_TARGET); + } + } + + @Override + protected String getEntityId(final Object itemId) { + final String targetId = String.valueOf( + getContainerDataSource().getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_ID).getValue()); + return "target." + targetId; + } + + @Override + protected Set getSelectedEntities() { + return managementUIState.getSelectedTargetId(); + } + + @Override + protected String getEntityType() { + return getI18n().getMessage("caption.target"); + } + + @Override + protected boolean hasDeletePermission() { + return getPermChecker().hasDeleteRepositoryPermission() || getPermChecker().hasDeleteTargetPermission(); + } + + @Override + protected String getDeletedEntityName(final Long entityId) { + final Optional target = targetManagement.get(entityId); + if (target.isPresent()) { + return target.get().getName(); + } + return ""; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index 4e00d6564..9c5aa305a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -26,7 +26,7 @@ import org.eclipse.hawkbit.ui.common.table.AbstractTableHeader; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.management.event.BulkUploadPopupEvent; import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; @@ -77,20 +77,20 @@ public class TargetTableHeader extends AbstractTableHeader { private final transient DistributionSetManagement distributionSetManagement; - TargetTableHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventbus, + TargetTableHeader(final VaadinMessageSource i18n, final SpPermissionChecker permChecker, final UIEventBus eventBus, final UINotification notification, final ManagementUIState managementUIState, final ManagementViewClientCriterion managementViewClientCriterion, final TargetManagement targetManagement, - final DeploymentManagement deploymentManagement, final UiProperties uiproperties, final UIEventBus eventBus, - final EntityFactory entityFactory, final UINotification uinotification, final TargetTagManagement tagManagement, - final DistributionSetManagement distributionSetManagement, final Executor uiExecutor, - final TargetTable targetTable) { - super(i18n, permChecker, eventbus, managementUIState, null, null); + final DeploymentManagement deploymentManagement, final UiProperties uiproperties, + final EntityFactory entityFactory, final UINotification uiNotification, + final TargetTagManagement tagManagement, final DistributionSetManagement distributionSetManagement, + final Executor uiExecutor, final TargetTable targetTable) { + super(i18n, permChecker, eventBus, managementUIState, null, null); this.notification = notification; this.managementViewClientCriterion = managementViewClientCriterion; - this.targetAddUpdateWindow = new TargetAddUpdateWindowLayout(i18n, targetManagement, eventBus, uinotification, + this.targetAddUpdateWindow = new TargetAddUpdateWindowLayout(i18n, targetManagement, eventBus, uiNotification, entityFactory, targetTable); this.targetBulkUpdateWindow = new TargetBulkUpdateWindowLayout(i18n, targetManagement, eventBus, - managementUIState, deploymentManagement, uiproperties, permChecker, uinotification, tagManagement, + managementUIState, deploymentManagement, uiproperties, permChecker, uiNotification, tagManagement, distributionSetManagement, entityFactory, uiExecutor); this.distributionSetManagement = distributionSetManagement; onLoadRestoreState(); @@ -280,7 +280,7 @@ public class TargetTableHeader extends AbstractTableHeader { protected void addNewItem(final ClickEvent event) { targetAddUpdateWindow.resetComponents(); final Window addTargetWindow = targetAddUpdateWindow.createNewWindow(); - addTargetWindow.setCaption(i18n.getMessage(UIComponentIdProvider.TARGET_ADD_CAPTION)); + addTargetWindow.setCaption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.target"))); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); } @@ -335,8 +335,7 @@ public class TargetTableHeader extends AbstractTableHeader { return; } final Long distributionSetId = distributionIdSet.iterator().next(); - final Optional distributionSet = distributionSetManagement - .get(distributionSetId); + final Optional distributionSet = distributionSetManagement.get(distributionSetId); if (!distributionSet.isPresent()) { notification.displayWarning(i18n.getMessage("distributionset.not.exists")); return; @@ -378,12 +377,12 @@ public class TargetTableHeader extends AbstractTableHeader { private static Set getDropppedDistributionDetails(final TableTransferable transferable) { final AbstractTable distTable = (AbstractTable) transferable.getSourceComponent(); - return distTable.getDeletedEntityByTransferable(transferable); + return distTable.getSelectedEntitiesByTransferable(transferable); } private void addFilterTextField(final DistributionSetIdName distributionSetIdName) { final Button filterLabelClose = SPUIComponentProvider.getButton("drop.filter.close", "", "", "", true, - FontAwesome.TIMES_CIRCLE, SPUIButtonStyleSmallNoBorder.class); + FontAwesome.TIMES_CIRCLE, SPUIButtonStyleNoBorder.class); filterLabelClose.addClickListener(clickEvent -> closeFilterByDistribution()); final Label filteredDistLabel = new Label(); filteredDistLabel.setStyleName(ValoTheme.LABEL_COLORED + " " + ValoTheme.LABEL_SMALL); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java index a97d60a26..3e934f51c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java @@ -42,19 +42,17 @@ public class TargetTableLayout extends AbstractTableLayout { public TargetTableLayout(final UIEventBus eventBus, final TargetTable targetTable, final TargetManagement targetManagement, final EntityFactory entityFactory, final VaadinMessageSource i18n, - final UIEventBus eventbus, final UINotification notification, final ManagementUIState managementUIState, + final UINotification uiNotification, final ManagementUIState managementUIState, final ManagementViewClientCriterion managementViewClientCriterion, - final DeploymentManagement deploymentManagement, final UiProperties uiproperties, - final SpPermissionChecker permissionChecker, final UINotification uinotification, - final TargetTagManagement tagManagement, final DistributionSetManagement distributionSetManagement, - final Executor uiExecutor) { + final DeploymentManagement deploymentManagement, final UiProperties uiProperties, + final SpPermissionChecker permissionChecker, final TargetTagManagement tagManagement, + final DistributionSetManagement distributionSetManagement, final Executor uiExecutor) { this.eventBus = eventBus; - this.targetDetails = new TargetDetails(i18n, eventbus, permissionChecker, managementUIState, uinotification, + this.targetDetails = new TargetDetails(i18n, eventBus, permissionChecker, managementUIState, uiNotification, tagManagement, targetManagement, deploymentManagement, entityFactory, targetTable); - this.targetTableHeader = new TargetTableHeader(i18n, permissionChecker, eventBus, notification, - managementUIState, managementViewClientCriterion, targetManagement, deploymentManagement, uiproperties, - eventbus, entityFactory, uinotification, tagManagement, distributionSetManagement, uiExecutor, - targetTable); + this.targetTableHeader = new TargetTableHeader(i18n, permissionChecker, eventBus, uiNotification, + managementUIState, managementViewClientCriterion, targetManagement, deploymentManagement, uiProperties, + entityFactory, uiNotification, tagManagement, distributionSetManagement, uiExecutor, targetTable); super.init(targetTableHeader, targetTable, targetDetails); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagLayout.java new file mode 100644 index 000000000..4602ed59a --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagLayout.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.targettag; + +import java.util.Optional; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.TargetTagManagement; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.layouts.AbstractTagLayout; +import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Abstract class for tag layout of Targets. + * + */ +public abstract class AbstractTargetTagLayout extends AbstractTagLayout { + + private static final long serialVersionUID = 1L; + + private final transient TargetTagManagement targetTagManagement; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param targetTagManagement + * TargetTagManagement + */ + public AbstractTargetTagLayout(final VaadinMessageSource i18n, final EntityFactory entityFactory, + final UIEventBus eventBus, final SpPermissionChecker permChecker, final UINotification uiNotification, + final TargetTagManagement targetTagManagement) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification); + this.targetTagManagement = targetTagManagement; + } + + @Override + protected Optional findEntityByName() { + return targetTagManagement.getByName(getTagName().getValue()); + } + + public TargetTagManagement getTargetTagManagement() { + return targetTagManagement; + } + + @Override + protected int getTagNameSize() { + return TargetTag.NAME_MAX_SIZE; + } + + @Override + protected int getTagDescSize() { + return TargetTag.DESCRIPTION_MAX_SIZE; + } + + @Override + protected String getTagNameId() { + return UIComponentIdProvider.NEW_TARGET_TAG_NAME; + } + + @Override + protected String getTagDescId() { + return UIComponentIdProvider.NEW_TARGET_TAG_DESC; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateTargetTagLayout.java new file mode 100644 index 000000000..3c99692b5 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateTargetTagLayout.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.targettag; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.TargetTagManagement; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.springframework.util.StringUtils; +import org.vaadin.spring.events.EventBus.UIEventBus; + +/** + * Layout for pop-up window which is created when creating a target tag on the + * Deployment View. + */ +public class CreateTargetTagLayout extends AbstractTargetTagLayout { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for CreateUpdateTargetTagLayoutWindow + * + * @param i18n + * I18N + * @param targetTagManagement + * TargetTagManagement + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + */ + public CreateTargetTagLayout(final VaadinMessageSource i18n, final TargetTagManagement targetTagManagement, + final EntityFactory entityFactory, final UIEventBus eventBus, final SpPermissionChecker permChecker, + final UINotification uiNotification) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, targetTagManagement); + } + + private void createNewTag() { + if (!StringUtils.isEmpty(getTagName().getValue())) { + setColorPicked(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); + String colour = ColorPickerConstants.START_COLOR.getCSS(); + if (!StringUtils.isEmpty(getColorPicked())) { + colour = getColorPicked(); + } + + final TargetTag newTargetTag = getTargetTagManagement().create(getEntityFactory().tag().create() + .name(getTagName().getValue()).description(getTagDesc().getValue()).colour(colour)); + getEventBus().publish(this, new TargetTagTableEvent(BaseEntityEventType.ADD_ENTITY, newTargetTag)); + displaySuccess(newTargetTag.getName()); + } else { + displayValidationError(getI18n().getMessage(getMessageErrorMissingTagname())); + } + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.create.new", getI18n().getMessage("caption.tag")); + } + + @Override + protected void saveEntity() { + createNewTag(); + } + + @Override + protected boolean isUpdateAction() { + return false; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java deleted file mode 100644 index 04d8c6002..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.management.targettag; - -import java.util.Objects; -import java.util.Optional; - -import org.eclipse.hawkbit.repository.EntityFactory; -import org.eclipse.hawkbit.repository.TargetTagManagement; -import org.eclipse.hawkbit.repository.builder.TagUpdate; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.components.RefreshableContainer; -import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; -import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent; -import org.eclipse.hawkbit.ui.utils.UINotification; -import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; -import org.springframework.data.domain.PageRequest; -import org.springframework.util.StringUtils; -import org.vaadin.spring.events.EventBus.UIEventBus; - -import com.vaadin.shared.ui.colorpicker.Color; - -/** - * Class for Create / Update Tag Layout of target - */ -public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLayout - implements RefreshableContainer { - - private static final long serialVersionUID = 1L; - - private final transient TargetTagManagement targetTagManagement; - - /** - * Constructor for CreateUpdateTargetTagLayoutWindow - * - * @param i18n - * I18N - * @param targetTagManagement - * TargetTagManagement - * @param entityFactory - * EntityFactory - * @param eventBus - * UIEventBus - * @param permChecker - * SpPermissionChecker - * @param uiNotification - * UINotification - */ - public CreateUpdateTargetTagLayoutWindow(final VaadinMessageSource i18n, - final TargetTagManagement targetTagManagement, final EntityFactory entityFactory, final UIEventBus eventBus, - final SpPermissionChecker permChecker, final UINotification uiNotification) { - super(i18n, entityFactory, eventBus, permChecker, uiNotification); - this.targetTagManagement = targetTagManagement; - } - - @Override - protected boolean doSubscribeToEventBus() { - return false; - } - - @Override - protected void addListeners() { - super.addListeners(); - optiongroup.addValueChangeListener(this::optionValueChanged); - } - - /** - * Populate target name combo. - */ - @Override - public void populateTagNameCombo() { - tagNameComboBox.removeAllItems(); - targetTagManagement.findAll(new PageRequest(0, MAX_TAGS)) - .forEach(value -> tagNameComboBox.addItem(value.getName())); - } - - /** - * @return the color which should be selected in the color-picker component. - */ - @Override - protected Color getColorForColorPicker() { - return ColorPickerHelper - .rgbToColorConverter(targetTagManagement.getByName(tagNameComboBox.getValue().toString()) - .map(TargetTag::getColour).filter(Objects::nonNull).orElse(ColorPickerConstants.DEFAULT_COLOR)); - } - - /** - * Select tag & set tag name & tag desc values corresponding to selected - * tag. - * - * @param targetTagSelected - * as the selected tag from combo - */ - @Override - public void setTagDetails(final String targetTagSelected) { - tagName.setValue(targetTagSelected); - final Optional selectedTargetTag = targetTagManagement.getByName(targetTagSelected); - if (selectedTargetTag.isPresent()) { - tagDesc.setValue(selectedTargetTag.get().getDescription()); - if (null == selectedTargetTag.get().getColour()) { - setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); - } else { - setTagColor(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.get().getColour()), - selectedTargetTag.get().getColour()); - } - } - } - - @Override - protected void updateEntity(final TargetTag entity) { - updateExistingTag(entity); - } - - @Override - protected void createEntity() { - createNewTag(); - } - - @Override - protected Optional findEntityByName() { - return targetTagManagement.getByName(tagName.getValue()); - } - - /** - * Create new tag. - */ - @Override - protected void createNewTag() { - super.createNewTag(); - if (!StringUtils.isEmpty(tagNameValue)) { - String colour = ColorPickerConstants.START_COLOR.getCSS(); - if (!StringUtils.isEmpty(getColorPicked())) { - colour = getColorPicked(); - } - - final TargetTag newTargetTag = targetTagManagement - .create(entityFactory.tag().create().name(tagNameValue).description(tagDescValue).colour(colour)); - eventBus.publish(this, new TargetTagTableEvent(BaseEntityEventType.ADD_ENTITY, newTargetTag)); - displaySuccess(newTargetTag.getName()); - } else { - displayValidationError(i18n.getMessage(MESSAGE_ERROR_MISSING_TAGNAME)); - } - } - - /** - * update tag. - */ - protected void updateExistingTag(final Tag targetObj) { - final TagUpdate update = entityFactory.tag().update(targetObj.getId()).name(tagName.getValue()) - .description(tagDesc.getValue()) - .colour(ColorPickerHelper.getColorPickedString(colorPickerLayout.getSelPreview())); - - targetTagManagement.update(update); - eventBus.publish(this, new TargetTagTableEvent(BaseEntityEventType.UPDATED_ENTITY, (TargetTag) targetObj)); - - uiNotification.displaySuccess(i18n.getMessage("message.update.success", new Object[] { targetObj.getName() })); - - } - - @Override - protected void createRequiredComponents() { - super.createRequiredComponents(); - createOptionGroup(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission()); - } - - @Override - protected void reset() { - - super.reset(); - setOptionGroupDefaultValue(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission()); - } - - @Override - protected String getWindowCaption() { - return i18n.getMessage("caption.add.tag"); - } - - @Override - public void refreshContainer() { - populateTagNameCombo(); - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/UpdateTargetTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/UpdateTargetTagLayout.java new file mode 100644 index 000000000..811f147bf --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/UpdateTargetTagLayout.java @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.management.targettag; + +import java.util.Optional; + +import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.TargetTagManagement; +import org.eclipse.hawkbit.repository.builder.TagUpdate; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; +import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.layouts.UpdateTag; +import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent; +import org.eclipse.hawkbit.ui.utils.UINotification; +import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; +import org.vaadin.spring.events.EventBus.UIEventBus; + +import com.vaadin.ui.Window.CloseListener; + +/** + * Layout for pop-up window which is created when updating a target tag on the + * Deployment View. + * + */ +public class UpdateTargetTagLayout extends AbstractTargetTagLayout implements UpdateTag { + + private static final long serialVersionUID = 1L; + + private final String selectedTagName; + + private final CloseListener closeListener; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param targetTagManagement + * TargetTagManagement + * @param entityFactory + * EntityFactory + * @param eventBus + * UIEventBus + * @param permChecker + * SpPermissionChecker + * @param uiNotification + * UINotification + * @param selectedTagName + * name of the selected target tag to update + * @param closeListener + * CloseListener + */ + public UpdateTargetTagLayout(final VaadinMessageSource i18n, final TargetTagManagement targetTagManagement, + final EntityFactory entityFactory, final UIEventBus eventBus, final SpPermissionChecker permChecker, + final UINotification uiNotification, final String selectedTagName, final CloseListener closeListener) { + super(i18n, entityFactory, eventBus, permChecker, uiNotification, targetTagManagement); + this.selectedTagName = selectedTagName; + this.closeListener = closeListener; + initUpdatePopup(); + } + + private void initUpdatePopup() { + setTagDetails(selectedTagName); + getWindow().addCloseListener(closeListener); + } + + @Override + protected String getWindowCaption() { + return getI18n().getMessage("caption.update", getI18n().getMessage("caption.tag")); + } + + @Override + protected void saveEntity() { + updateExistingTag(findEntityByName() + .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, getTagName().getValue()))); + } + + private void updateExistingTag(final Tag targetObj) { + final TagUpdate update = getEntityFactory().tag().update(targetObj.getId()).name(getTagName().getValue()) + .description(getTagDesc().getValue()) + .colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); + + getTargetTagManagement().update(update); + getEventBus().publish(this, new TargetTagTableEvent(BaseEntityEventType.UPDATED_ENTITY, (TargetTag) targetObj)); + getUiNotification().displaySuccess(getI18n().getMessage("message.update.success", targetObj.getName())); + } + + @Override + public void setTagDetails(final String selectedEntity) { + final Optional selectedTargetTag = getTargetTagManagement().getByName(selectedEntity); + selectedTargetTag.ifPresent(tag -> { + getTagName().setValue(tag.getName()); + getTagName().setEnabled(false); + getTagDesc().setValue(tag.getDescription()); + if (tag.getColour() == null) { + setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + } else { + setTagColor(ColorPickerHelper.rgbToColorConverter(tag.getColour()), tag.getColour()); + } + getWindow().setOrginaleValues(); + }); + } + + @Override + protected boolean isUpdateAction() { + return true; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/AbstractTargetTagFilterLayout.java similarity index 94% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagFilterLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/AbstractTargetTagFilterLayout.java index d88381e09..3a2b1fef0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/AbstractTargetTagFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/AbstractTargetTagFilterLayout.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; @@ -21,7 +21,7 @@ import com.vaadin.ui.VerticalLayout; */ public abstract class AbstractTargetTagFilterLayout extends VerticalLayout { - private static final long serialVersionUID = 9190616426688385851L; + private static final long serialVersionUID = 1L; private final AbstractFilterHeader filterHeader; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CustomTargetTagFilterButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/CustomTargetTagFilterButtonClick.java similarity index 80% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CustomTargetTagFilterButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/CustomTargetTagFilterButtonClick.java index ca0da4ef3..0fe362bc8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CustomTargetTagFilterButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/CustomTargetTagFilterButtonClick.java @@ -6,9 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; - -import java.io.Serializable; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterSingleButtonClick; @@ -25,9 +23,9 @@ import com.vaadin.ui.Button.ClickEvent; * Single button click behaviour of custom target filter buttons layout. * */ -public class CustomTargetTagFilterButtonClick extends AbstractFilterSingleButtonClick implements Serializable { +public class CustomTargetTagFilterButtonClick extends AbstractFilterSingleButtonClick { - private static final long serialVersionUID = -6173433602055291533L; + private static final long serialVersionUID = 1L; private final transient EventBus.UIEventBus eventBus; @@ -35,6 +33,16 @@ public class CustomTargetTagFilterButtonClick extends AbstractFilterSingleButton private final transient TargetFilterQueryManagement targetFilterQueryManagement; + /** + * Constructor + * + * @param eventBus + * UIEventBus + * @param managementUIState + * ManagementUIState + * @param targetFilterQueryManagement + * TargetFilterQueryManagement + */ public CustomTargetTagFilterButtonClick(final UIEventBus eventBus, final ManagementUIState managementUIState, final TargetFilterQueryManagement targetFilterQueryManagement) { this.eventBus = eventBus; @@ -50,11 +58,10 @@ public class CustomTargetTagFilterButtonClick extends AbstractFilterSingleButton @Override protected void filterClicked(final Button clickedButton) { - targetFilterQueryManagement.get((Long) clickedButton.getData()) - .ifPresent(targetFilterQuery -> { - this.managementUIState.getTargetTableFilters().setTargetFilterQuery(targetFilterQuery.getId()); - this.eventBus.publish(this, TargetFilterEvent.FILTER_BY_TARGET_FILTER_QUERY); - }); + targetFilterQueryManagement.get((Long) clickedButton.getData()).ifPresent(targetFilterQuery -> { + this.managementUIState.getTargetTableFilters().setTargetFilterQuery(targetFilterQuery.getId()); + this.eventBus.publish(this, TargetFilterEvent.FILTER_BY_TARGET_FILTER_QUERY); + }); } protected void processButtonClick(final ClickEvent event) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/FilterByStatusLayout.java similarity index 99% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/FilterByStatusLayout.java index a4d04f25e..13da6a0ee 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/FilterByStatusLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/FilterByStatusLayout.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/MultipleTargetFilter.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/MultipleTargetFilter.java similarity index 50% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/MultipleTargetFilter.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/MultipleTargetFilter.java index f86f197a9..5b1167704 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/MultipleTargetFilter.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/MultipleTargetFilter.java @@ -6,32 +6,39 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; +import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.TargetTagFilterHeaderEvent; +import org.eclipse.hawkbit.ui.components.ConfigMenuBar; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; +import org.eclipse.hawkbit.ui.management.targettag.CreateTargetTagLayout; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus.UIEventBus; +import org.vaadin.spring.events.EventScope; +import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Accordion; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; +import com.vaadin.ui.MenuBar.Command; import com.vaadin.ui.TabSheet.SelectedTabChangeListener; -import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** @@ -39,58 +46,69 @@ import com.vaadin.ui.themes.ValoTheme; */ public class MultipleTargetFilter extends Accordion implements SelectedTabChangeListener { - private static final long serialVersionUID = -2887693289126893943L; + private static final long serialVersionUID = 1L; private final TargetTagFilterButtons filterByButtons; + private final TargetFilterQueryButtons targetFilterQueryButtonsTab; - private final FilterByStatusLayout filterByStatusFotter; + + private final FilterByStatusLayout filterByStatusFooter; + private final CustomTargetTagFilterButtonClick customTargetTagFilterButtonClick; - private final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout; + private final SpPermissionChecker permChecker; + private final ManagementUIState managementUIState; + private final VaadinMessageSource i18n; + private final transient EventBus.UIEventBus eventBus; private VerticalLayout simpleFilterTab; - private Button config; + private ConfigMenuBar menu; - MultipleTargetFilter(final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout, - final SpPermissionChecker permChecker, final ManagementUIState managementUIState, final VaadinMessageSource i18n, - final UIEventBus eventBus, final ManagementViewClientCriterion managementViewClientCriterion, - final UINotification notification, final EntityFactory entityFactory, - final TargetFilterQueryManagement targetFilterQueryManagement) { + private final UINotification uiNotification; + + private final transient EntityFactory entityFactory; + + private final transient TargetTagManagement targetTagManagement; + + private VerticalLayout targetTagTableLayout; + + private Button cancelTagButton; + + MultipleTargetFilter(final SpPermissionChecker permChecker, final ManagementUIState managementUIState, + final VaadinMessageSource i18n, final UIEventBus eventBus, + final ManagementViewClientCriterion managementViewClientCriterion, final UINotification notification, + final EntityFactory entityFactory, final TargetFilterQueryManagement targetFilterQueryManagement, + final TargetTagManagement targetTagManagement) { this.filterByButtons = new TargetTagFilterButtons(eventBus, managementUIState, managementViewClientCriterion, - i18n, notification, permChecker, entityFactory); + i18n, notification, permChecker, entityFactory, targetTagManagement); this.targetFilterQueryButtonsTab = new TargetFilterQueryButtons(managementUIState, eventBus); - this.filterByStatusFotter = new FilterByStatusLayout(i18n, eventBus, managementUIState); + this.filterByStatusFooter = new FilterByStatusLayout(i18n, eventBus, managementUIState); this.customTargetTagFilterButtonClick = new CustomTargetTagFilterButtonClick(eventBus, managementUIState, targetFilterQueryManagement); - this.createUpdateTargetTagLayout = createUpdateTargetTagLayout; this.permChecker = permChecker; this.managementUIState = managementUIState; this.i18n = i18n; this.eventBus = eventBus; + this.uiNotification = notification; + this.entityFactory = entityFactory; + this.targetTagManagement = targetTagManagement; buildComponents(); + eventBus.subscribe(this); } - public TargetTagFilterButtons getFilterByButtons() { - return filterByButtons; - } - - /** - * Intialize component. - */ private void buildComponents() { - filterByStatusFotter.init(); + filterByStatusFooter.init(); filterByButtons.addStyleName(SPUIStyleDefinitions.NO_TOP_BORDER); targetFilterQueryButtonsTab.init(customTargetTagFilterButtonClick); - if (permChecker.hasCreateTargetPermission() || permChecker.hasUpdateTargetPermission()) { - config = SPUIComponentProvider.getButton(UIComponentIdProvider.ADD_TARGET_TAG, "", "", "", true, - FontAwesome.COG, SPUIButtonStyleSmallNoBorder.class); - config.addClickListener(event -> settingsIconClicked()); - } + menu = new ConfigMenuBar(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission(), + permChecker.hasDeleteRepositoryPermission(), getAddButtonCommand(), getUpdateButtonCommand(), + getDeleteButtonCommand(), UIComponentIdProvider.TARGET_MENU_BAR_ID); + menu.addStyleName("targetTag"); addStyleName(ValoTheme.ACCORDION_BORDERLESS); addTabs(); setSizeFull(); @@ -98,9 +116,6 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange addSelectedTabChangeListener(this); } - /** - * - */ private void switchToTabSelectedOnLoad() { if (managementUIState.isCustomFilterSelected()) { this.setSelectedTab(targetFilterQueryButtonsTab); @@ -109,9 +124,6 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange } } - /** - * Add tabs. - */ private void addTabs() { this.addTab(getSimpleFilterTab()).setId(UIComponentIdProvider.SIMPLE_FILTER_ACCORDION_TAB); this.addTab(getComplexFilterTab()).setId(UIComponentIdProvider.CUSTOM_FILTER_ACCORDION_TAB); @@ -119,11 +131,11 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange private Component getSimpleFilterTab() { simpleFilterTab = new VerticalLayout(); - final VerticalLayout targetTagTableLayout = new VerticalLayout(); + targetTagTableLayout = new VerticalLayout(); targetTagTableLayout.setSizeFull(); - if (null != config) { - targetTagTableLayout.addComponent(config); - targetTagTableLayout.setComponentAlignment(config, Alignment.TOP_RIGHT); + if (menu != null) { + targetTagTableLayout.addComponent(menu); + targetTagTableLayout.setComponentAlignment(menu, Alignment.TOP_RIGHT); } targetTagTableLayout.addComponent(filterByButtons); targetTagTableLayout.setComponentAlignment(filterByButtons, Alignment.MIDDLE_CENTER); @@ -132,8 +144,8 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange simpleFilterTab.setCaption(i18n.getMessage("caption.filter.simple")); simpleFilterTab.addComponent(targetTagTableLayout); simpleFilterTab.setExpandRatio(targetTagTableLayout, 1.0F); - simpleFilterTab.addComponent(filterByStatusFotter); - simpleFilterTab.setComponentAlignment(filterByStatusFotter, Alignment.MIDDLE_CENTER); + simpleFilterTab.addComponent(filterByStatusFooter); + simpleFilterTab.setComponentAlignment(filterByStatusFooter, Alignment.MIDDLE_CENTER); simpleFilterTab.setSizeFull(); simpleFilterTab.addStyleName(SPUIStyleDefinitions.SIMPLE_FILTER_HEADER); return simpleFilterTab; @@ -144,13 +156,6 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange return targetFilterQueryButtonsTab; } - /* - * (non-Javadoc) - * - * @see - * com.vaadin.ui.TabSheet.SelectedTabChangeListener#selectedTabChange(com - * .vaadin.ui.TabSheet.SelectedTabChangeEvent) - */ @Override public void selectedTabChange(final SelectedTabChangeEvent event) { if (i18n.getMessage("caption.filter.simple").equals(getSelectedTab().getCaption())) { @@ -162,10 +167,70 @@ public class MultipleTargetFilter extends Accordion implements SelectedTabChange } } - protected void settingsIconClicked() { - final Window addUpdateWindow = createUpdateTargetTagLayout.getWindow(); - UI.getCurrent().addWindow(addUpdateWindow); - addUpdateWindow.setVisible(true); + protected Command getAddButtonCommand() { + return command -> new CreateTargetTagLayout(i18n, targetTagManagement, entityFactory, eventBus, permChecker, + uiNotification); + } + + protected Command getDeleteButtonCommand() { + return command -> { + filterByButtons.addDeleteColumn(); + eventBus.publish(this, new TargetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + protected Command getUpdateButtonCommand() { + return command -> { + filterByButtons.addUpdateColumn(); + eventBus.publish(this, new TargetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_CANCEL_BUTTON)); + }; + } + + protected void processFilterHeaderEvent(final TargetTagFilterHeaderEvent event) { + if (FilterHeaderEnum.SHOW_MENUBAR == event.getFilterHeaderEnum() + && targetTagTableLayout.getComponent(0).equals(cancelTagButton)) { + removeCancelButtonAndAddMenuBar(); + } else if (FilterHeaderEnum.SHOW_CANCEL_BUTTON == event.getFilterHeaderEnum()) { + removeMenuBarAndAddCancelButton(); + } + } + + protected void removeMenuBarAndAddCancelButton() { + targetTagTableLayout.removeComponent(menu); + targetTagTableLayout.addComponent(createCancelButtonForUpdateOrDeleteTag(), 0); + targetTagTableLayout.setComponentAlignment(cancelTagButton, Alignment.TOP_RIGHT); + } + + protected Button createCancelButtonForUpdateOrDeleteTag() { + cancelTagButton = SPUIComponentProvider.getButton(UIComponentIdProvider.CANCEL_UPDATE_TAG_ID, "", "", null, + false, FontAwesome.TIMES_CIRCLE, SPUIButtonStyleNoBorder.class); + cancelTagButton.addClickListener(this::cancelUpdateOrDeleteTag); + return cancelTagButton; + } + + protected void removeCancelButtonAndAddMenuBar() { + targetTagTableLayout.removeComponent(cancelTagButton); + targetTagTableLayout.addComponent(menu, 0); + targetTagTableLayout.setComponentAlignment(menu, Alignment.TOP_RIGHT); + filterByButtons.removeUpdateAndDeleteColumn(); + } + + @SuppressWarnings("squid:S1172") + protected void cancelUpdateOrDeleteTag(final ClickEvent event) { + removeCancelButtonAndAddMenuBar(); + } + + @EventBusListenerMethod(scope = EventScope.UI) + private void onEvent(final TargetTagFilterHeaderEvent event) { + processFilterHeaderEvent(event); + } + + public TargetTagFilterButtons getFilterByButtons() { + return filterByButtons; + } + + public VerticalLayout getTargetTagTableLayout() { + return targetTagTableLayout; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetFilterQueryButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetFilterQueryButtons.java similarity index 98% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetFilterQueryButtons.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetFilterQueryButtons.java index 0e0f5152d..34696860b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetFilterQueryButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetFilterQueryButtons.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import java.util.ArrayList; import java.util.Collections; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagBeanQuery.java similarity index 98% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagBeanQuery.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagBeanQuery.java index 9611ce233..39811d198 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagBeanQuery.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import java.util.ArrayList; import java.util.List; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtonClick.java similarity index 98% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtonClick.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtonClick.java index cd08b1c9f..5816fb70b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtonClick.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import java.io.Serializable; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtons.java similarity index 69% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtons.java index 83a0eaafa..ad59006c1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterButtons.java @@ -6,24 +6,31 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import java.util.List; +import java.util.Optional; import java.util.Set; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.ui.SpPermissionChecker; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.TargetTagFilterHeaderEvent; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons; import org.eclipse.hawkbit.ui.common.table.AbstractTable; -import org.eclipse.hawkbit.ui.components.RefreshableContainer; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; +import org.eclipse.hawkbit.ui.management.event.TargetTagTableEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.tag.TagIdName; import org.eclipse.hawkbit.ui.management.targettable.TargetTable; +import org.eclipse.hawkbit.ui.management.targettag.UpdateTargetTagLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -41,6 +48,7 @@ import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.Table; @@ -49,8 +57,7 @@ import com.vaadin.ui.UI; /** * Target Tag filter buttons table. */ -public class TargetTagFilterButtons extends AbstractFilterButtons implements RefreshableContainer { - private static final String NO_TAG = "NO TAG"; +public class TargetTagFilterButtons extends AbstractFilterButtons { private static final long serialVersionUID = 1L; @@ -58,27 +65,27 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref private final ManagementViewClientCriterion managementViewClientCriterion; - private final VaadinMessageSource i18n; - - private final UINotification notification; + private final UINotification uiNotification; private final SpPermissionChecker permChecker; private final transient EntityFactory entityFactory; + private final transient TargetTagManagement targetTagManagement; + TargetTagFilterButtons(final UIEventBus eventBus, final ManagementUIState managementUIState, final ManagementViewClientCriterion managementViewClientCriterion, final VaadinMessageSource i18n, - final UINotification notification, final SpPermissionChecker permChecker, - final EntityFactory entityFactory) { - super(eventBus, new TargetTagFilterButtonClick(eventBus, managementUIState)); + final UINotification notification, final SpPermissionChecker permChecker, final EntityFactory entityFactory, + final TargetTagManagement targetTagManagement) { + super(eventBus, new TargetTagFilterButtonClick(eventBus, managementUIState), i18n); this.managementUIState = managementUIState; this.managementViewClientCriterion = managementViewClientCriterion; - this.i18n = i18n; - this.notification = notification; + this.uiNotification = notification; this.permChecker = permChecker; this.entityFactory = entityFactory; + this.targetTagManagement = targetTagManagement; - addNewTargetTag(entityFactory.tag().create().name(NO_TAG).build()); + addNewTargetTag(entityFactory.tag().create().name(SPUIDefinitions.NO_TAG).build()); } @Override @@ -105,7 +112,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref @Override protected String createButtonId(final String name) { - if (NO_TAG.equals(name)) { + if (SPUIDefinitions.NO_TAG.equals(name)) { return UIComponentIdProvider.NO_TAG_TARGET; } return name; @@ -138,8 +145,8 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref private Boolean isNoTagAssigned(final DragAndDropEvent event) { final String tagName = ((DragAndDropWrapper) (event.getTargetDetails().getTarget())).getData().toString(); if (tagName.equals(SPUIDefinitions.TARGET_TAG_BUTTON)) { - notification.displayValidationError(i18n.getMessage("message.tag.cannot.be.assigned", - new Object[] { i18n.getMessage("label.no.tag.assigned") })); + uiNotification.displayValidationError(getI18n().getMessage("message.tag.cannot.be.assigned", + getI18n().getMessage("label.no.tag.assigned"))); return false; } return true; @@ -156,7 +163,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref final Transferable transferable = event.getTransferable(); final Component compsource = transferable.getSourceComponent(); if (!(compsource instanceof AbstractTable)) { - notification.displayValidationError(i18n.getMessage(SPUILabelDefinitions.ACTION_NOT_ALLOWED)); + uiNotification.displayValidationError(getI18n().getMessage(SPUILabelDefinitions.ACTION_NOT_ALLOWED)); return false; } @@ -164,14 +171,14 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref final AbstractTable source = (AbstractTable) tabletransferable.getSourceComponent(); - if (!validateIfSourceisTargetTable(source) && !hasTargetUpdatePermission()) { + if (!validateIfSourceIsTargetTable(source) && !hasTargetUpdatePermission()) { return false; } - final Set deletedEntityByTransferable = source.getDeletedEntityByTransferable(tabletransferable); + final Set deletedEntityByTransferable = source.getSelectedEntitiesByTransferable(tabletransferable); if (deletedEntityByTransferable.isEmpty()) { - final String actionDidNotWork = i18n.getMessage("message.action.did.not.work", new Object[] {}); - notification.displayValidationError(actionDidNotWork); + final String actionDidNotWork = getI18n().getMessage("message.action.did.not.work"); + uiNotification.displayValidationError(actionDidNotWork); return false; } @@ -185,8 +192,8 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref */ private boolean hasTargetUpdatePermission() { if (!permChecker.hasUpdateTargetPermission()) { - notification.displayValidationError( - i18n.getMessage("message.permission.insufficient", SpPermission.UPDATE_TARGET)); + uiNotification.displayValidationError( + getI18n().getMessage("message.permission.insufficient", SpPermission.UPDATE_TARGET)); return false; } @@ -198,7 +205,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref final TableTransferable transferable = (TableTransferable) event.getTransferable(); final TargetTable targetTable = (TargetTable) transferable.getSourceComponent(); - final Set targetList = targetTable.getDeletedEntityByTransferable(transferable); + final Set targetList = targetTable.getSelectedEntitiesByTransferable(transferable); final String targTagName = HawkbitCommonUtil.removePrefix(targetDetails.getTarget().getId(), SPUIDefinitions.TARGET_TAG_ID_PREFIXS); @@ -211,7 +218,6 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref publishAssignTargetTagEvent(result); publishUnAssignTargetTagEvent(targTagName, result); - } private void publishUnAssignTargetTagEvent(final String targTagName, final TargetTagAssignmentResult result) { @@ -222,7 +228,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref if (!isTargetTagUnAssigned) { return; } - eventBus.publish(this, ManagementUIEvent.UNASSIGN_TARGET_TAG); + getEventBus().publish(this, ManagementUIEvent.UNASSIGN_TARGET_TAG); } private void publishAssignTargetTagEvent(final TargetTagAssignmentResult result) { @@ -231,12 +237,12 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref if (!isNewTargetTagAssigned) { return; } - eventBus.publish(this, ManagementUIEvent.ASSIGN_TARGET_TAG); + getEventBus().publish(this, ManagementUIEvent.ASSIGN_TARGET_TAG); } - private boolean validateIfSourceisTargetTable(final Table source) { + private boolean validateIfSourceIsTargetTable(final Table source) { if (!source.getId().equals(UIComponentIdProvider.TARGET_TABLE_ID)) { - notification.displayValidationError(i18n.getMessage(SPUILabelDefinitions.ACTION_NOT_ALLOWED)); + uiNotification.displayValidationError(getI18n().getMessage(SPUILabelDefinitions.ACTION_NOT_ALLOWED)); return false; } return true; @@ -244,15 +250,15 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref @Override protected String getButttonWrapperIdPrefix() { - return SPUIDefinitions.TARGET_TAG_ID_PREFIXS; } @Override - public void refreshContainer() { + public void refreshTable() { removeGeneratedColumn(FILTER_BUTTON_COLUMN); ((LazyQueryContainer) getContainerDataSource()).refresh(); - addNewTargetTag(entityFactory.tag().create().name(NO_TAG).build()); + removeUpdateAndDeleteColumn(); + addNewTargetTag(entityFactory.tag().create().name(SPUIDefinitions.NO_TAG).build()); addColumn(); } @@ -260,7 +266,7 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref void onEvent(final ManagementUIEvent event) { if (event == ManagementUIEvent.RESET_SIMPLE_FILTERS && !managementUIState.getTargetTableFilters().getClickedTargetTags().isEmpty()) { - ((TargetTagFilterButtonClick) filterButtonClickBehaviour).clearTargetTagFilters(); + ((TargetTagFilterButtonClick) getFilterButtonClickBehaviour()).clearTargetTagFilters(); } } @@ -280,4 +286,35 @@ public class TargetTagFilterButtons extends AbstractFilterButtons implements Ref protected String getButtonWrapperData() { return SPUIDefinitions.TARGET_TAG_BUTTON; } + + @Override + protected void addEditButtonClickListener(final ClickEvent event) { + new UpdateTargetTagLayout(getI18n(), targetTagManagement, entityFactory, getEventBus(), permChecker, + uiNotification, getEntityId(event), + getCloseListenerForEditAndDeleteTag(new TargetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR))); + } + + @Override + protected void addDeleteButtonClickListener(final ClickEvent event) { + final String entityName = getEntityId(event); + openConfirmationWindowForDeletion(entityName, getI18n().getMessage("caption.entity.target.tag"), + new TargetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); + } + + @Override + protected void deleteEntity(final String entityName) { + final Optional tagToDelete = targetTagManagement.getByName(entityName); + tagToDelete.ifPresent(tag -> { + if (managementUIState.getTargetTableFilters().getClickedTargetTags().contains(entityName)) { + uiNotification.displayValidationError(getI18n().getMessage("message.tag.delete", entityName)); + removeUpdateAndDeleteColumn(); + } else { + targetTagManagement.delete(entityName); + getEventBus().publish(this, new TargetTagTableEvent(BaseEntityEventType.REMOVE_ENTITY, tag)); + uiNotification + .displaySuccess(getI18n().getMessage("message.delete.success", tagToDelete.get().getName())); + } + }); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterHeader.java similarity index 64% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterHeader.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterHeader.java index 8e7a128f4..4e190ca0c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterHeader.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterHeader; @@ -16,25 +16,26 @@ import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; -import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.MenuBar.Command; /** * Target Tag filter by Tag Header. */ public class TargetTagFilterHeader extends AbstractFilterHeader { - private static final long serialVersionUID = 3046367045669148009L; + private static final long serialVersionUID = 1L; private final ManagementUIState managementUIState; - TargetTagFilterHeader(final VaadinMessageSource i18n, final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout, - final ManagementUIState managementUIState, final SpPermissionChecker permChecker, - final UIEventBus eventBus) { + TargetTagFilterHeader(final VaadinMessageSource i18n, final ManagementUIState managementUIState, + final SpPermissionChecker permChecker, final UIEventBus eventBus) { super(permChecker, eventBus, i18n); this.managementUIState = managementUIState; - if (permChecker.hasCreateTargetPermission() || permChecker.hasUpdateTargetPermission()) { - createUpdateTargetTagLayout.init(); - } + } + + @Override + protected boolean doSubscribeToEventBus() { + return false; } @Override @@ -42,20 +43,9 @@ public class TargetTagFilterHeader extends AbstractFilterHeader { return UIComponentIdProvider.HIDE_TARGET_TAGS; } - @Override - protected boolean hasCreateUpdatePermission() { - - return permChecker.hasCreateTargetPermission() || permChecker.hasUpdateTargetPermission(); - } - @Override protected String getTitle() { - return i18n.getMessage("header.target.filter.tag", new Object[] {}); - } - - @Override - protected void settingsIconClicked(final ClickEvent event) { - // Add tag icon not displayed. + return getI18n().getMessage("header.target.filter.tag"); } @Override @@ -67,7 +57,7 @@ public class TargetTagFilterHeader extends AbstractFilterHeader { @Override protected void hideFilterButtonLayout() { managementUIState.setTargetTagFilterClosed(true); - eventBus.publish(this, ManagementUIEvent.HIDE_TARGET_TAG_LAYOUT); + getEventBus().publish(this, ManagementUIEvent.HIDE_TARGET_TAG_LAYOUT); } @Override @@ -80,4 +70,24 @@ public class TargetTagFilterHeader extends AbstractFilterHeader { return false; } + @Override + protected Command getAddButtonCommand() { + return null; + } + + @Override + protected Command getDeleteButtonCommand() { + return null; + } + + @Override + protected Command getUpdateButtonCommand() { + return null; + } + + @Override + protected String getMenuBarId() { + return null; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterLayout.java similarity index 58% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterLayout.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterLayout.java index f7a29ccfa..0085ad000 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/filter/TargetTagFilterLayout.java @@ -6,12 +6,14 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.ui.management.targettag; +package org.eclipse.hawkbit.ui.management.targettag.filter; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; +import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.common.event.FilterHeaderEvent.FilterHeaderEnum; +import org.eclipse.hawkbit.ui.common.event.TargetTagFilterHeaderEvent; import org.eclipse.hawkbit.ui.components.RefreshableContainer; import org.eclipse.hawkbit.ui.dd.criteria.ManagementViewClientCriterion; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; @@ -28,19 +30,42 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; */ public class TargetTagFilterLayout extends AbstractTargetTagFilterLayout implements RefreshableContainer { - private static final long serialVersionUID = 2153612878428575009L; - private final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout; + private static final long serialVersionUID = 1L; - public TargetTagFilterLayout(final VaadinMessageSource i18n, final CreateUpdateTargetTagLayoutWindow createUpdateTargetTagLayout, - final ManagementUIState managementUIState, + private final transient UIEventBus eventBus; + + /** + * Constructor + * + * @param i18n + * VaadinMessageSource + * @param managementUIState + * ManagementUIState + * @param managementViewClientCriterion + * ManagementViewClientCriterion + * @param permChecker + * SpPermissionChecker + * @param eventBus + * UIEventBus + * @param notification + * UINotification + * @param entityFactory + * EntityFactory + * @param targetFilterQueryManagement + * TargetFilterQueryManagement + * @param targetTagManagement + * TargetTagManagement + */ + public TargetTagFilterLayout(final VaadinMessageSource i18n, final ManagementUIState managementUIState, final ManagementViewClientCriterion managementViewClientCriterion, final SpPermissionChecker permChecker, final UIEventBus eventBus, final UINotification notification, final EntityFactory entityFactory, - final TargetFilterQueryManagement targetFilterQueryManagement) { - super(new TargetTagFilterHeader(i18n, createUpdateTargetTagLayout, managementUIState, permChecker, eventBus), - new MultipleTargetFilter(createUpdateTargetTagLayout, permChecker, managementUIState, i18n, eventBus, - managementViewClientCriterion, notification, entityFactory, targetFilterQueryManagement), + final TargetFilterQueryManagement targetFilterQueryManagement, + final TargetTagManagement targetTagManagement) { + super(new TargetTagFilterHeader(i18n, managementUIState, permChecker, eventBus), + new MultipleTargetFilter(permChecker, managementUIState, i18n, eventBus, managementViewClientCriterion, + notification, entityFactory, targetFilterQueryManagement, targetTagManagement), managementUIState); - this.createUpdateTargetTagLayout = createUpdateTargetTagLayout; + this.eventBus = eventBus; eventBus.subscribe(this); } @@ -56,11 +81,8 @@ public class TargetTagFilterLayout extends AbstractTargetTagFilterLayout impleme @EventBusListenerMethod(scope = EventScope.UI) void onTargetTagTableEvent(final TargetTagTableEvent tableEvent) { - if (BaseEntityEventType.ADD_ENTITY != tableEvent.getEventType() - && BaseEntityEventType.REMOVE_ENTITY != tableEvent.getEventType()) { - return; - } refreshContainer(); + eventBus.publish(this, new TargetTagFilterHeaderEvent(FilterHeaderEnum.SHOW_MENUBAR)); } @Override @@ -70,7 +92,6 @@ public class TargetTagFilterLayout extends AbstractTargetTagFilterLayout impleme @Override public void refreshContainer() { - getMultipleFilterTabs().getFilterByButtons().refreshContainer(); - createUpdateTargetTagLayout.refreshContainer(); + getMultipleFilterTabs().getFilterByButtons().refreshTable(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 424400213..56552348d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -48,8 +48,8 @@ import org.eclipse.hawkbit.ui.common.builder.TextAreaBuilder; import org.eclipse.hawkbit.ui.common.builder.TextFieldBuilder; import org.eclipse.hawkbit.ui.common.builder.WindowBuilder; import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery; -import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout; -import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout; +import org.eclipse.hawkbit.ui.management.miscs.ActionTypeOptionGroupLayout.ActionTypeOption; import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.groupschart.GroupsPieChart; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; @@ -356,8 +356,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private Long getScheduledStartTime() { return AutoStartOptionGroupLayout.AutoStartOption.SCHEDULED.equals(getAutoStartOption()) - ? autoStartOptionGroupLayout.getStartAtDateField().getValue().getTime() - : null; + ? autoStartOptionGroupLayout.getStartAtDateField().getValue().getTime() : null; } private int getErrorThresholdPercentage(final int amountGroup) { @@ -391,8 +390,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private CommonDialogWindow createWindow() { return new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW) - .caption(i18n.getMessage("caption.configure.rollout")).content(this).layout(this).i18n(i18n) - .helpLink(uiProperties.getLinks().getDocumentation().getRolloutView()) + .caption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.rollout"))).content(this) + .layout(this).i18n(i18n).helpLink(uiProperties.getLinks().getDocumentation().getRolloutView()) .saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 6845d5456..ca3377ccd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -562,14 +562,14 @@ public class RolloutListGrid extends AbstractGrid { private void updateRollout(final Long rolloutId) { final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(rolloutId, false); - addTargetWindow.setCaption(i18n.getMessage("caption.update.rollout")); + addTargetWindow.setCaption(i18n.getMessage("caption.update", i18n.getMessage("caption.rollout"))); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); } private void copyRollout(final Long rolloutId) { final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(rolloutId, true); - addTargetWindow.setCaption(i18n.getMessage("caption.create.rollout")); + addTargetWindow.setCaption(i18n.getMessage("caption.create.new", i18n.getMessage("caption.rollout"))); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); } @@ -583,8 +583,8 @@ public class RolloutListGrid extends AbstractGrid { final String formattedConfirmationQuestion = getConfirmationQuestion(rollout.get()); final ConfirmationDialog confirmationDialog = new ConfirmationDialog( - i18n.getMessage("caption.confirm.delete.rollout"), formattedConfirmationQuestion, - i18n.getMessage("button.ok"), i18n.getMessage("button.cancel"), ok -> { + i18n.getMessage("caption.entity.delete.action.confirmbox"), formattedConfirmationQuestion, + i18n.getMessage(SPUIDefinitions.BUTTON_OK), i18n.getMessage(SPUIDefinitions.BUTTON_CANCEL), ok -> { if (!ok) { return; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java index 05457cfdb..a207d196c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.ui.rollout.rolloutgroup; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.grid.AbstractGridHeader; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; @@ -140,7 +140,7 @@ public class RolloutGroupsListHeader extends AbstractGridHeader { headerCaption = new LabelBuilder().id(UIComponentIdProvider.ROLLOUT_GROUP_HEADER_CAPTION).name("") .buildCaptionLabel(); final Button rolloutsListViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); rolloutsListViewLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links"); rolloutsListViewLink.setDescription(i18n.getMessage("message.rollouts")); rolloutsListViewLink.setCaption(i18n.getMessage("message.rollouts")); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java index c420c52f6..351eba144 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java @@ -12,7 +12,7 @@ import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.vaadin.spring.events.EventBus.UIEventBus; @@ -37,7 +37,8 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { private final VaadinMessageSource i18n; RolloutGroupTargetsCountLabelMessage(final RolloutUIState rolloutUIState, - final RolloutGroupTargetsListGrid rolloutGroupTargetsListGrid, final VaadinMessageSource i18n, final UIEventBus eventBus) { + final RolloutGroupTargetsListGrid rolloutGroupTargetsListGrid, final VaadinMessageSource i18n, + final UIEventBus eventBus) { this.rolloutUIState = rolloutUIState; this.rolloutGroupTargetsListGrid = rolloutGroupTargetsListGrid; this.i18n = i18n; @@ -61,7 +62,7 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { private void applyStyle() { /* Create label for Targets count message displaying below the table */ - addStyleName(SPUILabelDefinitions.SP_LABEL_MESSAGE_STYLE); + addStyleName(SPUIStyleDefinitions.SP_LABEL_MESSAGE_STYLE); setContentMode(ContentMode.HTML); setId(UIComponentIdProvider.COUNT_LABEL); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java index 45f3c4cca..bd9f8ef49 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListHeader.java @@ -12,7 +12,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.ui.common.builder.LabelBuilder; import org.eclipse.hawkbit.ui.common.grid.AbstractGridHeader; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent; import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; @@ -143,14 +143,14 @@ public class RolloutGroupTargetsListHeader extends AbstractGridHeader { headerCaption = new LabelBuilder().name("").buildCaptionLabel(); headerCaption.setStyleName(ValoTheme.LABEL_BOLD + " " + ValoTheme.LABEL_SMALL); final Button rolloutsListViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); rolloutsListViewLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links"); rolloutsListViewLink.setDescription(i18n.getMessage("message.rollouts")); rolloutsListViewLink.setCaption(i18n.getMessage("message.rollouts")); rolloutsListViewLink.addClickListener(value -> showRolloutListView()); rolloutNameLink = SPUIComponentProvider.getButton(null, "", "", null, false, null, - SPUIButtonStyleSmallNoBorder.class); + SPUIButtonStyleNoBorder.class); rolloutNameLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links"); rolloutNameLink.setDescription("Rollout"); rolloutNameLink.addClickListener(value -> showRolloutGroupListView()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index 25fa046aa..da8eff681 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -23,7 +23,7 @@ import org.eclipse.hawkbit.ui.AbstractHawkbitUI; import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; +import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorder; import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem.ConfigurationItemChangeListener; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -140,14 +140,14 @@ public class TenantConfigurationDashboardView extends CustomComponent implements final HorizontalLayout hlayout = new HorizontalLayout(); hlayout.setSpacing(true); saveConfigurationBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.SYSTEM_CONFIGURATION_SAVE, "", "", - "", true, FontAwesome.SAVE, SPUIButtonStyleSmallNoBorder.class); + "", true, FontAwesome.SAVE, SPUIButtonStyleNoBorder.class); saveConfigurationBtn.setEnabled(false); saveConfigurationBtn.setDescription(i18n.getMessage("configuration.savebutton.tooltip")); saveConfigurationBtn.addClickListener(event -> saveConfiguration()); hlayout.addComponent(saveConfigurationBtn); undoConfigurationBtn = SPUIComponentProvider.getButton(UIComponentIdProvider.SYSTEM_CONFIGURATION_CANCEL, "", - "", "", true, FontAwesome.UNDO, SPUIButtonStyleSmallNoBorder.class); + "", "", true, FontAwesome.UNDO, SPUIButtonStyleNoBorder.class); undoConfigurationBtn.setEnabled(false); undoConfigurationBtn.setDescription(i18n.getMessage("configuration.cancellbutton.tooltip")); undoConfigurationBtn.addClickListener(event -> undoConfiguration()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index 7a124c000..c61e465d7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -18,7 +18,6 @@ import org.springframework.data.domain.Sort.Direction; * Class to provide the unchanged constants. */ public final class SPUIDefinitions { - /** * Available locales. */ @@ -28,12 +27,10 @@ public final class SPUIDefinitions { * Default locale. */ public static final String DEFAULT_LOCALE = "en"; - /** * Locale cookie name. */ public static final String COOKIE_NAME = "BOSCHSI_UII_LOCALE"; - /** * Lazy query container page size. */ @@ -63,7 +60,7 @@ public final class SPUIDefinitions { /** * Action history distribution set column. */ - public static final String ACTION_HIS_TBL_DIST = "Distributionset"; + public static final String ACTION_HIS_TBL_DIST = "Distribution set"; /** * Action history Action Id hidden column. @@ -135,76 +132,6 @@ public final class SPUIDefinitions { public static final String DISTRIBUTION_TAG_BUTTON = "Distribution Tag"; - /** - * New Target tag name field id. - */ - public static final String NEW_TARGET_TAG_NAME = "target.tag.add.name"; - - /** - * New Software Module name field id. - */ - public static final String NEW_SOFTWARE_TYPE_NAME = "software.type.add.name"; - - /** - * New Distribution Type name field id. - */ - public static final String NEW_DISTRIBUTION_TYPE_NAME = "distribution.set.type.add.name"; - - /** - * New Distribution Type key field id. - */ - public static final String NEW_DISTRIBUTION_TYPE_KEY = "distribution.set.type.add.key"; - - /** - * New Create Update option group id. - */ - public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id"; - - /** - * Assign option group id(Firmware/Software). - */ - public static final String ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "assign.option.group.soft.module.type.id"; - - /** - * New Software Module desc field id. - */ - public static final String NEW_SOFTWARE_TYPE_DESC = "software.type.add.desc"; - - /** - * Hide filter by dist type layout button. - */ - public static final String HIDE_FILTER_DIST_TYPE = "hide.filter.dist.type.layout"; - - /** - * New Distribution Type distribution field id. - */ - public static final String NEW_DISTRIBUTION_TYPE_DESC = "distribution.set.type.add.desc"; - - /** - * New Distribution Type distribution field id. - */ - public static final String NEW_DISTRIBUTION_SET_TYPE_NAME_COMBO = "distribution.set.type.name.combo"; - - /** - * New Software Module key field id. - */ - public static final String NEW_SOFTWARE_TYPE_KEY = "software.type.add.key"; - - /** - * New Target tag desc field id. - */ - public static final String NEW_TARGET_TAG_DESC = "target.tag.add.desc"; - - /** - * New distribution Type set tag add icon id. - */ - public static final String ADD_DISTRIBUTION_TYPE_TAG = "distribution.type.tag.add"; - - /** - * New software module set type add icon id. - */ - public static final String ADD_SOFTWARE_MODULE_TYPE = "softwaremodule.type.add"; - /** * No data. */ @@ -229,12 +156,10 @@ public final class SPUIDefinitions { * Filter by tag key. */ public static final String FILTER_BY_TAG = "FilterByTag"; - /** * Filter by no tag button. */ public static final String FILTER_BY_NO_TAG = "FilterByNoTag"; - /** * Filter by target filter query. */ @@ -244,42 +169,34 @@ public final class SPUIDefinitions { * Filter by distribution key. */ public static final String FILTER_BY_DISTRIBUTION = "FilterByDistribution"; - /** * Filter by distributionSet Type. */ public static final String FILTER_BY_DISTRIBUTION_SET_TYPE = "FilterByDistributionSetType"; - /** * Order by pinnedTarget. */ public static final String ORDER_BY_PINNED_TARGET = "OrderByPinnedTarget"; - /** * Filter by text key. */ public static final String FILTER_BY_TEXT = "FilterByText"; - /** * Text field style. */ public static final String TEXT_STYLE = "text-style"; - /** * Show actions for a target. */ public static final String ACTIONS_BY_TARGET = "ActionsByTarget"; - /** * Show action-states for a action. */ public static final String ACTIONSTATES_BY_ACTION = "ActionStatesByAction"; - /** * Show messages for a action-status. */ public static final String MESSAGES_BY_ACTIONSTATUS = "MessagesByActionStatus"; - /** * Key for no-message MessageProxy. */ @@ -300,36 +217,26 @@ public final class SPUIDefinitions { */ public static final String COMBO_BOX_SPECIFIC_STYLE = "combo-specific-style"; - /** - * Length of Assignment details table in save popup window. - */ - public static final int ACCORDION_TAB_DETAILS_PAGE_LENGTH = 7; - /** * Target and distribution column width in save popup window. */ public static final float TARGET_DISTRIBUTION_COLUMN_WIDTH = 2.8F; - /** * Discard column width in save window popup. */ public static final float DISCARD_COLUMN_WIDTH = 1.2F; - /** * Target tag name. */ public static final String TAG_NAME = "target-tag-name"; - /** * Target tag desc. */ public static final String TAG_DESC = "target-tag-desc"; - /** * Software type name. */ public static final String TYPE_NAME = "type-name"; - /** * DistributionSet type name. */ @@ -344,7 +251,6 @@ public final class SPUIDefinitions { * DistributionSet type key. */ public static final String DIST_SET_TYPE_KEY = "dist-set-type-key"; - /** * Software type desc. */ @@ -355,16 +261,6 @@ public final class SPUIDefinitions { */ public static final String TYPE_KEY = "type-key"; - /** - * Tag combo style. - */ - public static final String FILTER_TYPE_COMBO_STYLE = "filter-combo-specific-style"; - - /** - * Color label style. - */ - public static final String COLOR_LABEL_STYLE = "color-label-style"; - /** * Minimum width required to show tags for both target and distribution * table without horizontal scroll. In case browser width is less than this @@ -377,7 +273,6 @@ public final class SPUIDefinitions { * Target tag button id prefix. */ public static final String TARGET_TAG_ID_PREFIXS = "target.tag."; - /** * Distribution tag button id prefix. */ @@ -397,33 +292,27 @@ public final class SPUIDefinitions { * DistributionSet Type tag button id prefix. */ public static final String DISTRIBUTION_SET_TYPE_ID_PREFIXS = "dist.set.type."; - /** * Target last query date format . */ public static final String LAST_QUERY_DATE_FORMAT = "EEE MMM d HH:mm:ss z yyyy"; - /** * Target last query date format . */ public static final String LAST_QUERY_DATE_FORMAT_SHORT = "MMM d HH:mm z ''yy"; - /** * Item Id used in drop comparisons. */ public static final String ITEMID = "itemId"; - /** * Expand action history. */ public static final String EXPAND_ACTION_HISTORY = "expand.action.history"; - /** * Filter by distribution key. */ public static final String ORDER_BY_DISTRIBUTION = "OrderByDistribution"; - /** Artifact upload related entries - start **/ /** * Artifact details by Base software module id. @@ -517,9 +406,14 @@ public final class SPUIDefinitions { public static final String NO_TAG_BUTTON_ID = "no_tag_button"; /** - * CUSTOM_FILTER_DELETE. + * DELETE column/button. */ - public static final String CUSTOM_FILTER_DELETE = "Delete"; + public static final String DELETE = "Delete"; + + /** + * EDIT column/button. + */ + public static final String EDIT = "Edit"; /** * TARGET_FILTER_MANAGEMENT - header caption . @@ -563,6 +457,21 @@ public final class SPUIDefinitions { public static final String ACTION_HIS_TBL_MAINTENANCE_WINDOW = "Maintenance Window"; + /** + * id for delete icon in entity table + */ + public static final String DELETE_ENTITY = "deleteEntity"; + + public static final String UPDATE_FILTER_BUTTON_COLUMN = "updateFilterButton"; + + public static final String DELETE_FILTER_BUTTON_COLUMN = "deleteFilterButton"; + + public static final String NO_TAG = "NO TAG"; + + public static final String BUTTON_CANCEL = "button.cancel"; + + public static final String BUTTON_OK = "button.ok"; + /** * /** Constructor. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java index 469340f1b..d2bb04c03 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java @@ -8,37 +8,11 @@ */ package org.eclipse.hawkbit.ui.utils; -import com.vaadin.ui.themes.ValoTheme; - /** * RepositoryConstants required for Label. */ public final class SPUILabelDefinitions { - /** - * Style - Message. - */ - public static final String SP_LABEL_MESSAGE_STYLE = "count-msg-box"; - /** - * Message hint text style. - */ - public static final String SP_MESSAGE_HINT_TEXT = "message-hint-text"; - /** - * Style - Success. - */ - public static final String SP_NOTIFICATION_SUCCESS_MESSAGE_STYLE = ValoTheme.NOTIFICATION_SUCCESS + " " - + ValoTheme.NOTIFICATION_TRAY; - /** - * Style - Error. - */ - public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " " - + ValoTheme.NOTIFICATION_TRAY; - - /** - * Style - Warning. - */ - public static final String SP_NOTIFICATION_WARNING_MESSAGE_STYLE = ValoTheme.NOTIFICATION_WARNING + " " - + ValoTheme.NOTIFICATION_TRAY; /** * Delay - Notification. */ @@ -84,6 +58,11 @@ public final class SPUILabelDefinitions { */ public static final String VAR_ID = "id"; + /** + * ID for software module + */ + public static final String VAR_SWM_ID = "swId"; + /** * DESC. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java index b7d140dbc..9b5e67a94 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIStyleDefinitions.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.utils; +import com.vaadin.ui.themes.ValoTheme; + /** * RepositoryConstants required for Style. * @@ -30,11 +32,6 @@ public final class SPUIStyleDefinitions { */ public static final String ACTION_HISTORY_MESSAGE_GRID = "action-history-message-grid"; - /** - * Style for accordion tab button. - */ - public static final String SP_ACCORDION_TAB_BTN = "accordion-tab-button-style"; - /** * Confirm box question label style. */ @@ -43,7 +40,7 @@ public final class SPUIStyleDefinitions { /** * Confirm box window style. */ - public static final String CONFIRMBOX_WINDOW_SYLE = "confirmbox-window-style"; + public static final String CONFIRMBOX_WINDOW_STYLE = "confirmbox-window-style"; /** * Error label style. @@ -69,11 +66,6 @@ public final class SPUIStyleDefinitions { public static final String WIDGET_TITLE = "widget-header"; - /** - * Style of accordian in confirmation window. - */ - public static final String CONFIRM_WINDOW_ACCORDIAN = "accordion"; - /** * Style of result action messages in the confirmation window. */ @@ -103,16 +95,6 @@ public final class SPUIStyleDefinitions { */ public static final String REDICON = "redicon"; - /** - * Action button style- footer buttons. - */ - public static final String ACTION_BUTTON = "action-button"; - - /** - * Width of 'drop to delete' layout and 'no actions' button - */ - public static final String DEL_ACTION_BUTTON = "del-action-button"; - /** * Confirmation window caption stle. */ @@ -253,9 +235,50 @@ public final class SPUIStyleDefinitions { public static final String METADATA_GRID = "metadata-grid"; /** - * Footer layout style. + * Tag combo style. */ - public static final String FOOTER_LAYOUT = "footer-layout"; + public static final String FILTER_TYPE_COMBO_STYLE = "filter-combo-specific-style"; + + /** + * Color label style. + */ + public static final String COLOR_LABEL_STYLE = "color-label-style"; + + /** + * Style - Message. + */ + public static final String SP_LABEL_MESSAGE_STYLE = "count-msg-box"; + + /** + * Message hint text style. + */ + public static final String SP_MESSAGE_HINT_TEXT = "message-hint-text"; + /** + * Style - Success. + */ + public static final String SP_NOTIFICATION_SUCCESS_MESSAGE_STYLE = ValoTheme.NOTIFICATION_SUCCESS + " " + + ValoTheme.NOTIFICATION_TRAY; + /** + * Style - Error. + */ + public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " " + + ValoTheme.NOTIFICATION_TRAY; + + /** + * Style - Warning. + */ + public static final String SP_NOTIFICATION_WARNING_MESSAGE_STYLE = ValoTheme.NOTIFICATION_WARNING + " " + + ValoTheme.NOTIFICATION_TRAY; + + /** + * Style for the positio of the menu bar to configure tags and types + */ + public static final String CONFIG_MENU_BAR_POSITION = "menubar-position"; + + /** + * Style for the menu bar items of the menu bar to configure tags and types + */ + public static final String CONFIG_MENU_BAR_ITEMS = "tags"; /** * Constructor. diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java index 0a57647c5..7745d13cd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UIComponentIdProvider.java @@ -19,14 +19,18 @@ public final class UIComponentIdProvider { * ID-Target. */ public static final String TARGET_TABLE_ID = "target.tableId"; + /** - * caption for add target window + * ID of the confirmation window when assigning a distribution set to a + * target */ - public static final String TARGET_ADD_CAPTION = "caption.add.new.target"; + public static final String DIST_SET_TO_TARGET_ASSIGNMENT_CONFIRM_ID = "dist.to.target.assign.confirm.id"; + /** - * caption for update target window + * ID of the confirmation window when assigning a software module to a + * distribution set */ - public static final String TARGET_UPDATE_CAPTION = "caption.update.target"; + public static final String SOFT_MODULE_TO_DIST_ASSIGNMENT_CONFIRM_ID = "swm.to.dist.assign.confirm.id"; /** * ID- Targ.Cont ID. */ @@ -39,14 +43,6 @@ public final class UIComponentIdProvider { * ID-Targ.Disc. */ public static final String TARGET_ADD_DESC = "target.add.desc"; - /** - * ID-Targ.DEL. - */ - public static final String TARGET_DELETE_ALL = "target.delete.all"; - /** - * ID-SW.DEL. - */ - public static final String SW_DELETE_ALL = "swmodule.delete.all"; /** * ID-Targ.Edit.icon. */ @@ -68,6 +64,17 @@ public final class UIComponentIdProvider { */ public static final String TARGET_FILTER_ADD_ICON_ID = "target.filter.add.id"; + /** + * ID for menubar for configuring target tags + */ + public static final String TARGET_MENU_BAR_ID = "target.menu.bar.id"; + + /** + * ID for the cancel button in the tag header, when updating or deleting a + * tag is selected + */ + public static final String CANCEL_UPDATE_TAG_ID = "cancel.update.tag.id"; + /** * ID for NO TAG for targets */ @@ -78,10 +85,6 @@ public final class UIComponentIdProvider { */ public static final String DIST_TABLE_ID = "dist.tableId"; - public static final String DIST_ADD_CAPTION = "caption.add.dist"; - - public static final String DIST_UPDATE_CAPTION = "caption.update.dist"; - /** * ID-Dist.Name. */ @@ -98,10 +101,6 @@ public final class UIComponentIdProvider { * ID-Dist.desc. */ public static final String DIST_ADD_DESC = "dist.add.desc"; - /** - * /** ID-Dist.DELETE. - */ - public static final String DIST_DELETE_ALL = "dist.delete.all"; /** * ID-Dist.MigCheck. */ @@ -126,6 +125,12 @@ public final class UIComponentIdProvider { * ID-Dist.PIN. */ public static final String DIST_PIN_BUTTON = "dist.pin.button"; + + /** + * ID for menubar for configuring distribution set tags + */ + public static final String DIST_TAG_MENU_BAR_ID = "distribution.set.menu.bar.id"; + /** * ID for NO TAG for distribution sets */ @@ -146,14 +151,12 @@ public final class UIComponentIdProvider { * ID - soft.module.vendor. */ public static final String SOFT_MODULE_VENDOR = "soft.module.vendor"; + /** - * ID - Save Assign. + * ID for menubar for configuring software module types */ - public static final String SAVE_ASSIGNMENT = "save.actions.popup.assign"; - /** - * ID - Discard Assign. - */ - public static final String DISCARD_ASSIGNMENT = "discard.actions.popup.assign"; + public static final String SOFT_MODULE_TYPE_MENU_BAR_ID = "soft.module.type.menu.bar.id"; + /** * ID - Delete Distribution SetType Save. */ @@ -226,10 +229,6 @@ public final class UIComponentIdProvider { */ public static final String TARGET_DROP_FILTER_ICON = "target.drop.filter.icon"; - /** - * Pending action button id. - */ - public static final String PENDING_ACTION_BUTTON = "pending.action.button"; /** * Action history grid Id. */ @@ -324,10 +323,6 @@ public final class UIComponentIdProvider { */ public static final String MAINTENANCE_WINDOW_SCHEDULE_TRANSLATOR_ID = "maintenance.window.schedule.translator"; - /** - * Delete button wrapper id. - */ - public static final String DELETE_BUTTON_WRAPPER_ID = "delete.button"; /** * tag color preview button id. */ @@ -356,14 +351,6 @@ public final class UIComponentIdProvider { * Upload - type button id. */ public static final String UPLOAD_TYPE_BUTTON_PREFIX = "upload.type.button."; - /** - * Upload - process button id. - */ - public static final String UPLOAD_PROCESS_BUTTON = "upload.process.button"; - /** - * Upload - discard button id. - */ - public static final String UPLOAD_DISCARD_BUTTON = "upload.discard.button"; /** * Upload - artifact detail close button. @@ -409,6 +396,12 @@ public final class UIComponentIdProvider { * Upload - artifact result table. */ public static final String UPLOAD_RESULT_TABLE = "upload.result.table"; + + /** + * Upload - artifact upload error reason. + */ + public static final String UPLOAD_ERROR_REASON = "upload-error-reason"; + /** * Upload - software module search text id. */ @@ -418,16 +411,16 @@ public final class UIComponentIdProvider { */ public static final String SW_MODULE_SEARCH_RESET_ICON = "sw.search.reset.icon"; - /** - * Upload - artifact upload error reason. - */ - public static final String UPLOAD_ERROR_REASON = "upload-error-reason"; - /** * Upload - artifact upload - Software module add button. */ public static final String SW_MODULE_ADD_BUTTON = "sw.module.add.button"; + /** + * Create Software Module dialog. + */ + public static final String SW_MODULE_CREATE_DIALOG = "sw.module.create.dialog"; + /** * Upload - artifact upload - Software module type combo id. */ @@ -448,10 +441,20 @@ public final class UIComponentIdProvider { */ public static final String UPLOAD_SW_MODULE_EDIT_BUTTON = "swmodule.edit.button"; + /** + * Artifact upload - sw module metadata button id. + */ + public static final String UPLOAD_SW_MODULE_METADATA_BUTTON = "swmodule.metadata.button"; + /** * Ds edit button id. */ public static final String DS_EDIT_BUTTON = "ds.edit.button"; + + /** + * Ds metadata button id. + */ + public static final String DS_METADATA_BUTTON = "ds.metadata.button"; /** * Upload Artifact details max table Id. */ @@ -526,6 +529,16 @@ public final class UIComponentIdProvider { */ public static final String CANCEL_BUTTON = "common.dialog.window.cancel"; + /** + * ID for update tags and types icon + */ + public static final String UPDATE_TAG_ID = "update."; + + /** + * ID for delete tags and types icon + */ + public static final String DELETE_TAG_ID = "delete."; + /** * Cancel button is. */ @@ -656,10 +669,109 @@ public final class UIComponentIdProvider { */ public static final String ADD_TARGET_TAG = "target.tag.add"; + /** + * Target tag configure icon id. + */ + public static final String CONFIGURE_TARGET_TAG = "target.tag.configure"; + /** * New distribution set tag add icon id. */ public static final String ADD_DISTRIBUTION_TAG = "distribution.tag.add"; + + /** + * New distribution set tag configure icon id. + */ + public static final String CONFIGURE_DISTRIBUTION_TAG = "distribution.tag.configure"; + + /** + * New Target tag name field id. + */ + public static final String NEW_TARGET_TAG_NAME = "target.tag.add.name"; + + /** + * New Distribution tag name field id. + */ + public static final String NEW_DISTRIBUTION_TAG_NAME = "distribution.tag.add.name"; + + /** + * New Software Module name field id. + */ + public static final String NEW_SOFTWARE_TYPE_NAME = "software.type.add.name"; + + /** + * New Distribution Type name field id. + */ + public static final String NEW_DISTRIBUTION_TYPE_NAME = "distribution.set.type.add.name"; + + /** + * New Distribution Type key field id. + */ + public static final String NEW_DISTRIBUTION_TYPE_KEY = "distribution.set.type.add.key"; + + /** + * New Create Update option group id. + */ + public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id"; + + /** + * Assign option group id(Firmware/Software). + */ + public static final String ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "assign.option.group.soft.module.type.id"; + + /** + * New Software Module desc field id. + */ + public static final String NEW_SOFTWARE_TYPE_DESC = "software.type.add.desc"; + /** + * Hide filter by dist type layout button. + */ + public static final String HIDE_FILTER_DIST_TYPE = "hide.filter.dist.type.layout"; + /** + * New Distribution Type distribution field id. + */ + public static final String NEW_DISTRIBUTION_TYPE_DESC = "distribution.set.type.add.desc"; + + /** + * New Distribution Type distribution field id. + */ + public static final String NEW_DISTRIBUTION_SET_TYPE_NAME_COMBO = "distribution.set.type.name.combo"; + + /** + * New Software Module key field id. + */ + public static final String NEW_SOFTWARE_TYPE_KEY = "software.type.add.key"; + + /** + * New Target tag desc field id. + */ + public static final String NEW_TARGET_TAG_DESC = "target.tag.add.desc"; + + /** + * New Distribution tag desc field id. + */ + public static final String NEW_DISTRIBUTION_TAG_DESC = "distribution.tag.add.desc"; + + /** + * New distribution Type set tag add icon id. + */ + public static final String ADD_DISTRIBUTION_TYPE_TAG = "distribution.type.tag.add"; + + /** + * New distribution Type set tag configure icon id. + */ + public static final String CONFIGURE_DISTRIBUTION_TYPE_TAG = "distribution.type.tag.configure"; + + /** + * New software module set type add icon id. + */ + public static final String ADD_SOFTWARE_MODULE_TYPE = "softwaremodule.type.add"; + + /** + * New software module set type configure icon id. + */ + public static final String CONFIGURE_SOFTWARE_MODULE_TYPE = "softwaremodule.type.configure"; + /** * Bulk target upload - distribution set combo. */ @@ -669,10 +781,12 @@ public final class UIComponentIdProvider { * Bulk target upload - description. */ public static final String BULK_UPLOAD_DESC = "bulkupload.description"; + /** * Bulk target upload - tag field. */ public static final String BULK_UPLOAD_TAG = "bulkupload.tag"; + /** * Bulk target upload - count label. */ @@ -765,7 +879,6 @@ public final class UIComponentIdProvider { /** * Target bulk upload minimize button id. */ - public static final String BULK_UPLOAD_CLOSE_BUTTON_ID = "bulk.upload.close.button.id"; /** @@ -948,31 +1061,26 @@ public final class UIComponentIdProvider { */ public static final String VALIDATION_STATUS_ICON_ID = "validation.status.icon"; - /** - * Artifact upload status popup - minimize button id. - */ - public static final String UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID = "artifact.upload.minimize.button.id"; - /** * Artifact upload status popup - close button id. */ public static final String UPLOAD_STATUS_POPUP_CLOSE_BUTTON_ID = "artifact.upload.close.button.id"; - /** - * Artifact upload status popup - resize button id. - */ - public static final String UPLOAD_STATUS_POPUP_RESIZE_BUTTON_ID = "artifact.upload.resize.button.id"; - /** * Artifact upload view - upload status button id. */ public static final String UPLOAD_STATUS_BUTTON = "artficat.upload.status.button.id"; /** - * Artifact uplaod view - uplod status popup id. + * Artifact upload view - uplod status popup id. */ public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; + /** + * Artifact upload view - uplod status popup grid. + */ + public static final String UPLOAD_STATUS_POPUP_GRID = "artifact.upload.status.popup.grid"; + /** * Software module table - Manage metadata id. */ @@ -1103,6 +1211,26 @@ public final class UIComponentIdProvider { */ public static final String ROLLOUT_APPROVAL_REMARK_FIELD_ID = "rollout.approve.remark"; + /** + * ID for the menu bar item to update a tag or type + */ + public static final String CONFIG_MENU_BAR_UPDATE = "update"; + + /** + * ID for the menu bar item to delete a tag or type + */ + public static final String CONFIG_MENU_BAR_DELETE = "delete"; + + /** + * ID for the menu bar item to create a tag or type + */ + public static final String CONFIG_MENU_BAR_CREATE = "create"; + + /** + * Artifact upload status popup - minimize button id. + */ + public static final String UPLOAD_STATUS_POPUP_MINIMIZE_BUTTON_ID = "artifact.upload.minimize.button.id"; + /** * /* Private Constructor. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java index 3a2aecca7..96f04bf29 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java @@ -39,7 +39,7 @@ public class UINotification implements Serializable { * is the message to displayed as success. */ public void displaySuccess(final String message) { - notificationMessage.showNotification(SPUILabelDefinitions.SP_NOTIFICATION_SUCCESS_MESSAGE_STYLE, null, message, + notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_SUCCESS_MESSAGE_STYLE, null, message, true); } @@ -50,7 +50,7 @@ public class UINotification implements Serializable { * is the message to displayed as warning. */ public void displayWarning(final String message) { - notificationMessage.showNotification(SPUILabelDefinitions.SP_NOTIFICATION_WARNING_MESSAGE_STYLE, null, message, + notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_WARNING_MESSAGE_STYLE, null, message, true); } @@ -64,7 +64,7 @@ public class UINotification implements Serializable { final StringBuilder updatedMsg = new StringBuilder(FontAwesome.EXCLAMATION_TRIANGLE.getHtml()); updatedMsg.append(' '); updatedMsg.append(message); - notificationMessage.showNotification(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null, + notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null, updatedMsg.toString(), true); } diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/accordion.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/accordion.scss index fde6ad203..18af89765 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/accordion.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/accordion.scss @@ -20,11 +20,6 @@ } } - //Accordion button layout style - .accordion-tab-button-style { - margin: 10px 0; - } - .accordion { margin: 10px; width: 550px !important; diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/artifact-upload.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/artifact-upload.scss index 6f7bf2c2c..94cc1615c 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/artifact-upload.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/artifact-upload.scss @@ -89,6 +89,10 @@ // Hence provide margin-top so that it appear at center. margin-top: 45px; } + + .upload-button { + margin-top: 10px; + } //Upload confirmation popup and upload result popup style .confirmation-popup { diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/common.scss index b81e3dc77..b67fa143b 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/common.scss @@ -86,20 +86,6 @@ z-index: 1; } - .view-header:before { - border-bottom: $app-header-border-bottom; - font-size: 42px; - font-weight: bold; - height: 42px; - line-height: 50px; - padding-bottom: 5px; - padding-left: 0; - padding-top: 0; - position: absolute; - top: 0; - width: calc(100% - 15px); - z-index: 1; - } .view-header:after { background: $logo-image no-repeat right top; background-position: $logo-position; diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/filter-layout-styles.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/filter-layout-styles.scss index 04034af82..59f0c0cd4 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/filter-layout-styles.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/filter-layout-styles.scss @@ -11,7 +11,7 @@ //Tag widget header height adjusted to match table header heights .filter-btns-header-layout { - padding-bottom: 22px; + padding-bottom: 14px; } //Tag layout style @@ -34,6 +34,10 @@ .v-table-table { box-shadow: none !important; } + + .v-table-body { + overflow-x:hidden; + } } //Tag button wrapper style diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss deleted file mode 100644 index 2ce9eb99b..000000000 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/footer-common.scss +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -// scss-lint:disable ImportantRule, PropertySortOrder - -@mixin footer-common { - - //Footer drop to delete layout - icon style - .delete-icon { - .v-icon { - color: $signal-red-color !important; - } - } - - .no-border { - border: 0px !important; - } - - //Style applied on all buttons of footer layout.Width and height of buttons can be configured - .action-button { - @include valo-gradient($color: $footer-button-background-color); - background-image: none; - border: 1px solid $widget-border-color; - color: $footer-button-color; - font-weight: $footer-button-font-weight; - - .v-icon { - color: $hawkbit-primary-color; - } - height: round($action-button-height-scale * $v-unit-size) !important; - font-size: $v-font-size--small !important; - } - - .action-button:focus:after { - border: 1px solid $footer-button-background-color; - box-shadow: none !important; - } - - .action-button:before { - height: 100% !important; - } - - //Upload button style - .action-button .v-button { - height: round($action-button-height-scale * $v-unit-size) !important; - font-size: $v-font-size--small !important; - } - - .v-upload .v-button { - text-align: center !important; - } - - //Width of 'drop to delete' layout and 'no actions' button - .del-action-button { - width: round($delete-action-button-width-scale * $v-unit-size); - } - - //Drop to delete layout style - .drop-to-delete-button { - background: $widget-bg !important; - background-image: none !important; - cursor: auto !important; - - .v-pressed:after { - background: none repeat scroll 0 0 transparent !important; - border-color: #ffffff !important; - box-shadow: none !important; - opacity: 1; - } - } - - .drop-to-delete-button:hover { - background: $widget-bg !important; - background-image: none !important; - } - - .drop-to-delete-button:hover:after, - .drop-to-delete-button:focus:after { - background: none repeat scroll 0 0 transparent !important; - border-color: $widget-border-color !important; - box-shadow: none !important; - } - - .drop-to-delete-button:active { - opacity: 1 !important; - } - - - .footer-layout{ - .app-loading { - background-position: bottom; - background-repeat: no-repeat; - } - - .app-loading:before { - background: none; - height: 20px !important; - width: 20px !important; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - border: 2px solid rgba(0, 0, 0, 0); - border-top-color: $hawkbit-primary-color; - border-right-color: $hawkbit-primary-color; - border-radius: 100%; - -webkit-animation: v-rotate-360 500ms infinite linear; - -moz-animation: v-rotate-360 500ms infinite linear; - -ms-animation: v-rotate-360 500ms infinite linear; - -o-animation: v-rotate-360 500ms infinite linear; - animation: v-rotate-360 500ms infinite linear; - pointer-events: none; - position: fixed; - margin-top: 12px; - margin-left: -10px; - } - } - -} diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/grid.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/grid.scss index 6c9e6b310..72929ebb2 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/grid.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/grid.scss @@ -30,4 +30,12 @@ .v-grid-cell.frozen + th { border-left: $v-grid-border-size solid $widget-border-color ; } + + .v-button-borderless-colored { + color: inherit; + } + + .fullSize .v-gridlayout-slot { + height: 100% !important; + } } \ No newline at end of file diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/hawkbitvariables.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/hawkbitvariables.scss index 477134281..4d604d169 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/hawkbitvariables.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/hawkbitvariables.scss @@ -67,8 +67,6 @@ $menu-title-bg-color: #551f62; //Color of icons like add ,config,search etc $button-icon-color: #551f62; -//Footer button background color -$footer-button-background-color: #fff; //Color of assigned distribution,when target is selected $installed-row-color: $lighter-orange-color; @@ -85,19 +83,9 @@ $success-icon-color: #ff0000; //Error icon color on invalid target filter query $error-icon-color: #008000; - //Font style of view caption $view-caption-font-style: 400 1.6em "Open Sans", sans-serif; -//Footer button width scale -$action-button-width-scale: 3; - -//Footer button height scale -$action-button-height-scale:1.2; - -//Delete button width scale -$delete-action-button-width-scale:4.8; - //Detail tab - font scale $details-tab-font-scale: 1; diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss index bd48c0ad1..ed09af636 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss @@ -33,7 +33,7 @@ //Deployment view - Style of count message .v-caption-count-msg-box { - text-align: center; + margin-left: 180px; color: $info-message-color-grey; font-weight: bold; height: 10px; @@ -41,9 +41,8 @@ //*Deployment view -Assigned and installed message* .count-msg-box { - padding-left: 10px; + margin-left: 180px; padding-top: 3px; - text-align: center; color: $info-message-color-grey; font-weight: italic; font-size: 12px; @@ -288,4 +287,31 @@ .breadcrumbPaddingLeft{ padding-left: 3px !important; } + + .app-loading { + background-position: bottom; + background-repeat: no-repeat; + } + + .app-loading:before { + background: none; + height: 20px !important; + width: 20px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(0, 0, 0, 0); + border-top-color: $hawkbit-primary-color; + border-right-color: $hawkbit-primary-color; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + -ms-animation: v-rotate-360 500ms infinite linear; + -o-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; + position: fixed; + margin-top: 12px; + margin-left: -10px; + } } diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss index 24c77f776..c268df035 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/tags.scss @@ -70,4 +70,55 @@ text-overflow:ellipsis; text-align:left; } + + .menubar-position { + margin-top: -5px; + right: 20px; + width: 20px; + } + + .v-menubar-menuitem-tags .v-menubar-submenu-indicator + .v-menubar-menuitem-caption:after { + content: none; + } + + .v-menubar-popup .v-menubar-menuitem-menubar-position { + padding-left: 0px; + width: 100px; + right: 0px; + } + + .v-menubar-submenu-menubar-position { + width: 100px; + right: 0px; + } + + .v-menubar-submenu-menubar-position .v-menubar-menuitem { + padding-left: 3px; + } + + .v-menubar-borderless .v-menubar-menuitem-selected { + color: inherit; + background-image: none; + background-color: inherit; + } + + .v-menubar > .v-menubar-menuitem .v-icon { + margin: 0 4px 0 19px; + } + + .v-menubar-borderless .v-menubar-menuitem { + padding: 0px; + } + + .v-menubar > .v-menubar-menuitem { + padding: 0px; + } + + .targetTag { + right: 19px; + } + + #target\.tag\.drop\.area .v-slot-icon-only { + height: 32px; + } } diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/hawkbittheme.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/hawkbittheme.scss index 24d2b2890..d73af93dc 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/hawkbittheme.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/hawkbittheme.scss @@ -61,7 +61,6 @@ $v-animations-enabled: true; @import 'customstyles/systemconfig'; @import 'customstyles/table-common'; @import 'customstyles/table-header-common'; -@import 'customstyles/footer-common'; @import 'customstyles/popup-common'; @import 'customstyles/target-filter-query'; @import 'customstyles/statusprogressbar'; @@ -97,7 +96,6 @@ $v-included-components: remove($v-included-components, form); @include filter-layout-styles; @include table-common; @include table-header-common; - @include footer-common; @include popup-common; @include target-filter-query; @include statusprogressbar; diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index c5878338f..137d073b5 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -106,13 +106,17 @@ caption.filter.simple = Simple Filter caption.filter.custom = Custom Filter caption.metadata = Metadata +caption.target = Target +caption.distribution = Distribution +caption.tag = Tag +caption.type = Type +caption.software.module = Software Module +caption.rollout = Rollout + +caption.create.new = Create new {0} +caption.update = Update {0} + caption.select.auto.assign.dist = Select auto assignment distribution set -caption.add.dist = Configure New Distribution -caption.update.dist = Configure Update Distribution -caption.add.tag = Configure Tag -caption.add.type = Configure Type -caption.add.new.target = Configure New Target -caption.update.target = Configure Update Target caption.bulk.upload.targets = Bulk Upload caption.softwares.distdetail.tab = Modules caption.tags.tab = Tags @@ -124,22 +128,18 @@ caption.assign.dist.accordion.tab = Assign Software Module caption.delete.dist.accordion.tab = Delete Distributions caption.delete.target.accordion.tab = Delete Targets caption.delete.swmodule.accordion.tab = Delete SW Modules -caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type -caption.delete.sw.module.type.accordion.tab = Delete Software Module Type +caption.delete.dist.set.type.accordion.tab = Delete Distribution set type +caption.delete.sw.module.type.accordion.tab = Delete Software module type caption.attributes = Attributes -caption.panel.dist.installed = Installed Distribution Set -caption.panel.dist.assigned = Assigned Distribution Set -caption.soft.delete.confirmbox = Confirm Software Module Delete Action +caption.panel.dist.installed = Installed Distribution set +caption.panel.dist.assigned = Assigned Distribution set caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forcequit.action.confirmbox = Confirm force quit action caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.confirm.abort.action = Confirm Abort Action -caption.confirm.delete.rollout = Confirm Rollout deletion -caption.filter.delete.confirmbox = Confirm Filter Delete Action caption.metadata.popup = Metadata of -caption.metadata.delete.action.confirmbox = Confirm Metadata Delete Action caption.confirm.assign.consequences = Auto assign consequences caption.auto.assignment.ds = Auto assignment @@ -176,12 +176,9 @@ label.create.type = Create Type label.update.type = Update Type label.singleAssign.type = Firmware (FW) label.multiAssign.type = Software (SW) -label.choose.type = Choose Type to Update -label.choose.type.color = Choose Type Color +label.choose.type.color = Type Color +label.choose.tag.color = Tag Color label.combobox.type = Select Type -label.combobox.tag = Select Tag -label.choose.tag = Choose Tag to update -label.choose.tag.color = Choose Tag Color label.target.filtered.total = Total Filtered Targets : label.filter = Filter : label.target.filter.count = Total Targets : @@ -217,7 +214,7 @@ label.tag.name = Tag name label.configuration.auth.header = Allow targets to authenticate via a certificate authenticated by an reverse proxy label.configuration.auth.gatewaytoken = Allow a gateway to authenticate and manage multiple targets through a gateway security token label.configuration.auth.targettoken = Allow targets to authenticate directly with their target security token -label.configuration.repository.autoclose.action = Autoclose running actions with new Distribution Set assignment +label.configuration.repository.autoclose.action = Autoclose running actions with new Distribution set assignment label.configuration.anonymous.download = Allow targets to download artifacts without security credentials label.unsupported.browser.ie=Sorry! current browser is not supported. Please use Internet Explorer 11 and above label.auto.assign.description=When an auto assign distribution set is selected, it will be automatically assigned to all targets that match the target filter. @@ -288,10 +285,10 @@ message.target.assigned.pending = Some target(s) are already assigned.Pending f message.cannot.delete = Cannot be deleted message.check.softwaremodule = Please provide both name and verion! message.duplicate.softwaremodule = {0} : {1} already exists! -message.tag.delete = Please unclick the tag {0}, then try to delete -message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete +message.tag.delete = Please unclick the tag {0} before deleting +message.dist.type.check.delete = Please unclick the distribution type {0} before deleting message.cannot.delete.default.dstype = Default distribution set type cannot be deleted -message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0} before deleting message.targets.already.deleted = Few Target(s) are already deleted. Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -317,7 +314,7 @@ message.dist.deleted = {0} Distribution set(s) deleted message.tag.update.mandatory = Please select the Tag to update message.tag.duplicate.check = {0} already exists, please enter another value message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value -message.type.update.mandatory = Please select the Distribution Set type to update +message.type.update.mandatory = Please select the Distribution set type to update message.type.key.swmodule.duplicate.check = Software Module type with key {0} already exists, please give another value message.no.action.history = No action history is available for the target : {0} message.no.available = --No messages available-- @@ -334,23 +331,23 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? +message.sm.delete.confirm = Are you sure you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel.. message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! -message.cancel.action.confirm = Are you sure that you want to cancel this action? +message.cancel.action.confirm = Are you sure you want to cancel this action? message.target.alreadyAssigned = {0} Target(s) were already assigned -message.dist.alreadyAssigned = {0} Distribution Set(s) were already assigned +message.dist.alreadyAssigned = {0} Distribution set(s) were already assigned message.force.action = Force -message.force.action.confirm = Are you sure that you want to force this action? +message.force.action.confirm = Are you sure you want to force this action? message.force.action.success = Action forced successfully ! message.forcequit.action = Force Quit.. message.forcequit.action.success = Action has been force quit successfully ! message.forcequit.action.failed = Force Quitting the action is not possible ! -message.forcequit.action.confirm = Attention!\nForce quit should only be used when the assignment action is not working properly.\nForce quitting an action has no effect on the connected target. It is just resetting \nthe data stored on the SP update server. \nAre you absolutely sure that you want to force quit this action? +message.forcequit.action.confirm = Attention!\nForce quit should only be used when the assignment action is not working properly.\nForce quitting an action has no effect on the connected target. It is just resetting \nthe data stored on the SP update server. \nAre you absolutely sure you want to force quit this action? message.distribution.no.update = distribution {0} set is already assigned to targets and cannot be changed message.action.not.allowed = Action not allowed message.action.did.not.work = Action did not work. Please try again. @@ -362,9 +359,9 @@ message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0} message.no.targets.assiged.fortag = No targets are assigned to tag {0} message.error.missing.tagname = Please select tag name message.type.delete = Please unclick the distribution type {0}, then try to delete -message.error.dist.set.type.update= Distribution Set Type is already assigned to set(s) and cannot be changed +message.error.dist.set.type.update= Distribution set type is already assigned to set(s) and cannot be changed message.no.directory.upload = Directory upload is not supported -message.delete.filter.confirm = Are you sure that you want to delete custom filter? +message.delete.filter.confirm = Are you sure you want to delete custom filter? message.delete.filter.success = Custom filter {0} deleted Successfully! message.create.filter.success = Custom filter {0} created Successfully! message.update.filter.success = Custom filter updated Successfully! @@ -388,20 +385,16 @@ soft.module.application =Application soft.module.os =OS #Artifact upload -message.error.noFileSelected = No file selected for upload -message.error.noProvidedName = Please provide custom file name message.error.noSwModuleSelected = Please select a Software Module +message.error.multiSwModuleSelected = Please select only one Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : -message.delete.artifact = Are you sure that you want to delete artifact {0} ? -message.duplicate.filename = Duplicate file name +message.delete.artifact = Are you sure you want to delete artifact {0} ? message.swModule.deleted = {0} Software Module(s) deleted +message.error.swModule.notDeleted = Upload is running for Software Module(s) message.upload.failed = Streaming Failed -message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes -message.uploadedfile.aborted = File upload aborted -message.file.not.found = File not found -message.artifact.deleted =Artifact with file {0} deleted successfully -message.abort.upload = Are you sure that you want to abort the upload? +message.uploadedfile.size.exceeded = File size exceeded. Allowed size {0} bytes +message.artifact.deleted = Artifact with file {0} deleted successfully @@ -413,8 +406,6 @@ upload.md5 = MD5 checksum upload.last.modified.date=Last modified date upload.failed = Failed upload.success = Success -upload.caption.add.new.swmodule = Configure New Software Module -upload.caption.delete.swmodule = Configure Delete Software Module upload.swmodule.type = Type upload.artifact.alreadyExists = Artifact will be overridden as the given name already exists upload.size = Size(B) @@ -423,7 +414,6 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -443,12 +433,12 @@ message.software.dist.already.assigned = Software Module {0} is already assigned message.software.dist.type.notallowed = Software Module {0} cannot be assigned, because Distribution {1} does not support the Software Module Type {2} message.software.already.dragged = Software Module {0} was already dragged to this Distribution. message.target.assigned = {0} is assigned to {1} -message.dist.type.delete = {0} Distribution Type(s) deleted successfully. -message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. +message.dist.type.delete = Distribution Type deleted successfully. +message.sw.module.type.delete = Software Module Type deleted successfully. message.dist.type.discard.success = All Distribution Types are discarded successfully ! message.dist.discard.success = All Distributions are discarded successfully ! message.assign.discard.success = All assignments are discarded successfully ! -message.target.ds.assign.success = Assignments saved successfully ! +message.target.ds.assign.success = Assignment saved successfully ! message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists! message.key.missing = Key is missing ! message.value.missing = Value is missing ! @@ -456,10 +446,12 @@ message.metadata.saved = Metadata with key {0} successfully saved ! message.metadata.updated = Metadata with key {0} successfully updated ! message.metadata.duplicate.check = Metadata with key {0} already exists, please enter another value message.metadata.deleted.successfully = Metadata with key {0} successfully deleted ! -message.confirm.delete.metadata = Are you sure that you want to delete metadata with key {0} ? +message.confirm.delete.metadata = Are you sure you want to delete metadata with key {0} ? message.error.notification.ds.target.assigned = Distribution set {0}:{1} is already assigned to targets and cannot be changed # Login view +notification.login.title=Welcome to Bosch IoT Software Provisioning. +notification.login.description=Please login with your Bosch Identity Management credentials. notification.login.failed.title=Login failed! notification.login.failed.description=Login with the given credentials failed. notification.login.failed.credentialsexpired.title=Password Expired! @@ -480,8 +472,8 @@ link.usermanagement.name=User Management # System Configuration View notification.configuration.save.successful=Saved changes notification.configuration.save.notpossible = Saving was not possible, because of invalid user input. -configuration.defaultdistributionset.title=Distribution Set Type -configuration.defaultdistributionset.select.label=Select the default Distribution Set type: +configuration.defaultdistributionset.title=Distribution set type +configuration.defaultdistributionset.select.label=Select the default Distribution set type: configuration.savebutton.tooltip=Save Configurations configuration.cancellbutton.tooltip=Cancel Configurations configuration.authentication.title=Authentication Configuration @@ -520,7 +512,7 @@ header.assigned.ds = Assigned DS header.installed.ds = Installed DS header.target.status = Status header.target.tags = Tags -header.total.targets = Targets +header.total.targets = Targets header.key = Key header.value = Value metadata.targetvisible = Visible for targets @@ -560,14 +552,11 @@ prompt.groups = Groups prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution Set +prompt.distribution.set = Distribution set button.rollout.groups.def.button = Define groups button.rollout.add.group = Add Group caption.configure.rollout = Configure Rollout caption.configure.rollout.groups = Configure Deployment Groups -caption.update.rollout = Update Rollout -caption.create.rollout = Create new Rollout -caption.approve.rollout = Approve Rollout prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -634,5 +623,15 @@ distributionset.not.existsDistribution=Distribution set does not exist. Maybe th distributionsets.not.exists=Distribution sets do not exists. Maybe the sets were deleted. targettag.not.exists=Target tag {0} does not exists. Maybe the target tag was deleted. +caption.entity.target.tag = Target Tag +caption.entity.distribution.tag = Distribution Tag +caption.entity.distribution.type = Distribution set Type +caption.entity.software.module.type = Software Module Type validator.textfield.min.length = Please enter a text consisting of at least one and a maximum of {0} characters. + +caption.entity.delete.action.confirmbox = Confirm Deletion +message.confirm.delete.entity = Are you sure you want to delete {0} {1}{2}? +caption.entity.assign.action.confirmbox = Confirm Assignment +message.confirm.assign.entity = Are you sure you want to assign distribution {0} to {1} {2}? +message.confirm.assign.multiple.entities = Are you sure you want to assign {0} {1} to distribution {2}? diff --git a/hawkbit-ui/src/test/java/org/eclipse/hawkbit/push/SpringSecurityAtmosphereInterceptorTest.java b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/push/SpringSecurityAtmosphereInterceptorTest.java index a1cc4b343..50a5dcc03 100644 --- a/hawkbit-ui/src/test/java/org/eclipse/hawkbit/push/SpringSecurityAtmosphereInterceptorTest.java +++ b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/push/SpringSecurityAtmosphereInterceptorTest.java @@ -26,13 +26,13 @@ import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; +import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Stories; @Features("Unit Tests - Management UI") @Stories("Push Security") @RunWith(MockitoJUnitRunner.class) -// TODO: create description annotations public class SpringSecurityAtmosphereInterceptorTest { @Mock @@ -52,6 +52,7 @@ public class SpringSecurityAtmosphereInterceptorTest { } @Test + @Description("Verify that Security Context is set from Request to thread local when calling inspect") public void inspectRetrievesSetsSecurityContextFromRequestToThreadLocal() { when(atmosphereResourceMock.getRequest()).thenReturn(atmosphereRequestMock); @@ -64,6 +65,7 @@ public class SpringSecurityAtmosphereInterceptorTest { } @Test + @Description("Verify that security Context gets cleared after atmosphere request") public void afterAtmosphereRequestSecurityContextGetsCleared() { SecurityContextHolder.setContext(sessionSecurityContextMock); diff --git a/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadStateTest.java b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadStateTest.java new file mode 100644 index 000000000..be6f7f9db --- /dev/null +++ b/hawkbit-ui/src/test/java/org/eclipse/hawkbit/ui/artifacts/state/ArtifactUploadStateTest.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.artifacts.state; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadId; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress; +import org.eclipse.hawkbit.ui.artifacts.upload.FileUploadProgress.FileUploadStatus; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Unit Tests - Management UI") +@Stories("Upload UI state") +@RunWith(MockitoJUnitRunner.class) +public class ArtifactUploadStateTest { + + @Mock + public SoftwareModuleFilters softwareModuleFilters; + + @Mock + public FileUploadId fileUploadId1; + + @Mock + public FileUploadId fileUploadId2; + + @Mock + public FileUploadId fileUploadId3; + + public FileUploadProgress fileUploadProgressStateFailed; + public FileUploadProgress fileUploadProgressStateSucceeded; + public FileUploadProgress fileUploadProgressStateInProgress; + + private ArtifactUploadState stateUnderTest; + + @Before + public void setupTest() { + stateUnderTest = new ArtifactUploadState(softwareModuleFilters); + } + + @Test + public void isAtLeastOneUploadInProgressReturnsTrueForUploadInProgress() { + simulateUploadInProgressFor(fileUploadId1); + simulateUploadFailedFor(fileUploadId2); + simulateUploadSucceededFor(fileUploadId3); + + assertThat(stateUnderTest.isAtLeastOneUploadInProgress()).isTrue(); + } + + @Test + public void isAtLeastOneUploadInProgressReturnsFalseForFailedAndSuccededUploads() { + simulateUploadFailedFor(fileUploadId1, fileUploadId2); + simulateUploadSucceededFor(fileUploadId3); + + assertThat(stateUnderTest.isAtLeastOneUploadInProgress()).isFalse(); + } + + @Test + public void areAllUploadsFinishedReturnsTrueForFailedAndSuccededUpload() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + simulateUploadSucceededFor(fileUploadId1); + simulateUploadFailedFor(fileUploadId2, fileUploadId3); + + assertThat(stateUnderTest.areAllUploadsFinished()).isTrue(); + } + + @Test + public void areAllUploadsFinishedReturnsFalseForUploadInProgress() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + + assertThat(stateUnderTest.areAllUploadsFinished()).isFalse(); + } + + @Test + public void areAllUploadsFinishedReturnsTrueAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.areAllUploadsFinished()).isTrue(); + } + + @Test + public void isAtLeastOneUploadInProgressReturnsFalseAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.isAtLeastOneUploadInProgress()).isFalse(); + } + + @Test + public void getAllFileUploadIdsFromOverallUploadProcessListReturnsNothingAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.getAllFileUploadIdsFromOverallUploadProcessList()).isEmpty(); + } + + @Test + public void getAllFileUploadProgressValuesFromOverallUploadProcessListReturnsNothingAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.getAllFileUploadProgressValuesFromOverallUploadProcessList()).isEmpty(); + } + + @Test + public void getFilesInFailedStateReturnsNothingAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + simulateUploadFailedFor(fileUploadId1, fileUploadId2, fileUploadId3); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.getFilesInFailedState()).isEmpty(); + } + + @Test + public void isFileInUploadStateReturnsFalseAfterFileStateReset() { + simulateUploadInProgressFor(fileUploadId1); + + stateUnderTest.clearFileStates(); + + assertThat(stateUnderTest.isFileInUploadState(fileUploadId1)).isFalse(); + } + + @Test + public void getAllFileUploadIdsFromOverallUploadProcessListReturnsAllFileIds() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + simulateUploadFailedFor(fileUploadId1); + simulateUploadSucceededFor(fileUploadId2); + + assertThat(stateUnderTest.getAllFileUploadIdsFromOverallUploadProcessList()) + .containsExactlyInAnyOrder(fileUploadId1, fileUploadId2, fileUploadId3); + } + + @Test + public void getFilesInFailedStateReturnsOnlyFailedFileIds() { + simulateUploadInProgressFor(fileUploadId1, fileUploadId2, fileUploadId3); + simulateUploadFailedFor(fileUploadId2); + simulateUploadSucceededFor(fileUploadId3); + + assertThat(stateUnderTest.getFilesInFailedState()).containsOnly(fileUploadId2); + } + + @Test + public void isFileInUploadStateReturnsTrueForFileInProgress() { + simulateUploadInProgressFor(fileUploadId1); + + assertThat(stateUnderTest.isFileInUploadState(fileUploadId1)).isTrue(); + } + + @Test + public void isFileInUploadStateReturnsTrueForFileUploadFailed() { + simulateUploadInProgressFor(fileUploadId1); + simulateUploadFailedFor(fileUploadId1); + + assertThat(stateUnderTest.isFileInUploadState(fileUploadId1)).isTrue(); + } + + @Test + public void isFileInUploadStateReturnsTrueForFileUploadSucceeded() { + simulateUploadInProgressFor(fileUploadId1); + simulateUploadSucceededFor(fileUploadId1); + + assertThat(stateUnderTest.isFileInUploadState(fileUploadId1)).isTrue(); + } + + @Test + public void isFileInUploadStateReturnsFalseForUnknownFileId() { + + assertThat(stateUnderTest.isFileInUploadState(fileUploadId1)).isFalse(); + } + + private void simulateUploadInProgressFor(final FileUploadId... fileUploadIds) { + for (final FileUploadId fileUploadId : fileUploadIds) { + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_IN_PROGRESS); + stateUnderTest.updateFileUploadProgress(fileUploadId, fileUploadProgress); + } + } + + private void simulateUploadSucceededFor(final FileUploadId... fileUploadIds) { + for (final FileUploadId fileUploadId : fileUploadIds) { + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_SUCCESSFUL); + stateUnderTest.updateFileUploadProgress(fileUploadId, fileUploadProgress); + } + } + + private void simulateUploadFailedFor(final FileUploadId... fileUploadIds) { + for (final FileUploadId fileUploadId : fileUploadIds) { + final FileUploadProgress fileUploadProgress = new FileUploadProgress(fileUploadId, + FileUploadStatus.UPLOAD_FAILED); + stateUnderTest.updateFileUploadProgress(fileUploadId, fileUploadProgress); + } + } + +}