Fix xss vulnerability (#924)
* Fix XSS vulnerability for Distribution Set and Software Module field * Fix XSS vulnerability for Artifact Details of header in Upload view * Fix XSS vulnerability in Distribution View Software Module box show artifact details window and fix SonarQube issue * Fix XSS vulnerability in Upload View Software Module field manage metadata * Fix XSS vulnerability for Notifications when creating or deleting new or existing Distributions or Software Modules plus adapting error notifications when trying to duplicate * Fix XSS vulnerability for Distributions View when assigning sm to dist confirmation popup text * Fix XSS vulnerability for Distributions View modules tab of distribution value of SoftwareModule * Fix XSS vulnerability for Deployment View assigned tab of target which has risky distribution assigned * Fix XSS vulnerability in Deployment view action history (of) field and eliminate bugs * Fix XSS vulnerability bug in Deployment View Action history of field * Fix XSS vulnerability for Distributions View Module tab as it rendered tool tip * Fix XSS vulnerability formatting * Invented some IDs to ease testing regarding XSS vulnerability * Fix XSS peer review findings * Fix XSS vulnerability for Distribution Set and Software Module field * Resolve merge conflicts Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>
This commit is contained in:
@@ -24,7 +24,6 @@ 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.common.ConfirmationDialog;
|
||||
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;
|
||||
@@ -48,7 +47,6 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
@@ -91,8 +89,12 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
|
||||
private final UINotification uINotification;
|
||||
|
||||
private Label prefixTitleOfArtifactDetails;
|
||||
|
||||
private Label titleOfArtifactDetails;
|
||||
|
||||
private HorizontalLayout headerCaptionLayout;
|
||||
|
||||
private SPUIButton maxMinButton;
|
||||
|
||||
private Table artifactDetailsTable;
|
||||
@@ -140,7 +142,7 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
labelSoftwareModule = HawkbitCommonUtil.getFormattedNameVersion(selectedSoftwareModule.get().getName(),
|
||||
selectedSoftwareModule.get().getVersion());
|
||||
}
|
||||
createComponents(labelSoftwareModule);
|
||||
createComponents();
|
||||
buildLayout();
|
||||
eventBus.subscribe(this);
|
||||
|
||||
@@ -162,12 +164,36 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void createComponents(final String labelSoftwareModule) {
|
||||
titleOfArtifactDetails = new LabelBuilder().id(UIComponentIdProvider.ARTIFACT_DETAILS_HEADER_LABEL_ID)
|
||||
.name(HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelSoftwareModule, i18n)).buildCaptionLabel();
|
||||
titleOfArtifactDetails.setContentMode(ContentMode.HTML);
|
||||
private void createComponents() {
|
||||
prefixTitleOfArtifactDetails = new Label();
|
||||
prefixTitleOfArtifactDetails.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
prefixTitleOfArtifactDetails.addStyleName(ValoTheme.LABEL_BOLD);
|
||||
prefixTitleOfArtifactDetails.setSizeUndefined();
|
||||
|
||||
titleOfArtifactDetails = new Label();
|
||||
titleOfArtifactDetails.setId(UIComponentIdProvider.ARTIFACT_DETAILS_HEADER_LABEL_ID);
|
||||
titleOfArtifactDetails.setSizeFull();
|
||||
titleOfArtifactDetails.setImmediate(true);
|
||||
titleOfArtifactDetails.setWidth("100%");
|
||||
titleOfArtifactDetails.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
titleOfArtifactDetails.addStyleName("text-bold");
|
||||
titleOfArtifactDetails.addStyleName("text-cut");
|
||||
titleOfArtifactDetails.addStyleName("header-caption-right");
|
||||
|
||||
headerCaptionLayout = new HorizontalLayout();
|
||||
headerCaptionLayout.setMargin(false);
|
||||
headerCaptionLayout.setSpacing(true);
|
||||
headerCaptionLayout.setSizeFull();
|
||||
headerCaptionLayout.addStyleName("header-caption");
|
||||
|
||||
headerCaptionLayout.addComponent(prefixTitleOfArtifactDetails);
|
||||
headerCaptionLayout.setComponentAlignment(prefixTitleOfArtifactDetails, Alignment.TOP_LEFT);
|
||||
headerCaptionLayout.setExpandRatio(prefixTitleOfArtifactDetails, 0.0F);
|
||||
|
||||
headerCaptionLayout.addComponent(titleOfArtifactDetails);
|
||||
headerCaptionLayout.setComponentAlignment(titleOfArtifactDetails, Alignment.TOP_LEFT);
|
||||
headerCaptionLayout.setExpandRatio(titleOfArtifactDetails, 1.0F);
|
||||
|
||||
maxMinButton = createMaxMinButton();
|
||||
|
||||
artifactDetailsTable = createArtifactDetailsTable();
|
||||
@@ -199,10 +225,10 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
header.setSizeFull();
|
||||
header.setHeightUndefined();
|
||||
header.setImmediate(true);
|
||||
header.addComponents(titleOfArtifactDetails, maxMinButton);
|
||||
header.setComponentAlignment(titleOfArtifactDetails, Alignment.TOP_LEFT);
|
||||
header.addComponents(headerCaptionLayout, maxMinButton);
|
||||
header.setComponentAlignment(headerCaptionLayout, Alignment.TOP_LEFT);
|
||||
header.setComponentAlignment(maxMinButton, Alignment.TOP_RIGHT);
|
||||
header.setExpandRatio(titleOfArtifactDetails, 1.0F);
|
||||
header.setExpandRatio(headerCaptionLayout, 1.0F);
|
||||
|
||||
setSizeFull();
|
||||
setImmediate(true);
|
||||
@@ -426,12 +452,14 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
|
||||
private void populateArtifactDetails(final Long baseSwModuleId, final String swModuleName) {
|
||||
if (!readOnly) {
|
||||
if (StringUtils.isEmpty(swModuleName)) {
|
||||
setTitleOfLayoutHeader();
|
||||
|
||||
if (StringUtils.hasText(swModuleName)) {
|
||||
prefixTitleOfArtifactDetails.setValue(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS_OF));
|
||||
titleOfArtifactDetails.setValue(swModuleName);
|
||||
} else {
|
||||
titleOfArtifactDetails.setValue(HawkbitCommonUtil.getArtifactoryDetailsLabelId(swModuleName, i18n));
|
||||
titleOfArtifactDetails.setContentMode(ContentMode.HTML);
|
||||
setTitleOfLayoutHeader();
|
||||
}
|
||||
|
||||
}
|
||||
final Map<String, Object> queryConfiguration;
|
||||
if (baseSwModuleId != null) {
|
||||
@@ -452,8 +480,8 @@ public class ArtifactDetailsLayout extends VerticalLayout {
|
||||
* Set title of artifact details header layout.
|
||||
*/
|
||||
private void setTitleOfLayoutHeader() {
|
||||
titleOfArtifactDetails.setValue(HawkbitCommonUtil.getArtifactoryDetailsLabelId("", i18n));
|
||||
titleOfArtifactDetails.setContentMode(ContentMode.HTML);
|
||||
prefixTitleOfArtifactDetails.setValue(i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS));
|
||||
titleOfArtifactDetails.setValue("");
|
||||
}
|
||||
|
||||
@EventBusListenerMethod(scope = EventScope.UI)
|
||||
|
||||
@@ -22,7 +22,6 @@ 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.SPUIButtonStyleNoBorder;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
@@ -131,10 +130,15 @@ public abstract class AbstractMetadataPopupLayout<E extends NamedEntity, M exten
|
||||
public CommonDialogWindow getWindow(final E entity, final String metaDatakey) {
|
||||
selectedEntity = entity;
|
||||
|
||||
metadataWindow = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).caption(getMetadataCaption())
|
||||
.content(this).cancelButtonClickListener(event -> onCancel())
|
||||
.id(UIComponentIdProvider.METADATA_POPUP_ID).layout(mainLayout).i18n(i18n)
|
||||
.saveDialogCloseListener(new SaveOnDialogCloseListener()).buildCommonDialogWindow();
|
||||
metadataWindow = new WindowBuilder(SPUIDefinitions.CREATE_UPDATE_WINDOW).content(this)
|
||||
.cancelButtonClickListener(event -> onCancel()).id(UIComponentIdProvider.METADATA_POPUP_ID)
|
||||
.layout(mainLayout).i18n(i18n).saveDialogCloseListener(new SaveOnDialogCloseListener())
|
||||
.buildCommonDialogWindow();
|
||||
|
||||
metadataWindow.setCaptionAsHtml(false);
|
||||
metadataWindow.setAssistivePrefix(i18n.getMessage("caption.metadata.popup") + " " + "<b>");
|
||||
metadataWindow.setCaption(getElementTitle());
|
||||
metadataWindow.setAssistivePostfix("</b>");
|
||||
|
||||
metadataWindow.setHeight(550, Unit.PIXELS);
|
||||
metadataWindow.setWidth(800, Unit.PIXELS);
|
||||
@@ -431,14 +435,6 @@ public abstract class AbstractMetadataPopupLayout<E extends NamedEntity, M exten
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getMetadataCaption() {
|
||||
final StringBuilder caption = new StringBuilder();
|
||||
caption.append(HawkbitCommonUtil.DIV_DESCRIPTION_START + i18n.getMessage("caption.metadata.popup") + " "
|
||||
+ HawkbitCommonUtil.getBoldHTMLText(getElementTitle()));
|
||||
caption.append(HawkbitCommonUtil.DIV_DESCRIPTION_END);
|
||||
return caption.toString();
|
||||
}
|
||||
|
||||
protected String getElementTitle() {
|
||||
return getSelectedEntity().getName();
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
* @param callback
|
||||
* the callback.
|
||||
* @param tab
|
||||
* ConfirmationTab which contains more information about the
|
||||
* action which has to be confirmed, e.g. maintenance window
|
||||
* 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
|
||||
*/
|
||||
@@ -71,7 +71,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -90,7 +90,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -111,7 +111,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -125,8 +125,8 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
* @param id
|
||||
* the id of the confirmation dialog
|
||||
* @param mapCloseToCancel
|
||||
* Flag indicating whether or not the close event on the
|
||||
* enclosing window should be mapped to a cancel event.
|
||||
* Flag indicating whether or not the close event on the enclosing
|
||||
* window should be mapped to a cancel event.
|
||||
*/
|
||||
public ConfirmationDialog(final String caption, final String question, final String okLabel,
|
||||
final String cancelLabel, final ConfirmationDialogCallback callback, final String id,
|
||||
@@ -136,7 +136,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -157,7 +157,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -173,8 +173,8 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
* @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
|
||||
* 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,
|
||||
@@ -185,7 +185,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
|
||||
/**
|
||||
* Constructor for configuring confirmation dialog.
|
||||
*
|
||||
*
|
||||
* @param caption
|
||||
* the dialog caption.
|
||||
* @param question
|
||||
@@ -201,11 +201,11 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
* @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
|
||||
* ConfirmationTab which contains more information about the action
|
||||
* which has to be confirmed, e.g. maintenance window
|
||||
* @param mapCloseToCancel
|
||||
* Flag indicating whether or not the close event on the
|
||||
* enclosing window should be mapped to a cancel event.
|
||||
* Flag indicating whether or not the close event on the enclosing
|
||||
* window should be mapped to a cancel event.
|
||||
*/
|
||||
public ConfirmationDialog(final String caption, final String question, final String okLabel,
|
||||
final String cancelLabel, final ConfirmationDialogCallback callback, final Resource icon, final String id,
|
||||
@@ -253,9 +253,9 @@ public class ConfirmationDialog implements Button.ClickListener {
|
||||
}
|
||||
|
||||
private static Label createConfirmationQuestion(final String question) {
|
||||
final Label questionLbl = new Label(String.format("<p>%s</p>", question.replaceAll("\n", "<br/>")),
|
||||
ContentMode.HTML);
|
||||
final Label questionLbl = new Label(question, ContentMode.TEXT);
|
||||
questionLbl.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_QUESTION_LABEL);
|
||||
|
||||
return questionLbl;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.common.detailslayout;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
import org.eclipse.hawkbit.ui.SpPermissionChecker;
|
||||
import org.eclipse.hawkbit.ui.common.builder.LabelBuilder;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.common.table.BaseUIEntityEvent;
|
||||
import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken;
|
||||
@@ -26,7 +25,6 @@ import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
import org.vaadin.spring.events.EventBus.UIEventBus;
|
||||
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
@@ -34,6 +32,7 @@ import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.TabSheet;
|
||||
import com.vaadin.ui.UI;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Abstract Layout to show the entity details.
|
||||
@@ -50,7 +49,9 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
|
||||
private T selectedBaseEntity;
|
||||
|
||||
private Label caption;
|
||||
private Label captionPrefix;
|
||||
|
||||
private Label captionNameVersion;
|
||||
|
||||
private Button editButton;
|
||||
|
||||
@@ -91,8 +92,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* false) if the view does not contain any listener to avoid Vaadin blowing up
|
||||
* our logs with warnings.
|
||||
*/
|
||||
protected boolean doSubscribeToEventBus() {
|
||||
return true;
|
||||
@@ -122,7 +123,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
|
||||
/**
|
||||
* Default implementation to handle an entity event.
|
||||
*
|
||||
*
|
||||
* @param baseEntityEvent
|
||||
* the event
|
||||
*/
|
||||
@@ -139,7 +140,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
}
|
||||
|
||||
protected void setName(final String headerCaption, final String value) {
|
||||
caption.setValue(HawkbitCommonUtil.getSoftwareModuleName(headerCaption, value));
|
||||
captionPrefix.setValue(headerCaption + " : ");
|
||||
captionNameVersion.setValue(HawkbitCommonUtil.getFormattedName(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,8 +178,8 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
descriptionLayout.removeAllComponents();
|
||||
final Label descLabel = SPUIComponentProvider.createNameValueLabel("", description == null ? "" : description);
|
||||
/**
|
||||
* By default text will be truncated based on layout width. So removing
|
||||
* it as we need full description.
|
||||
* By default text will be truncated based on layout width. So removing it as we
|
||||
* need full description.
|
||||
*/
|
||||
descLabel.removeStyleName("label-style");
|
||||
descLabel.setId(UIComponentIdProvider.DETAILS_DESCRIPTION_LABEL_ID);
|
||||
@@ -213,10 +215,20 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
}
|
||||
|
||||
protected void createComponents() {
|
||||
caption = createHeaderCaption();
|
||||
caption.setImmediate(true);
|
||||
caption.setContentMode(ContentMode.HTML);
|
||||
caption.setId(getDetailsHeaderCaptionId());
|
||||
captionPrefix = new Label(getDefaultCaption());
|
||||
captionPrefix.setImmediate(true);
|
||||
captionPrefix.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
captionPrefix.addStyleName(ValoTheme.LABEL_BOLD);
|
||||
captionPrefix.setSizeUndefined();
|
||||
|
||||
captionNameVersion = new Label();
|
||||
captionNameVersion.setImmediate(true);
|
||||
captionNameVersion.setId(getDetailsHeaderCaptionId());
|
||||
captionNameVersion.setWidth("100%");
|
||||
captionNameVersion.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
captionNameVersion.addStyleName("text-bold");
|
||||
captionNameVersion.addStyleName("text-cut");
|
||||
captionNameVersion.addStyleName("header-caption-right");
|
||||
|
||||
editButton = SPUIComponentProvider.getButton("", "", i18n.getMessage(UIMessageIdProvider.TOOLTIP_UPDATE), null,
|
||||
false, FontAwesome.PENCIL_SQUARE_O, SPUIButtonStyleNoBorder.class);
|
||||
@@ -242,16 +254,31 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
|
||||
protected void buildLayout() {
|
||||
nameEditLayout = new HorizontalLayout();
|
||||
|
||||
final HorizontalLayout headerCaptionLayout = new HorizontalLayout();
|
||||
headerCaptionLayout.setMargin(false);
|
||||
headerCaptionLayout.setSpacing(true);
|
||||
headerCaptionLayout.setSizeFull();
|
||||
headerCaptionLayout.addStyleName("header-caption");
|
||||
|
||||
headerCaptionLayout.addComponent(captionPrefix);
|
||||
headerCaptionLayout.setComponentAlignment(captionPrefix, Alignment.TOP_LEFT);
|
||||
headerCaptionLayout.setExpandRatio(captionPrefix, 0.0F);
|
||||
|
||||
headerCaptionLayout.addComponent(captionNameVersion);
|
||||
headerCaptionLayout.setComponentAlignment(captionNameVersion, Alignment.TOP_LEFT);
|
||||
headerCaptionLayout.setExpandRatio(captionNameVersion, 1.0F);
|
||||
|
||||
nameEditLayout.setWidth(100.0F, Unit.PERCENTAGE);
|
||||
nameEditLayout.addComponent(caption);
|
||||
nameEditLayout.setComponentAlignment(caption, Alignment.TOP_LEFT);
|
||||
nameEditLayout.addComponents(headerCaptionLayout);
|
||||
nameEditLayout.setComponentAlignment(headerCaptionLayout, Alignment.TOP_LEFT);
|
||||
if (hasEditPermission()) {
|
||||
nameEditLayout.addComponent(editButton);
|
||||
nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT);
|
||||
nameEditLayout.addComponent(manageMetadataBtn);
|
||||
nameEditLayout.setComponentAlignment(manageMetadataBtn, Alignment.TOP_RIGHT);
|
||||
}
|
||||
nameEditLayout.setExpandRatio(caption, 1.0F);
|
||||
nameEditLayout.setExpandRatio(headerCaptionLayout, 1.0F);
|
||||
nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
||||
|
||||
addComponent(nameEditLayout);
|
||||
@@ -264,13 +291,9 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
addStyleName(SPUIStyleDefinitions.WIDGET_STYLE);
|
||||
}
|
||||
|
||||
private Label createHeaderCaption() {
|
||||
return new LabelBuilder().name(getDefaultCaption()).buildCaptionLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is no data in table (i.e. no row selected), then disable the
|
||||
* edit button. If row is selected, enable edit button.
|
||||
* If there is no data in table (i.e. no row selected), then disable the edit
|
||||
* button. If row is selected, enable edit button.
|
||||
*/
|
||||
protected void populateData(final T selectedBaseEntity) {
|
||||
this.selectedBaseEntity = selectedBaseEntity;
|
||||
@@ -307,7 +330,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
||||
protected abstract void populateMetadataDetails();
|
||||
|
||||
/**
|
||||
* Default caption of header to be displayed when no data row selected in
|
||||
* Default captionPrefix of header to be displayed when no data row selected in
|
||||
* table.
|
||||
*
|
||||
* @return String
|
||||
|
||||
@@ -79,8 +79,8 @@ public class SoftwareModuleDetailsTable extends Table {
|
||||
* @param i18n
|
||||
* I18N
|
||||
* @param isUnassignSoftModAllowed
|
||||
* boolean flag to check for unassign functionality allowed for
|
||||
* the view.
|
||||
* boolean flag to check for unassign functionality allowed for the
|
||||
* view.
|
||||
* @param distributionSetManagement
|
||||
* DistributionSetManagement
|
||||
* @param permissionChecker
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
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.SPUIButtonStyleNoBorder;
|
||||
@@ -16,13 +15,14 @@ import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.VerticalLayout;
|
||||
import com.vaadin.ui.themes.ValoTheme;
|
||||
|
||||
/**
|
||||
* Abstract grid header placed on top of a grid.
|
||||
@@ -34,6 +34,8 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
|
||||
private final String titleText;
|
||||
private Label title;
|
||||
private Label prefixText;
|
||||
private HorizontalLayout prefixWithTitle;
|
||||
private HorizontalLayout titleLayout;
|
||||
private transient AbstractHeaderMaximizeSupport maximizeSupport;
|
||||
|
||||
@@ -67,24 +69,49 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
* @return this DefaultGridHeader in order to allow method chaining
|
||||
*/
|
||||
public DefaultGridHeader init() {
|
||||
buildTitleLabel();
|
||||
buildTitleHorizontalLayout();
|
||||
buildTitleLayout();
|
||||
buildComponent();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the title label.
|
||||
* Builds the title HorizontalLayout containing two labels.
|
||||
*
|
||||
* @return title-label
|
||||
* @return title as HorizontalLayout
|
||||
*/
|
||||
protected Label buildTitleLabel() {
|
||||
// create default title - even shown when no data is available
|
||||
title = new LabelBuilder().name(titleText).buildCaptionLabel();
|
||||
title.setImmediate(true);
|
||||
title.setContentMode(ContentMode.HTML);
|
||||
protected HorizontalLayout buildTitleHorizontalLayout() {
|
||||
|
||||
return title;
|
||||
prefixText = new Label();
|
||||
prefixText.setValue(titleText);
|
||||
prefixText.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
prefixText.addStyleName(ValoTheme.LABEL_BOLD);
|
||||
prefixText.setSizeUndefined();
|
||||
|
||||
title = new Label();
|
||||
title.setSizeFull();
|
||||
title.setImmediate(true);
|
||||
title.setWidth("100%");
|
||||
title.addStyleName(ValoTheme.LABEL_SMALL);
|
||||
title.addStyleName("text-bold");
|
||||
title.addStyleName("text-cut");
|
||||
title.addStyleName("header-caption-right");
|
||||
|
||||
prefixWithTitle = new HorizontalLayout();
|
||||
prefixWithTitle.setMargin(false);
|
||||
prefixWithTitle.setSpacing(true);
|
||||
prefixWithTitle.setSizeFull();
|
||||
prefixWithTitle.addStyleName("header-caption");
|
||||
|
||||
prefixWithTitle.addComponent(prefixText);
|
||||
prefixWithTitle.setComponentAlignment(prefixText, Alignment.TOP_LEFT);
|
||||
prefixWithTitle.setExpandRatio(prefixText, 0.0F);
|
||||
|
||||
prefixWithTitle.addComponent(title);
|
||||
prefixWithTitle.setComponentAlignment(title, Alignment.TOP_LEFT);
|
||||
prefixWithTitle.setExpandRatio(title, 1.0F);
|
||||
|
||||
return prefixWithTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,9 +125,9 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
titleLayout.setSpacing(false);
|
||||
titleLayout.setMargin(false);
|
||||
titleLayout.setSizeFull();
|
||||
titleLayout.addComponent(title);
|
||||
titleLayout.setComponentAlignment(title, Alignment.TOP_LEFT);
|
||||
titleLayout.setExpandRatio(title, 0.8F);
|
||||
titleLayout.addComponent(prefixWithTitle);
|
||||
titleLayout.setComponentAlignment(prefixWithTitle, Alignment.TOP_LEFT);
|
||||
titleLayout.setExpandRatio(prefixWithTitle, 0.8F);
|
||||
|
||||
if (hasHeaderMaximizeSupport()) {
|
||||
titleLayout.addComponents(getHeaderMaximizeSupport().maxMinButton);
|
||||
@@ -125,12 +152,12 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables maximize-support for the header by setting a
|
||||
* HeaderMaximizeSupport implementation.
|
||||
* Enables maximize-support for the header by setting a HeaderMaximizeSupport
|
||||
* implementation.
|
||||
*
|
||||
* @param maximizeSupport
|
||||
* encapsulates layout of min-max-button and behavior for
|
||||
* minimize and maximize.
|
||||
* encapsulates layout of min-max-button and behavior for minimize
|
||||
* and maximize.
|
||||
*/
|
||||
public void setHeaderMaximizeSupport(final AbstractHeaderMaximizeSupport maximizeSupport) {
|
||||
this.maximizeSupport = maximizeSupport;
|
||||
@@ -140,8 +167,7 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
* Gets the HeaderMaximizeSupport implementation describing behavior for
|
||||
* minimize and maximize.
|
||||
*
|
||||
* @return maximizeSupport that encapsulates behavior for minimize and
|
||||
* maximize.
|
||||
* @return maximizeSupport that encapsulates behavior for minimize and maximize.
|
||||
*/
|
||||
public AbstractHeaderMaximizeSupport getHeaderMaximizeSupport() {
|
||||
return maximizeSupport;
|
||||
@@ -162,8 +188,15 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
*
|
||||
* @param newTitle
|
||||
*/
|
||||
public void updateTitle(final String newTitle) {
|
||||
title.setValue(newTitle);
|
||||
public void updateTitle(final String newTitle, final String hasTextCasePrefixText, final String hasNoTextCasePrefixText) {
|
||||
|
||||
if (StringUtils.hasText(newTitle)) {
|
||||
prefixText.setValue(i18n.getMessage(hasTextCasePrefixText));
|
||||
title.setValue(newTitle);
|
||||
} else {
|
||||
prefixText.setValue(i18n.getMessage(hasNoTextCasePrefixText));
|
||||
title.setValue("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,14 +237,12 @@ public class DefaultGridHeader extends VerticalLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional actions for maximize operation might be performed by this
|
||||
* method.
|
||||
* Additional actions for maximize operation might be performed by this method.
|
||||
*/
|
||||
protected abstract void maximize();
|
||||
|
||||
/**
|
||||
* Additional actions for minimize operation might be performed by this
|
||||
* method.
|
||||
* Additional actions for minimize operation might be performed by this method.
|
||||
*/
|
||||
protected abstract void minimize();
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ import com.vaadin.server.ExternalResource;
|
||||
import com.vaadin.server.FontAwesome;
|
||||
import com.vaadin.server.Resource;
|
||||
import com.vaadin.shared.ui.label.ContentMode;
|
||||
import com.vaadin.ui.Alignment;
|
||||
import com.vaadin.ui.Button;
|
||||
import com.vaadin.ui.CheckBox;
|
||||
import com.vaadin.ui.ComboBox;
|
||||
import com.vaadin.ui.HorizontalLayout;
|
||||
import com.vaadin.ui.Label;
|
||||
import com.vaadin.ui.Link;
|
||||
import com.vaadin.ui.Panel;
|
||||
@@ -44,6 +46,8 @@ import com.vaadin.ui.themes.ValoTheme;
|
||||
public final class SPUIComponentProvider {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SPUIComponentProvider.class);
|
||||
|
||||
private static final String LABEL_STYLE = "label-style";
|
||||
|
||||
/**
|
||||
* Prevent Instance creation as utility class.
|
||||
*/
|
||||
@@ -202,10 +206,50 @@ public final class SPUIComponentProvider {
|
||||
final Label nameValueLabel = new Label(getBoldHTMLText(label) + valueStr, ContentMode.HTML);
|
||||
nameValueLabel.setSizeFull();
|
||||
nameValueLabel.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||
nameValueLabel.addStyleName("label-style");
|
||||
nameValueLabel.addStyleName(LABEL_STYLE);
|
||||
return nameValueLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to CreateName value labels.
|
||||
*
|
||||
* @param label
|
||||
* as string
|
||||
* @param values
|
||||
* as string
|
||||
* @return HorizontalLayout
|
||||
*/
|
||||
public static HorizontalLayout createNameValueLayout(final String label, final String... values) {
|
||||
final String valueStr = StringUtils.arrayToDelimitedString(values, " ");
|
||||
|
||||
final Label nameValueLabel = new Label( label );
|
||||
nameValueLabel.setContentMode(ContentMode.TEXT);
|
||||
nameValueLabel.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||
nameValueLabel.addStyleName("text-bold");
|
||||
nameValueLabel.setSizeUndefined();
|
||||
|
||||
final Label valueStrLabel = new Label(valueStr);
|
||||
valueStrLabel.setWidth("100%");
|
||||
valueStrLabel.addStyleName("text-cut");
|
||||
valueStrLabel.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||
valueStrLabel.addStyleName(LABEL_STYLE);
|
||||
|
||||
final HorizontalLayout nameValueLayout = new HorizontalLayout();
|
||||
nameValueLayout.setMargin(false);
|
||||
nameValueLayout.setSpacing(true);
|
||||
nameValueLayout.setSizeFull();
|
||||
|
||||
nameValueLayout.addComponent(nameValueLabel);
|
||||
nameValueLayout.setComponentAlignment(nameValueLabel, Alignment.TOP_LEFT);
|
||||
nameValueLayout.setExpandRatio(nameValueLabel, 0.0F);
|
||||
|
||||
nameValueLayout.addComponent(valueStrLabel);
|
||||
nameValueLayout.setComponentAlignment(valueStrLabel, Alignment.TOP_LEFT);
|
||||
nameValueLayout.setExpandRatio(valueStrLabel, 1.0F);
|
||||
|
||||
return nameValueLayout;
|
||||
}
|
||||
|
||||
private static Label createUsernameLabel(final String label, final String username) {
|
||||
String loadAndFormatUsername = "";
|
||||
if (!StringUtils.isEmpty(username)) {
|
||||
@@ -215,14 +259,14 @@ public final class SPUIComponentProvider {
|
||||
final Label nameValueLabel = new Label(getBoldHTMLText(label) + loadAndFormatUsername, ContentMode.HTML);
|
||||
nameValueLabel.setSizeFull();
|
||||
nameValueLabel.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||
nameValueLabel.addStyleName("label-style");
|
||||
nameValueLabel.addStyleName(LABEL_STYLE);
|
||||
nameValueLabel.setDescription(loadAndFormatUsername);
|
||||
return nameValueLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create label which represents the {@link BaseEntity#getCreatedBy()} by
|
||||
* user name
|
||||
* Create label which represents the {@link BaseEntity#getCreatedBy()} by user
|
||||
* name
|
||||
*
|
||||
* @param i18n
|
||||
* the i18n
|
||||
@@ -236,8 +280,8 @@ public final class SPUIComponentProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create label which represents the {@link BaseEntity#getLastModifiedBy()}
|
||||
* by user name
|
||||
* Create label which represents the {@link BaseEntity#getLastModifiedBy()} by
|
||||
* user name
|
||||
*
|
||||
* @param i18n
|
||||
* the i18n
|
||||
@@ -306,11 +350,10 @@ public final class SPUIComponentProvider {
|
||||
* @param icon
|
||||
* of the link
|
||||
* @param targetOpen
|
||||
* specify how the link should be open (f. e. new windows =
|
||||
* _blank)
|
||||
* specify how the link should be open (f. e. new windows = _blank)
|
||||
* @param style
|
||||
* chosen style of the link. Might be {@code null} if no style
|
||||
* should be used
|
||||
* chosen style of the link. Might be {@code null} if no style should
|
||||
* be used
|
||||
* @return a link UI component
|
||||
*/
|
||||
public static Link getLink(final String id, final String name, final String resource, final FontAwesome icon,
|
||||
|
||||
@@ -87,7 +87,7 @@ public class SwModuleDetails extends AbstractSoftwareModuleDetails {
|
||||
}
|
||||
|
||||
private Button createShowArtifactDetailsButton() {
|
||||
artifactDetailsButton = SPUIComponentProvider.getButton("", "", "", null, false, FontAwesome.FILE_O,
|
||||
artifactDetailsButton = SPUIComponentProvider.getButton(UIComponentIdProvider.UPLOAD_SW_MODULE_SHOW_ARTIFACT_DETAILS_BUTTON, "", "", null, false, FontAwesome.FILE_O,
|
||||
SPUIButtonStyleNoBorder.class);
|
||||
artifactDetailsButton.setDescription(getI18n().getMessage(UIMessageIdProvider.TOOLTIP_ARTIFACT_ICON));
|
||||
artifactDetailsButton.addClickListener(event -> showArtifactDetailsWindow(getSelectedBaseEntity()));
|
||||
@@ -96,9 +96,11 @@ public class SwModuleDetails extends AbstractSoftwareModuleDetails {
|
||||
|
||||
private void showArtifactDetailsWindow(final SoftwareModule softwareModule) {
|
||||
final Window artifactDtlsWindow = new Window();
|
||||
artifactDtlsWindow.setCaption(HawkbitCommonUtil
|
||||
.getArtifactoryDetailsLabelId(softwareModule.getName() + "." + softwareModule.getVersion(), getI18n()));
|
||||
artifactDtlsWindow.setCaptionAsHtml(true);
|
||||
artifactDtlsWindow.setId(UIComponentIdProvider.SHOW_ARTIFACT_DETAILS_POPUP_ID);
|
||||
artifactDtlsWindow.setAssistivePrefix(HawkbitCommonUtil
|
||||
.getArtifactoryDetailsLabelId(softwareModule.getName(), getI18n()) + " " + "<b>");
|
||||
artifactDtlsWindow.setCaption(softwareModule.getName() + ":" + softwareModule.getVersion());
|
||||
artifactDtlsWindow.setAssistivePostfix("</b>");
|
||||
artifactDtlsWindow.setClosable(true);
|
||||
artifactDtlsWindow.setResizable(true);
|
||||
artifactDtlsWindow.setImmediate(true);
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
|
||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.UIMessageIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
@@ -79,13 +78,12 @@ public class ActionHistoryLayout extends AbstractGridComponentLayout {
|
||||
private String getActionHistoryCaption(final String targetName) {
|
||||
final String caption;
|
||||
if (StringUtils.hasText(targetName)) {
|
||||
caption = getI18n().getMessage(UIMessageIdProvider.CAPTION_ACTION_HISTORY_FOR,
|
||||
HawkbitCommonUtil.getBoldHTMLText(targetName));
|
||||
caption = getI18n().getMessage(UIMessageIdProvider.CAPTION_ACTION_HISTORY_FOR, targetName);
|
||||
} else {
|
||||
caption = getI18n().getMessage(UIMessageIdProvider.CAPTION_ACTION_HISTORY);
|
||||
}
|
||||
|
||||
return HawkbitCommonUtil.getCaptionText(caption);
|
||||
return caption;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,12 +111,12 @@ public class ActionHistoryLayout extends AbstractGridComponentLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default registration for selection propagation in order to
|
||||
* interrupt update cascade in minimized state to prevent updates on
|
||||
* invisible action-status-grid and message-grid.
|
||||
* Override default registration for selection propagation in order to interrupt
|
||||
* update cascade in minimized state to prevent updates on invisible
|
||||
* action-status-grid and message-grid.
|
||||
* <p>
|
||||
* The master selection is stored and propagation is performed as soon as
|
||||
* the state changes to maximize and hence the dependent grids are updated.
|
||||
* The master selection is stored and propagation is performed as soon as the
|
||||
* state changes to maximize and hence the dependent grids are updated.
|
||||
*/
|
||||
@Override
|
||||
public void registerDetails(final AbstractGrid<?>.DetailsSupport details) {
|
||||
@@ -188,7 +186,8 @@ public class ActionHistoryLayout extends AbstractGridComponentLayout {
|
||||
* name of the target
|
||||
*/
|
||||
public void updateActionHistoryHeader(final String targetName) {
|
||||
updateTitle(getActionHistoryCaption(targetName));
|
||||
updateTitle(targetName, UIMessageIdProvider.CAPTION_ACTION_HISTORY_FOR,
|
||||
UIMessageIdProvider.CAPTION_ACTION_HISTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -350,7 +350,7 @@ public class BulkUploadHandler extends CustomComponent
|
||||
errorMessage.append(dsAssignmentFailedMsg);
|
||||
}
|
||||
if (errorMessage.length() > 0) {
|
||||
errorMessage.append("<br>");
|
||||
errorMessage.append("\n");
|
||||
}
|
||||
if (tagAssignmentFailedMsg != null) {
|
||||
errorMessage.append(tagAssignmentFailedMsg);
|
||||
|
||||
@@ -225,18 +225,18 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
||||
|
||||
private void populateDistributionDtls(final VerticalLayout layout, final DistributionSet distributionSet) {
|
||||
layout.removeAllComponents();
|
||||
layout.addComponent(SPUIComponentProvider.createNameValueLabel(getI18n().getMessage("label.dist.details.name"),
|
||||
layout.addComponent(SPUIComponentProvider.createNameValueLayout(getI18n().getMessage("label.dist.details.name"),
|
||||
distributionSet == null ? "" : distributionSet.getName()));
|
||||
|
||||
layout.addComponent(
|
||||
SPUIComponentProvider.createNameValueLabel(getI18n().getMessage("label.dist.details.version"),
|
||||
SPUIComponentProvider.createNameValueLayout(getI18n().getMessage("label.dist.details.version"),
|
||||
distributionSet == null ? "" : distributionSet.getVersion()));
|
||||
|
||||
if (distributionSet == null) {
|
||||
return;
|
||||
}
|
||||
distributionSet.getModules()
|
||||
.forEach(module -> layout.addComponent(getSWModlabel(module.getType().getName(), module)));
|
||||
.forEach(module -> layout.addComponent(getSWModLayout(module.getType().getName(), module)));
|
||||
}
|
||||
|
||||
private void updateAttributesLayout(final String controllerId) {
|
||||
@@ -264,11 +264,11 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
||||
final TreeMap<String, String> sortedAttributes = new TreeMap<>((key1, key2) -> key1.compareToIgnoreCase(key2));
|
||||
sortedAttributes.putAll(attributes);
|
||||
sortedAttributes.forEach((key, value) -> {
|
||||
final Label conAttributeLabel = SPUIComponentProvider.createNameValueLabel(key.concat(" : "),
|
||||
final HorizontalLayout conAttributeLayout = SPUIComponentProvider.createNameValueLayout(key.concat(" : "),
|
||||
value == null ? "" : value);
|
||||
conAttributeLabel.setDescription(key.concat(" : ") + value);
|
||||
conAttributeLabel.addStyleName("label-style");
|
||||
attributesLayout.addComponent(conAttributeLabel);
|
||||
conAttributeLayout.setDescription(key.concat(" : ") + value);
|
||||
conAttributeLayout.addStyleName("label-style");
|
||||
attributesLayout.addComponent(conAttributeLayout);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -322,8 +322,9 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
||||
* as Module (JVM|OS|AH)
|
||||
* @return Label as UI
|
||||
*/
|
||||
private static Label getSWModlabel(final String labelName, final SoftwareModule swModule) {
|
||||
return SPUIComponentProvider.createNameValueLabel(labelName + " : ", swModule.getName(), swModule.getVersion());
|
||||
private static HorizontalLayout getSWModLayout(final String labelName, final SoftwareModule swModule) {
|
||||
return SPUIComponentProvider.createNameValueLayout(labelName + " : ", swModule.getName(),
|
||||
swModule.getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -84,8 +84,8 @@ public final class HawkbitCommonUtil {
|
||||
*
|
||||
* @param text
|
||||
* text to be trimmed
|
||||
* @return null if the text is null or if the text is blank, text.trim() if
|
||||
* the text is not empty.
|
||||
* @return null if the text is null or if the text is blank, text.trim() if the
|
||||
* text is not empty.
|
||||
*/
|
||||
public static String trimAndNullIfEmpty(final String text) {
|
||||
if (text != null && !text.trim().isEmpty()) {
|
||||
@@ -95,18 +95,16 @@ public final class HawkbitCommonUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate the given text all the string arguments with the given
|
||||
* delimiter.
|
||||
* Concatenate the given text all the string arguments with the given delimiter.
|
||||
*
|
||||
* @param delimiter
|
||||
* the delimiter text to be used while concatenation.
|
||||
* @param texts
|
||||
* all these string values will be concatenated with the given
|
||||
* delimiter.
|
||||
* @return null in case no text arguments to be compared. just concatenation
|
||||
* of all texts arguments if "delimiter" is null or empty.
|
||||
* concatenation of all texts arguments with "delimiter" if it not
|
||||
* null.
|
||||
* @return null in case no text arguments to be compared. just concatenation of
|
||||
* all texts arguments if "delimiter" is null or empty. concatenation of
|
||||
* all texts arguments with "delimiter" if it not null.
|
||||
*/
|
||||
public static String concatStrings(final String delimiter, final String... texts) {
|
||||
final String delim = delimiter == null ? "" : delimiter;
|
||||
@@ -140,21 +138,6 @@ public final class HawkbitCommonUtil {
|
||||
return boldStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Label for Artifact Details.
|
||||
*
|
||||
* @param caption
|
||||
* as caption of the details
|
||||
* @param name
|
||||
* as name
|
||||
* @return SoftwareModuleName
|
||||
*/
|
||||
public static String getSoftwareModuleName(final String caption, final String name) {
|
||||
return new StringBuilder()
|
||||
.append(DIV_DESCRIPTION_START + caption + " : " + getBoldHTMLText(getFormattedName(name)))
|
||||
.append(DIV_DESCRIPTION_END).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tool tip for Poll status.
|
||||
*
|
||||
@@ -181,7 +164,7 @@ public final class HawkbitCommonUtil {
|
||||
* @return String formatted text
|
||||
*/
|
||||
public static String getFormattedName(final String orgText) {
|
||||
return trimAndNullIfEmpty(orgText) == null ? SPUIDefinitions.SPACE : orgText;
|
||||
return trimAndNullIfEmpty(orgText) == null ? "" : orgText;
|
||||
}
|
||||
|
||||
private static float findRequiredSwModuleExtraWidth(final float newBrowserWidth) {
|
||||
@@ -246,10 +229,11 @@ public final class HawkbitCommonUtil {
|
||||
* @return Label
|
||||
*/
|
||||
public static Label getFormatedLabel(final String labelContent) {
|
||||
final Label labelValue = new Label(labelContent, ContentMode.HTML);
|
||||
final Label labelValue = new Label(labelContent, ContentMode.TEXT);
|
||||
labelValue.setSizeFull();
|
||||
labelValue.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||
labelValue.addStyleName("label-style");
|
||||
labelValue.addStyleName("avoid-tooltip");
|
||||
return labelValue;
|
||||
}
|
||||
|
||||
@@ -301,20 +285,20 @@ public final class HawkbitCommonUtil {
|
||||
final int unassignedCount = result.getUnassigned();
|
||||
if (assignedCount == 1) {
|
||||
formMsg.append(i18n.getMessage("message.target.assigned.one", result.getAssignedEntity().get(0).getName(),
|
||||
tagName)).append("<br>");
|
||||
tagName)).append("\n");
|
||||
} else if (assignedCount > 1) {
|
||||
formMsg.append(i18n.getMessage("message.target.assigned.many", assignedCount, tagName)).append("<br>");
|
||||
formMsg.append(i18n.getMessage("message.target.assigned.many", assignedCount, tagName)).append("\n");
|
||||
|
||||
if (alreadyAssignedCount > 0) {
|
||||
final String alreadyAssigned = i18n.getMessage("message.target.alreadyAssigned", alreadyAssignedCount);
|
||||
formMsg.append(alreadyAssigned).append("<br>");
|
||||
formMsg.append(alreadyAssigned).append("\n");
|
||||
}
|
||||
}
|
||||
if (unassignedCount == 1) {
|
||||
formMsg.append(i18n.getMessage("message.target.unassigned.one",
|
||||
result.getUnassignedEntity().get(0).getName(), tagName)).append("<br>");
|
||||
result.getUnassignedEntity().get(0).getName(), tagName)).append("\n");
|
||||
} else if (unassignedCount > 1) {
|
||||
formMsg.append(i18n.getMessage("message.target.unassigned.many", unassignedCount, tagName)).append("<br>");
|
||||
formMsg.append(i18n.getMessage("message.target.unassigned.many", unassignedCount, tagName)).append("\n");
|
||||
}
|
||||
return formMsg.toString();
|
||||
}
|
||||
@@ -552,14 +536,13 @@ public final class HawkbitCommonUtil {
|
||||
* @return complete caption text of the table
|
||||
*/
|
||||
public static String getArtifactoryDetailsLabelId(final String name, final VaadinMessageSource i18n) {
|
||||
String caption;
|
||||
final String caption;
|
||||
if (StringUtils.hasText(name)) {
|
||||
caption = i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS_OF,
|
||||
HawkbitCommonUtil.getBoldHTMLText(name));
|
||||
caption = i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS_OF);
|
||||
} else {
|
||||
caption = i18n.getMessage(UIMessageIdProvider.CAPTION_ARTIFACT_DETAILS);
|
||||
}
|
||||
return getCaptionText(caption);
|
||||
return caption;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,7 +65,7 @@ public class NotificationMessage extends Notification {
|
||||
setCaption(caption);
|
||||
setDescription(description);
|
||||
setStyleName(styleName);
|
||||
setHtmlContentAllowed(true);
|
||||
setHtmlContentAllowed(false);
|
||||
setPosition(Position.BOTTOM_RIGHT);
|
||||
if (autoClose) {
|
||||
setDelayMsec(SPUILabelDefinitions.SP_DELAY);
|
||||
|
||||
@@ -252,6 +252,16 @@ public final class SPUIStyleDefinitions {
|
||||
*/
|
||||
public static final String COLOR_LABEL_STYLE = "color-label-style";
|
||||
|
||||
/**
|
||||
* Label bold style.
|
||||
*/
|
||||
public static final String BOLD_LABEL_STYLE = "label-bold-style";
|
||||
|
||||
/**
|
||||
* Label right padding style
|
||||
*/
|
||||
public static final String RIGHT_PADDING_LABEL_STYLE = "header-caption-right";
|
||||
|
||||
/**
|
||||
* Style - Message.
|
||||
*/
|
||||
|
||||
@@ -445,6 +445,11 @@ public final class UIComponentIdProvider {
|
||||
*/
|
||||
public static final String UPLOAD_SW_MODULE_EDIT_BUTTON = "swmodule.edit.button";
|
||||
|
||||
/**
|
||||
* Artifact upload - sw module show artifact details button id.
|
||||
*/
|
||||
public static final String UPLOAD_SW_MODULE_SHOW_ARTIFACT_DETAILS_BUTTON = "swmodule.show.artifacts.details.button";
|
||||
|
||||
/**
|
||||
* Artifact upload - sw module metadata button id.
|
||||
*/
|
||||
@@ -1167,6 +1172,11 @@ public final class UIComponentIdProvider {
|
||||
*/
|
||||
public static final String METADATA_POPUP_ID = "metadata.popup.id";
|
||||
|
||||
/**
|
||||
* Show artifact details popup id.
|
||||
*/
|
||||
public static final String SHOW_ARTIFACT_DETAILS_POPUP_ID = "show.artifact.details.popup.id";
|
||||
|
||||
/**
|
||||
* Rollout popup id.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@ public class UINotification implements Serializable {
|
||||
* is the message to displayed as success.
|
||||
*/
|
||||
public void displaySuccess(final String message) {
|
||||
notificationMessage.setIcon(null);
|
||||
notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_SUCCESS_MESSAGE_STYLE, null, message,
|
||||
true);
|
||||
}
|
||||
@@ -50,6 +51,7 @@ public class UINotification implements Serializable {
|
||||
* is the message to displayed as warning.
|
||||
*/
|
||||
public void displayWarning(final String message) {
|
||||
notificationMessage.setIcon(null);
|
||||
notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_WARNING_MESSAGE_STYLE, null, message,
|
||||
true);
|
||||
}
|
||||
@@ -61,11 +63,10 @@ public class UINotification implements Serializable {
|
||||
* as message.
|
||||
*/
|
||||
public void displayValidationError(final String message) {
|
||||
final StringBuilder updatedMsg = new StringBuilder(FontAwesome.EXCLAMATION_TRIANGLE.getHtml());
|
||||
updatedMsg.append(' ');
|
||||
updatedMsg.append(message);
|
||||
notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null,
|
||||
updatedMsg.toString(), true);
|
||||
final StringBuilder updatedMsg = new StringBuilder(message);
|
||||
notificationMessage.setIcon(FontAwesome.EXCLAMATION_TRIANGLE);
|
||||
notificationMessage.showNotification(SPUIStyleDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, updatedMsg.toString(), null
|
||||
, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ $generic-text-font-size: $generic-text-font-scale * $v-font-size;
|
||||
|
||||
//Report widget max icon style
|
||||
.icon-only {
|
||||
@include sp-icon-style($sp-button-size : $icon-font-size);
|
||||
@include sp-icon-style($sp-button-size: $icon-font-size);
|
||||
margin-bottom: 12px !important;
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
@@ -91,6 +91,39 @@ $generic-text-font-size: $generic-text-font-scale * $v-font-size;
|
||||
-webkit-text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.text-bold {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.v-Notification-error .v-icon {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-caption-right {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.avoid-tooltip {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
//This was needed to make the split of prefix "Artifact details of"
|
||||
//and the actual value "smName:smVersion" in context of the XSS vulnerabilities
|
||||
//possible after changing ContentMode
|
||||
//from HTML to TEXT. As no Labels allowed at the windows caption field of the
|
||||
//artifact details window , decision was made to use the methods
|
||||
//Window.setAssistivePrefix() and Window.setAssistivePostfix() to solve the XSS-problem.
|
||||
//Both, assistive postfix and prefix are usually not visible on the page and only for
|
||||
//assistive purpose, but with overwriting this third party html class it's a possible
|
||||
//workaround for the XSS vulnerability. I added a comment in the generic-styles.scss.
|
||||
.v-assistive-device-only {
|
||||
position: static;
|
||||
top: auto;
|
||||
left: auto;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.v-panel,
|
||||
.v-textfield {
|
||||
background: $widget-bg;
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
//confimation dialogue popup - Content margin adjustment
|
||||
.confirmbox-question-label {
|
||||
margin: 0 8px 8px;
|
||||
margin: 15px 8px 18px 8px;
|
||||
}
|
||||
|
||||
.bulk-upload-button{
|
||||
|
||||
@@ -98,9 +98,9 @@ distribution.set.tag.updated.event.container.notifcation.message=distribution se
|
||||
caption.filter.by.type = Filter by type
|
||||
caption.bulk.upload = Bulk Upload
|
||||
caption.action.history = Action history
|
||||
caption.action.history.for = Action history for {0}
|
||||
caption.action.history.for = Action history for
|
||||
caption.artifact.details = Artifact Details
|
||||
caption.artifact.details.of = Artifact Details of {0}
|
||||
caption.artifact.details.of = Artifact Details of
|
||||
caption.action.states= Action States
|
||||
caption.action.messages = Messages
|
||||
caption.error = Error
|
||||
|
||||
Reference in New Issue
Block a user