Remove footer, expand layout and move functions to other elements (#689)
* Remove process and discard upload buttons; change upload process to only have one upload status window that is displayed immediately when an upload is triggered. * Separation of FileTransferHandler: FileTransferHandler was split into 3 parts. One common part remains in the abstract super class. The other pieces were moved to the upload-specific and the streaming-specific subclasses. * Fix upload process: Fix status visualization in progress window. Move repository transfer to the file upload handler so it can report if the complete upload process succeeded or failed. * Prevent file upload if no software module or more than one is selected. * Added Unit Tests and fixed Sonar findings. * Move upload button from the buttom to the right side of the drag and drop area. * Remove minimize and resize buttons in progress dialog. Remove unused code. * Code cleanup and layout adaptions: Remove unnecessary code and fix layout problems when showing the upload button on the right side of the drag and drop area. * Removed abort functionality for user because of Vaadin bug https://github.com/vaadin/framework/issues/10545 * Fixed Vaadin upload bug by subclassing Upload and overriding necessary methods. * Disable drag-and-drop area in case no OR more than one software module selected. * Enhance /adapt unit tests * Enhance /adapt UI tests Signed-off-by: Markus Block <markus.block@bosch-si.com> * First draw, insert delete button in entity tables * Add shortcuts to cancel/confirm buttons in confirmation dialog * First draw, target/distribution assignment * Entity assignments for tables * Fix table row mark correctly when assigning entities * Mark the right entity in table when deleting an entity * Refactor code for distribution tags on deployment view * Target Tags can be managed with Menu Bar * Refactor classes for managing tags and types for all entities * Disable fields correctly when updating/deleting tags and types * Remove delete and action buttons in the bottom * Delete Metadata column in tables * Redesign tables for tags and types. Show action icon for update/delete * Correct CSS for menubar for tag/type actions * Add confirmation window when deleting tag or type * Remove unused code. Fix style for target tag config menu bar * New abstract classes for target/ds tags * Reorganize package structure tags, set ids for tags * Add total targets count in target table, add close icon for menubar * Add total target label and remove footer styles * MenuBar is displayed when update/delete action is cancelled, finished, or update/delete modus is left * Insert EventHandling for show menuBar/CancelButton * Delete drag & drop criteria where not needed anymore * Fix mandatory field check in DistributionTypeLayout * Fix notification message * Move upload button into drop area * Enhance /adapt unit tests * Enhance /adapt UI tests Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>
This commit is contained in:
committed by
Stefan Behl
parent
bafce18db6
commit
f5f51bfc2c
@@ -202,10 +202,10 @@ public interface TargetManagement {
|
||||
void delete(@NotEmpty Collection<Long> 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
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.eclipse.m2e.core.maven2Builder"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
</launchConfiguration>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_DISABLED_BUILDER" value="org.sonarlint.eclipse.core.sonarlintBuilder"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
</launchConfiguration>
|
||||
@@ -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() }));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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> 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<Long> changedSoftwareModuleIds,
|
||||
final SoftwareModule selectedSoftwareModule) {
|
||||
return changedSoftwareModuleIds.stream().anyMatch(smId -> selectedSoftwareModule.getId().equals(smId));
|
||||
}
|
||||
|
||||
public Table getArtifactDetailsTable() {
|
||||
|
||||
@@ -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<SoftwareModule> {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Long> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, ConfirmationTab> getConfirmationTabs() {
|
||||
final Map<String, ConfirmationTab> 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<Long> 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<CustomFile> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<SoftwareModule> softwareModuleTable;
|
||||
|
||||
private Label softwareModuleType;
|
||||
|
||||
/**
|
||||
* Constructor for SoftwareModuleAddUpdateWindow
|
||||
*
|
||||
@@ -248,7 +251,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent {
|
||||
nameTextField.clear();
|
||||
versionTextField.clear();
|
||||
descTextArea.clear();
|
||||
if (!editSwModule) {
|
||||
typeComboBox.clear();
|
||||
}
|
||||
editSwModule = Boolean.FALSE;
|
||||
}
|
||||
|
||||
@@ -261,7 +266,13 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent {
|
||||
|
||||
formLayout = new FormLayout();
|
||||
formLayout.setCaption(null);
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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<SoftwareModul
|
||||
|
||||
private final UploadViewClientCriterion uploadViewClientCriterion;
|
||||
|
||||
private final SwMetadataPopupLayout swMetadataPopupLayout;
|
||||
|
||||
SoftwareModuleTable(final UIEventBus eventBus, final VaadinMessageSource i18n, final UINotification uiNotification,
|
||||
final ArtifactUploadState artifactUploadState, final SoftwareModuleManagement softwareManagement,
|
||||
final UploadViewClientCriterion uploadViewClientCriterion,
|
||||
final SwMetadataPopupLayout swMetadataPopupLayout) {
|
||||
super(eventBus, i18n, uiNotification);
|
||||
final UploadViewClientCriterion uploadViewClientCriterion, final SpPermissionChecker permChecker) {
|
||||
super(eventBus, i18n, uiNotification, permChecker);
|
||||
this.artifactUploadState = artifactUploadState;
|
||||
this.softwareModuleManagement = softwareManagement;
|
||||
this.uploadViewClientCriterion = uploadViewClientCriterion;
|
||||
this.swMetadataPopupLayout = swMetadataPopupLayout;
|
||||
|
||||
addNewContainerDS();
|
||||
setColumnProperties();
|
||||
@@ -99,17 +90,16 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
final BeanQueryFactory<BaseSwModuleBeanQuery> 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<String, Object> prepareQueryConfigFilters() {
|
||||
final Map<String, Object> 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<SoftwareModul
|
||||
lqc.addContainerProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, String.class, null, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFirstRowSelectedOnLoad() {
|
||||
return artifactUploadState.getSelectedSoftwareModules().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getItemIdToSelect() {
|
||||
return artifactUploadState.getSelectedSoftwareModules().isEmpty() ? null
|
||||
@@ -156,7 +141,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
|
||||
@Override
|
||||
protected void publishSelectedEntityEvent(final SoftwareModule lastSoftwareModule) {
|
||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, lastSoftwareModule));
|
||||
getEventBus().publish(this, new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, lastSoftwareModule));
|
||||
}
|
||||
|
||||
@EventBusListenerMethod(scope = EventScope.UI)
|
||||
@@ -166,7 +151,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
|
||||
@EventBusListenerMethod(scope = EventScope.UI)
|
||||
void onEvent(final UploadArtifactUIEvent event) {
|
||||
if (event == UploadArtifactUIEvent.DELETED_ALL_SOFWARE) {
|
||||
if (event == UploadArtifactUIEvent.DELETED_ALL_SOFTWARE) {
|
||||
UI.getCurrent().access(this::refreshFilter);
|
||||
}
|
||||
}
|
||||
@@ -176,8 +161,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<Long> visibleItemIds = (List<Long>) 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<SoftwareModul
|
||||
super.updateEntity(baseEntity, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCustomGeneratedColumns() {
|
||||
addGeneratedColumn(SPUILabelDefinitions.METADATA_ICON, new ColumnGenerator() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Object generateCell(final Table source, final Object itemId, final Object columnId) {
|
||||
final String nameVersionStr = getNameAndVerion(itemId);
|
||||
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
|
||||
manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId));
|
||||
return manageMetaDataBtn;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableColumn> getTableVisibleColumns() {
|
||||
final List<TableColumn> 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<SoftwareModul
|
||||
artifactUploadState.setNoDataAvilableSoftwareModule(!available);
|
||||
}
|
||||
|
||||
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;
|
||||
@Override
|
||||
protected void handleOkDelete(final List<Long> 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<Long> 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<Long> 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> softwareModule = softwareModuleManagement.get(entityId);
|
||||
if (softwareModule.isPresent()) {
|
||||
return softwareModule.get().getName() + ":" + softwareModule.get().getVersion();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout<SoftwareModul
|
||||
final SwMetadataPopupLayout swMetadataPopupLayout = new SwMetadataPopupLayout(i18n, uiNotification, eventBus,
|
||||
softwareModuleManagement, entityFactory, permChecker);
|
||||
this.softwareModuleTable = new SoftwareModuleTable(eventBus, i18n, uiNotification, artifactUploadState,
|
||||
softwareModuleManagement, uploadViewClientCriterion, swMetadataPopupLayout);
|
||||
softwareModuleManagement, uploadViewClientCriterion, permChecker);
|
||||
|
||||
final SoftwareModuleAddUpdateWindow softwareModuleAddUpdateWindow = new SoftwareModuleAddUpdateWindow(i18n,
|
||||
uiNotification, eventBus, softwareModuleManagement, softwareModuleTypeManagement, entityFactory,
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* 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.common.builder.LabelBuilder;
|
||||
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;
|
||||
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.OptionGroup;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* General Layout for the software module types pop-up window which is provided
|
||||
* on the Distribution and Upload view when creating, updating or deleting a
|
||||
* software module type
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSoftwareModuleTypeLayout extends AbstractTypeLayout<SoftwareModuleType> {
|
||||
|
||||
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<SoftwareModuleType> findEntityByKey() {
|
||||
return softwareModuleTypeManagement.getByKey(getTypeKey().getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SoftwareModuleType> 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<String> optionValues = new ArrayList<>();
|
||||
optionValues.add(singleAssign.getValue());
|
||||
optionValues.add(multiAssign.getValue());
|
||||
assignOptionGroupByValues(optionValues);
|
||||
}
|
||||
|
||||
private void assignOptionGroupByValues(final List<String> 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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<SoftwareModuleType> {
|
||||
|
||||
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<SoftwareModuleType> 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<String> optionValues = new ArrayList<>();
|
||||
optionValues.add(singleAssign.getValue());
|
||||
optionValues.add(multiAssign.getValue());
|
||||
assignOptionGroupByValues(optionValues);
|
||||
}
|
||||
|
||||
private void assignOptionGroupByValues(final List<String> 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<SoftwareModuleType> findEntityByKey() {
|
||||
return softwareModuleTypeManagement.getByKey(typeKey.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<SoftwareModuleType> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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<SoftwareModuleType> 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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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<Long, String> deleteSofwareModules = new HashMap<>();
|
||||
|
||||
private final Set<CustomFile> fileSelected = new HashSet<>();
|
||||
|
||||
private transient Optional<Long> selectedBaseSwModuleId = Optional.empty();
|
||||
|
||||
private final Map<String, SoftwareModule> baseSwModuleList = new HashMap<>();
|
||||
|
||||
private Set<Long> selectedSoftwareModules = Collections.emptySet();
|
||||
|
||||
private boolean swTypeFilterClosed;
|
||||
@@ -60,49 +65,17 @@ public class ArtifactUploadState implements ManagementEntityState, Serializable
|
||||
|
||||
private boolean statusPopupMinimized;
|
||||
|
||||
private boolean uploadCompleted;
|
||||
|
||||
private List<UploadStatusObject> 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<FileUploadId, FileUploadProgress> 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<UploadStatusObject> getUploadedFileStatusList() {
|
||||
return uploadedFileStatusList;
|
||||
}
|
||||
|
||||
public void setUploadedFileStatusList(final List<UploadStatusObject> 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<Long, String> getDeleteSofwareModules() {
|
||||
public Map<Long, String> getDeleteSoftwareModules() {
|
||||
return deleteSofwareModules;
|
||||
}
|
||||
|
||||
public Set<CustomFile> getFileSelected() {
|
||||
return fileSelected;
|
||||
}
|
||||
|
||||
public Optional<Long> getSelectedBaseSwModuleId() {
|
||||
return selectedBaseSwModuleId;
|
||||
}
|
||||
|
||||
public Map<String, SoftwareModule> getBaseSwModuleList() {
|
||||
return baseSwModuleList;
|
||||
}
|
||||
|
||||
public Set<Long> 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<FileUploadId> filesToRemove) {
|
||||
getOverallFilesInUploadProcessMap().keySet().removeAll(filesToRemove);
|
||||
}
|
||||
|
||||
public Set<FileUploadId> getAllFileUploadIdsFromOverallUploadProcessList() {
|
||||
return Collections.unmodifiableSet(getOverallFilesInUploadProcessMap().keySet());
|
||||
}
|
||||
|
||||
public Collection<FileUploadProgress> getAllFileUploadProgressValuesFromOverallUploadProcessList() {
|
||||
return Collections.unmodifiableCollection(getOverallFilesInUploadProcessMap().values());
|
||||
}
|
||||
|
||||
public Set<FileUploadId> 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<FileUploadId, FileUploadProgress> getOverallFilesInUploadProcessMap() {
|
||||
if (overallFilesInUploadProcess == null) {
|
||||
overallFilesInUploadProcess = Maps.newConcurrentMap();
|
||||
}
|
||||
return overallFilesInUploadProcess;
|
||||
}
|
||||
|
||||
private Set<FileUploadId> getFailedUploads() {
|
||||
final Collection<FileUploadProgress> allFileUploadProgressObjects = getOverallFilesInUploadProcessMap()
|
||||
.values();
|
||||
final Set<FileUploadId> failedFileUploads = Sets.newHashSet();
|
||||
for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) {
|
||||
if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_FAILED) {
|
||||
failedFileUploads.add(fileUploadProgress.getFileUploadId());
|
||||
}
|
||||
}
|
||||
return failedFileUploads;
|
||||
}
|
||||
|
||||
private Set<FileUploadId> getSucceededUploads() {
|
||||
final Collection<FileUploadProgress> allFileUploadProgressObjects = getOverallFilesInUploadProcessMap()
|
||||
.values();
|
||||
final Set<FileUploadId> succeededFileUploads = Sets.newHashSet();
|
||||
for (final FileUploadProgress fileUploadProgress : allFileUploadProgressObjects) {
|
||||
if (fileUploadProgress.getFileUploadStatus() == FileUploadStatus.UPLOAD_SUCCESSFUL) {
|
||||
succeededFileUploads.add(fileUploadProgress.getFileUploadId());
|
||||
}
|
||||
}
|
||||
return succeededFileUploads;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import com.vaadin.spring.annotation.SpringComponent;
|
||||
import com.vaadin.spring.annotation.VaadinSessionScope;
|
||||
|
||||
/**
|
||||
* Softwrae module filters.
|
||||
* Software module filters.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<Long> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<UploadStatus> 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<String> 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> 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<Artifact> 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<String> itemIds = (List<String>) 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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") + "<br>"
|
||||
+ 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Long> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 = "</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<String> 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("<br>");
|
||||
}
|
||||
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<String> getDuplicateFileNamesList() {
|
||||
return duplicateFileNamesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update pending action count.
|
||||
*/
|
||||
private void updateActionCount() {
|
||||
if (!artifactUploadState.getFileSelected().isEmpty()) {
|
||||
processBtn.setCaption(SPUILabelDefinitions.PROCESS + "<div class='unread'>"
|
||||
+ 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<CustomFile> 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("<div class='error-count error-count-color'>" + uploadsFailed + HTML_DIV);
|
||||
} else {
|
||||
builder.append("<div class='unread error-count-color'>" + uploadsFailed + HTML_DIV);
|
||||
}
|
||||
}
|
||||
if (uploadsPending != 0) {
|
||||
builder.append("<div class='unread'>" + 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 = "<div class=\"statusIconGreen\">" + FontAwesome.CHECK_CIRCLE.getHtml() + "</div>";
|
||||
break;
|
||||
case STATUS_FAILED:
|
||||
result = "<div class=\"statusIconRed\">" + FontAwesome.EXCLAMATION_CIRCLE.getHtml() + "</div>";
|
||||
break;
|
||||
case STATUS_INPROGRESS:
|
||||
result = "<div class=\"statusIconActive\"></div>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<UploadStatus> 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<UploadStatus> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 = "<div class=\"statusIconGreen\">" + FontAwesome.CHECK_CIRCLE.getHtml() + "</div>";
|
||||
break;
|
||||
case "Failed":
|
||||
result = "<div class=\"statusIconRed\">" + FontAwesome.EXCLAMATION_CIRCLE.getHtml() + "</div>";
|
||||
break;
|
||||
default:
|
||||
result = "<div class=\"statusIconActive\"></div>";
|
||||
}
|
||||
|
||||
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<UploadStatusObject> 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<UploadStatusObject> 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<UploadStatusObject> 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<ColorSelector> 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");
|
||||
|
||||
@@ -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<E extends NamedVersionedEntity
|
||||
final String key = (String) item.getItemProperty(KEY).getValue();
|
||||
|
||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(
|
||||
i18n.getMessage("caption.metadata.delete.action.confirmbox"),
|
||||
i18n.getMessage("message.confirm.delete.metadata", key), i18n.getMessage("button.ok"),
|
||||
i18n.getMessage("button.cancel"), ok -> {
|
||||
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<E extends NamedVersionedEntity
|
||||
|
||||
private Button createAddIcon() {
|
||||
addIcon = SPUIComponentProvider.getButton(UIComponentIdProvider.METADTA_ADD_ICON_ID,
|
||||
i18n.getMessage("button.save"), null, null, false, FontAwesome.PLUS,
|
||||
SPUIButtonStyleSmallNoBorder.class);
|
||||
i18n.getMessage("button.save"), null, null, false, FontAwesome.PLUS, SPUIButtonStyleNoBorder.class);
|
||||
addIcon.addClickListener(event -> onAdd());
|
||||
return addIcon;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
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("<p>%s</p>", question.replaceAll("\n", "<br/>")),
|
||||
ContentMode.HTML);
|
||||
questionLbl.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_QUESTION_LABEL);
|
||||
vLayout.addComponent(questionLbl);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<String, ConfirmationTab> confimrationTabs = getConfirmationTabs();
|
||||
for (final Entry<String, ConfirmationTab> 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 <br>
|
||||
*
|
||||
* @param message
|
||||
* to be added to the consolidated messages.
|
||||
*/
|
||||
public void addToConsolitatedMsg(final String message) {
|
||||
if (consolidatedMessage != null && consolidatedMessage.length() > 0) {
|
||||
consolidatedMessage = consolidatedMessage + "<br>";
|
||||
}
|
||||
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<String, ConfirmationTab> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -34,4 +34,5 @@ public abstract class AbstractNamedVersionedEntityTableDetailsLayout<T extends N
|
||||
return HawkbitCommonUtil.getFormattedNameVersion(getSelectedBaseEntity().getName(),
|
||||
getSelectedBaseEntity().getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ public abstract class AbstractSoftwareModuleDetails
|
||||
protected void onEdit(final ClickEvent event) {
|
||||
final Window addSoftwareModule = softwareModuleAddUpdateWindow
|
||||
.createUpdateSoftwareModuleWindow(getSelectedBaseEntityId());
|
||||
addSoftwareModule.setCaption(getI18n().getMessage("upload.caption.update.swmodule"));
|
||||
addSoftwareModule
|
||||
.setCaption(getI18n().getMessage("caption.update", getI18n().getMessage("caption.software.module")));
|
||||
UI.getCurrent().addWindow(addSoftwareModule);
|
||||
addSoftwareModule.setVisible(Boolean.TRUE);
|
||||
}
|
||||
@@ -91,6 +92,11 @@ public abstract class AbstractSoftwareModuleDetails
|
||||
return UIComponentIdProvider.UPLOAD_SW_MODULE_EDIT_BUTTON;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMetadataButtonId() {
|
||||
return UIComponentIdProvider.UPLOAD_SW_MODULE_METADATA_BUTTON;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultCaption() {
|
||||
return getI18n().getMessage("upload.swModuleTable.header");
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseUIEntityEvent;
|
||||
import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken;
|
||||
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.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
@@ -71,6 +71,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> 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<T extends NamedEntity> 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<T extends NamedEntity> 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<T extends NamedEntity> 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<T extends NamedEntity> 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<T extends NamedEntity> extends
|
||||
|
||||
protected abstract void showMetadata(Button.ClickEvent event);
|
||||
|
||||
public HorizontalLayout getNameEditLayout() {
|
||||
return nameEditLayout;
|
||||
}
|
||||
|
||||
public Button getEditButton() {
|
||||
return editButton;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Object> getVisibleColumnsAsList() {
|
||||
return Arrays.asList(getVisibleColumns());
|
||||
}
|
||||
|
||||
private void deleteColumnIfVisible(final String columnName) {
|
||||
final List<Object> 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,9 +289,60 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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("<div class='unread'>" + count + "</div>");
|
||||
}
|
||||
|
||||
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() + "<div class='unread'>" + newCount + "</div>");
|
||||
} 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();
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<E extends NamedVersionedEntity> extends AbstractTable<E> {
|
||||
|
||||
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<TableColumn> getTableVisibleColumns() {
|
||||
final List<TableColumn> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<E extends NamedEntity> 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<E extends NamedEntity> 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<E extends NamedEntity> 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<E extends NamedEntity> 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<E extends NamedEntity> extends Table impleme
|
||||
|
||||
protected void setColumnProperties() {
|
||||
final List<TableColumn> columnList = getTableVisibleColumns();
|
||||
addDeleteButtonToColumnList(columnList);
|
||||
final List<Object> swColumnIds = new ArrayList<>();
|
||||
for (final TableColumn column : columnList) {
|
||||
setColumnHeader(column.getColumnPropertyId(), column.getColumnHeader());
|
||||
@@ -185,11 +220,9 @@ public abstract class AbstractTable<E extends NamedEntity> 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<TableColumn> columnList) {
|
||||
if (hasDeletePermission()) {
|
||||
columnList.add(new TableColumn(SPUIDefinitions.DELETE_ENTITY, "", 0.0F));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,18 +281,18 @@ public abstract class AbstractTable<E extends NamedEntity> extends Table impleme
|
||||
* the table transferable
|
||||
* @return set of entities id which will deleted
|
||||
*/
|
||||
public Set<Long> getDeletedEntityByTransferable(final TableTransferable transferable) {
|
||||
public Set<Long> getSelectedEntitiesByTransferable(final TableTransferable transferable) {
|
||||
final Set<Long> selectedEntities = getTableValue(this);
|
||||
final Set<Long> 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<E extends NamedEntity> 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<E extends NamedEntity> 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<Long> entitiesToBeDeleted = getEntitiesForDeletion(event);
|
||||
final String confirmationQuestion = createConfirmationQuestionForDeletion(entitiesToBeDeleted);
|
||||
final ConfirmationDialog confirmDialog = createConfirmationWindowForDeletion(entitiesToBeDeleted,
|
||||
confirmationQuestion);
|
||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||
confirmDialog.getWindow().bringToFront();
|
||||
}
|
||||
|
||||
private List<Long> getEntitiesForDeletion(final ClickEvent event) {
|
||||
List<Long> entitiesToBeDeleted;
|
||||
final Long id = getDeleteButtonId(event);
|
||||
final Set<Long> 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<Long> 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<Long> 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<Long> 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<Long> 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<Long> allEntities);
|
||||
|
||||
protected abstract String getEntityType();
|
||||
|
||||
protected abstract Set<Long> getSelectedEntities();
|
||||
|
||||
protected abstract String getEntityId(Object itemId);
|
||||
|
||||
/**
|
||||
* Get Item Id which should be displayed as selected.
|
||||
@@ -368,7 +487,6 @@ public abstract class AbstractTable<E extends NamedEntity> 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<E extends NamedEntity> extends Table impleme
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return columnList;
|
||||
}
|
||||
|
||||
@@ -416,17 +533,16 @@ public abstract class AbstractTable<E extends NamedEntity> 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 Sets.newHashSet(targetItemId);
|
||||
}
|
||||
|
||||
private Set<Long> getDraggedTargetList(final TableTransferable transferable, final Table source) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AbstractTable<NamedEntity> table = (AbstractTable<NamedEntity>) source;
|
||||
return table.getDeletedEntityByTransferable(transferable);
|
||||
return table.getSelectedEntitiesByTransferable(transferable);
|
||||
}
|
||||
|
||||
private boolean validateDropList(final Set<?> droplist) {
|
||||
@@ -499,6 +615,27 @@ public abstract class AbstractTable<E extends NamedEntity> 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<Long> ids) {
|
||||
source.setValue(ids);
|
||||
}
|
||||
|
||||
protected EventBus.UIEventBus getEventBus() {
|
||||
return eventBus;
|
||||
}
|
||||
|
||||
protected VaadinMessageSource getI18n() {
|
||||
return i18n;
|
||||
}
|
||||
|
||||
protected SpPermissionChecker getPermChecker() {
|
||||
return permChecker;
|
||||
}
|
||||
|
||||
protected abstract List<String> hasMissingPermissionsForDrop();
|
||||
|
||||
protected abstract boolean validateDragAndDropWrapper(final DragAndDropWrapper wrapperSource);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 <code>false</code>.
|
||||
*/
|
||||
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 <code>true</code> if the drag operation is starting, otherwise
|
||||
* <code>false</code>
|
||||
*/
|
||||
private boolean isDragStarting(VDragEvent drag) {
|
||||
private boolean isDragStarting(final VDragEvent drag) {
|
||||
boolean result = false;
|
||||
if (!drag.equals(previousDragEvent)) {
|
||||
result = true;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<DistributionSetType> {
|
||||
|
||||
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<DistributionSetType> 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<DistributionSetType> findEntityByName() {
|
||||
return distributionSetTypeManagement.getByName(getTagName().getValue());
|
||||
}
|
||||
|
||||
public DistributionSetTypeSoftwareModuleSelectLayout getTwinTables() {
|
||||
return twinTables;
|
||||
}
|
||||
|
||||
public DistributionSetTypeManagement getDistributionSetTypeManagement() {
|
||||
return distributionSetTypeManagement;
|
||||
}
|
||||
|
||||
public SoftwareModuleTypeManagement getSoftwareModuleTypeManagement() {
|
||||
return softwareModuleTypeManagement;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Long> itemIds = (List<Long>) getTwinTables().getSelectedTable().getItemIds();
|
||||
|
||||
if (typeNameValue != null && typeKeyValue != null && !CollectionUtils.isEmpty(itemIds)) {
|
||||
final List<Long> mandatory = itemIds.stream()
|
||||
.filter(itemId -> DistributionSetTypeSoftwareModuleSelectLayout
|
||||
.isMandatoryModuleType(getTwinTables().getSelectedTable().getItem(itemId)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<Long> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<DistributionSetType> {
|
||||
|
||||
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<DistributionSetType> 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<Long> selectedIds = (Set<Long>) sourceTable.getValue();
|
||||
if (selectedIds == null) {
|
||||
return;
|
||||
}
|
||||
for (final Long id : selectedIds) {
|
||||
addTargetTableData(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeSMType() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Set<Long> selectedIds = (Set<Long>) 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<SoftwareModuleType> 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<Long> itemIds = (List<Long>) selectedTable.getItemIds();
|
||||
if (typeNameValue != null && typeKeyValue != null && !CollectionUtils.isEmpty(itemIds)) {
|
||||
|
||||
final List<Long> mandatory = itemIds.stream()
|
||||
.filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<Long> 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<Long> itemIds = (List<Long>) 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<DistributionSetType> findEntityByKey() {
|
||||
return distributionSetTypeManagement.getByKey(typeKey.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<DistributionSetType> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<SoftwareModuleType> 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<Long> selectedIds = (Set<Long>) 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<Long> selectedIds = (Set<Long>) 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<DistributionSetType> 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<Long> itemIds = (List<Long>) 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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<DistributionSetType> 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<Distribution
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DistributionSetTable.class);
|
||||
|
||||
private final SpPermissionChecker permissionChecker;
|
||||
|
||||
private final ManageDistUIState manageDistUIState;
|
||||
@@ -93,22 +85,19 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
|
||||
private final transient TargetManagement targetManagement;
|
||||
|
||||
private final DsMetadataPopupLayout dsMetadataPopupLayout;
|
||||
|
||||
DistributionSetTable(final UIEventBus eventBus, final VaadinMessageSource i18n, final UINotification notification,
|
||||
final SpPermissionChecker permissionChecker, final ManageDistUIState manageDistUIState,
|
||||
final DistributionSetManagement distributionSetManagement,
|
||||
final SoftwareModuleManagement softwareManagement,
|
||||
final DistributionsViewClientCriterion distributionsViewClientCriterion,
|
||||
final TargetManagement targetManagement, final DsMetadataPopupLayout dsMetadataPopupLayout) {
|
||||
super(eventBus, i18n, notification);
|
||||
final TargetManagement targetManagement) {
|
||||
super(eventBus, i18n, notification, permissionChecker);
|
||||
this.permissionChecker = permissionChecker;
|
||||
this.manageDistUIState = manageDistUIState;
|
||||
this.distributionSetManagement = distributionSetManagement;
|
||||
this.softwareModuleManagement = softwareManagement;
|
||||
this.distributionsViewClientCriterion = distributionsViewClientCriterion;
|
||||
this.targetManagement = targetManagement;
|
||||
this.dsMetadataPopupLayout = dsMetadataPopupLayout;
|
||||
addTableStyleGenerator();
|
||||
addNewContainerDS();
|
||||
setColumnProperties();
|
||||
@@ -127,7 +116,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
manageDistUIState.getLastSelectedDistribution()
|
||||
.ifPresent(lastSelectedDsIdName -> 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<Distribution
|
||||
Boolean.class, null, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isFirstRowSelectedOnLoad() {
|
||||
return manageDistUIState.getSelectedDistributions().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getItemIdToSelect() {
|
||||
return isFirstRowSelectedOnLoad() ? null : manageDistUIState.getSelectedDistributions();
|
||||
return manageDistUIState.getSelectedDistributions().isEmpty() ? null
|
||||
: manageDistUIState.getSelectedDistributions();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,12 +180,12 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
|
||||
@Override
|
||||
protected void afterEntityIsSelected() {
|
||||
eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION);
|
||||
getEventBus().publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishSelectedEntityEvent(final DistributionSet distributionSet) {
|
||||
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, distributionSet));
|
||||
getEventBus().publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, distributionSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,13 +202,14 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
protected void onDropEventFromTable(final DragAndDropEvent event) {
|
||||
final TableTransferable transferable = (TableTransferable) event.getTransferable();
|
||||
final AbstractTable<?> source = (AbstractTable<?>) transferable.getSourceComponent();
|
||||
final Set<Long> softwareModulesIdList = source.getDeletedEntityByTransferable(transferable);
|
||||
final Set<Long> 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<Distribution
|
||||
protected boolean isDropValid(final DragAndDropEvent dragEvent) {
|
||||
final Component compsource = dragEvent.getTransferable().getSourceComponent();
|
||||
if (!(compsource instanceof Table)) {
|
||||
notification.displayValidationError(i18n.getMessage(ACTION_NOT_ALLOWED_MSG));
|
||||
getNotification().displayValidationError(getI18n().getMessage(ACTION_NOT_ALLOWED_MSG));
|
||||
return false;
|
||||
}
|
||||
return super.isDropValid(dragEvent);
|
||||
}
|
||||
|
||||
private void handleDropEvent(final Table source, final Set<Long> softwareModulesIdList, final Object distId) {
|
||||
final Optional<DistributionSet> distributionSet = distributionSetManagement.get((Long) distId);
|
||||
|
||||
private void assignSwmToDs(final Table source, final Set<Long> softwareModulesIdList, final long distId) {
|
||||
final Optional<DistributionSet> distributionSet = distributionSetManagement.get(distId);
|
||||
distributionSet.ifPresent(set -> {
|
||||
final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(set);
|
||||
selectDroppedEntities(distributionSetIdName.getId());
|
||||
final HashMap<Long, HashSet<SoftwareModuleIdName>> map = createAssignmentMap(distributionSetIdName);
|
||||
handleSoftwareModulesForAssignment(source, softwareModulesIdList, distId, map);
|
||||
final HashSet<SoftwareModuleIdName> 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<Long, HashSet<SoftwareModuleIdName>> createAssignmentMap(
|
||||
final DistributionSetIdName distributionSetIdName) {
|
||||
final HashMap<Long, HashSet<SoftwareModuleIdName>> 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<Long> softwareModulesIdList,
|
||||
final long distId, final HashMap<Long, HashSet<SoftwareModuleIdName>> 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<Distribution
|
||||
|
||||
final Optional<SoftwareModule> 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<SoftwareModuleIdName> 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<Distribution
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDropedDetails(final DistributionSetIdName distributionSetIdName,
|
||||
final HashSet<SoftwareModuleIdName> 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<Long> softIds = softIdNameSet.stream().map(softIdName -> softIdName.getId())
|
||||
.collect(Collectors.toList());
|
||||
distributionSetManagement.assignSoftwareModules(distIdName.getId(), softIds);
|
||||
});
|
||||
|
||||
int count = 0;
|
||||
for (final Entry<DistributionSetIdName, HashSet<SoftwareModuleIdName>> 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<Distribution
|
||||
}
|
||||
|
||||
if (distributionSetManagement.isInUse(ds.get().getId())) {
|
||||
notification.displayValidationError(i18n.getMessage("message.error.notification.ds.target.assigned",
|
||||
ds.get().getName(), ds.get().getVersion()));
|
||||
getNotification().displayValidationError(getI18n().getMessage(
|
||||
"message.error.notification.ds.target.assigned", ds.get().getName(), ds.get().getVersion()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -340,14 +377,14 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
private boolean validateSoftwareModule(final SoftwareModule sm, final DistributionSet ds) {
|
||||
if (targetManagement.countByFilters(null, null, null, ds.getId(), Boolean.FALSE, new String[] {}) > 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<Distribution
|
||||
|
||||
if (!ds.getType().containsModuleType(sm.getType())) {
|
||||
/* Invalid type of the software module */
|
||||
notification.displayValidationError(i18n.getMessage("message.software.dist.type.notallowed",
|
||||
getNotification().displayValidationError(getI18n().getMessage("message.software.dist.type.notallowed",
|
||||
HawkbitCommonUtil.concatStrings(":", sm.getName(), sm.getVersion()),
|
||||
HawkbitCommonUtil.concatStrings(":", ds.getName(), ds.getVersion()), sm.getType().getName()));
|
||||
return false;
|
||||
@@ -372,7 +409,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
||||
final Set<SoftwareModuleIdName> 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<Distribution
|
||||
manageDistUIState.setNoDataAvailableDist(!available);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCustomGeneratedColumns() {
|
||||
addGeneratedColumn(SPUILabelDefinitions.METADATA_ICON, new ColumnGenerator() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Object generateCell(final Table source, final Object itemId, final Object columnId) {
|
||||
final String nameVersionStr = getNameAndVerion(itemId);
|
||||
final Button manageMetaDataBtn = createManageMetadataButton(nameVersionStr);
|
||||
manageMetaDataBtn.addClickListener(event -> showMetadataDetails((Long) itemId));
|
||||
return manageMetaDataBtn;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<TableColumn> getTableVisibleColumns() {
|
||||
final List<TableColumn> 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<Long> 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<Long> 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<DistributionSet> distribution = distributionSetManagement.get(entityId);
|
||||
if (distribution.isPresent()) {
|
||||
return distribution.get().getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,17 +43,17 @@ public class DistributionSetTableLayout extends AbstractTableLayout<Distribution
|
||||
final DistributionsViewClientCriterion distributionsViewClientCriterion,
|
||||
final SystemManagement systemManagement) {
|
||||
|
||||
final DsMetadataPopupLayout popupLayout = new DsMetadataPopupLayout(i18n, uiNotification, eventBus,
|
||||
distributionSetManagement, entityFactory, permissionChecker);
|
||||
|
||||
this.distributionSetTable = new DistributionSetTable(eventBus, i18n, uiNotification, permissionChecker,
|
||||
manageDistUIState, distributionSetManagement, softwareManagement, distributionsViewClientCriterion,
|
||||
targetManagement, popupLayout);
|
||||
targetManagement);
|
||||
|
||||
final DistributionAddUpdateWindowLayout distributionAddUpdateWindowLayout = new DistributionAddUpdateWindowLayout(
|
||||
i18n, uiNotification, eventBus, distributionSetManagement, distributionSetTypeManagement,
|
||||
systemManagement, entityFactory, distributionSetTable);
|
||||
|
||||
final DsMetadataPopupLayout popupLayout = new DsMetadataPopupLayout(i18n, uiNotification, eventBus,
|
||||
distributionSetManagement, entityFactory, permissionChecker);
|
||||
|
||||
super.init(
|
||||
new DistributionSetTableHeader(i18n, permissionChecker, eventBus, manageDistUIState,
|
||||
distributionAddUpdateWindowLayout),
|
||||
|
||||
@@ -38,13 +38,14 @@ import org.vaadin.addons.lazyquerycontainer.QueryDefinition;
|
||||
*/
|
||||
public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
||||
|
||||
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<DistributionSet> firstPageDistributionSets;
|
||||
|
||||
private DistributionSetType distributionSetType;
|
||||
private transient DistributionSetType distributionSetType;
|
||||
private Boolean dsComplete;
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user