From bbaa6baa728a7ffae079c3cdd83b277a4ed9692a Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 9 Jun 2016 13:24:40 +0200 Subject: [PATCH] Improved enable save button functionality when update tag Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 55 +++------ .../CreateUpdateSoftwareTypeLayout.java | 41 ++++++- .../hawkbit/ui/common/CommonDialogWindow.java | 74 +++++++++++- .../ui/components/SPUIComponentProvider.java | 2 + .../CreateUpdateDistSetTypeLayout.java | 49 ++++++-- .../AbstractCreateUpdateTagLayout.java | 71 +++++++++-- .../ui/layouts/CreateUpdateTypeLayout.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 64 ++++++---- ...eateUpdateDistributionTagLayoutWindow.java | 5 + .../TargetAddUpdateWindowLayout.java | 43 +++++-- .../CreateUpdateTargetTagLayoutWindow.java | 4 + .../rollout/AddUpdateRolloutWindowLayout.java | 113 ++++++++++++------ 12 files changed, 384 insertions(+), 146 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 0dd85d08b..309c111ea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -13,7 +13,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -73,8 +72,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se @Autowired private transient EntityFactory entityFactory; - private Label mandatoryLabel; - private TextField nameTextField; private TextField versionTextField; @@ -136,14 +133,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(this::nameTextFieldChanged); + nameTextField.addTextChangeListener(this::listenerNameTextFieldChanged); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField.addTextChangeListener(this::versionTextFieldChanged); + versionTextField.addTextChangeListener(this::listenerVersionTextFieldChanged); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, @@ -157,49 +154,29 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addDescriptionTextChangeListener(); addVendorTextChangeListener(); - /* Label for mandatory symbol */ - mandatoryLabel = new Label(i18n.get("label.mandatory.field")); - mandatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - mandatoryLabel.addStyleName(ValoTheme.LABEL_SMALL); - typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); typeComboBox.setId(SPUIComponentIdProvider.SW_MODULE_TYPE); typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); - typeComboBox.addValueChangeListener(this::typeComboBoxChanged); + typeComboBox.addValueChangeListener(this::listenerTypeComboBoxChanged); populateTypeNameCombo(); resetOldValues(); } - private void nameTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, nameTextField); } - private void versionTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, versionTextField); } - private void typeComboBoxChanged(final ValueChangeEvent event) { - if (event.getProperty().getValue() != null) { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerTypeComboBoxChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, typeComboBox); } private void populateTypeNameCombo() { @@ -212,6 +189,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void resetOldValues() { oldDescriptionValue = null; oldVendorValue = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void createWindow() { @@ -227,7 +208,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); - // formLayout.addComponent(mandatoryLabel); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); @@ -252,13 +232,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { requiredFields.put(c.getCaption(), null); } - // else if (c instanceof TextField && ((TextField) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } else if (c instanceof TextArea && ((TextArea) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } } return requiredFields; } @@ -347,6 +320,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -383,6 +357,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } else { addNewBaseSoftware(); } + window.setSaveButtonEnabled(false); } private boolean hasDescriptionChanged(final TextChangeEvent event) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index ad78e09e7..7473d5509 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -9,7 +9,10 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; @@ -31,11 +34,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; @@ -69,7 +75,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -86,11 +92,13 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); + typeKey.addTextChangeListener(this::typeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -103,6 +111,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout singleMultiOptionGroup(); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, tagName); + } + + private void typeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -112,13 +128,23 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout getFormLayout().addComponent(assignOptiongroup); } - // TODO MR requiredFields - @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -128,9 +154,9 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { assignOptiongroup.setEnabled(false); @@ -172,6 +198,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout .findSoftwareModuleTypeByName(targetTagSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) { assignOptiongroup.setValue(multiAssignStr); @@ -201,6 +228,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { if (!mandatoryValuesPresent()) { + window.setSaveButtonEnabled(false); return; } @@ -216,6 +244,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout updateSWModuleType(existingSMTypeByName); } + window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index d14830aa4..7b5df4a8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; +import java.io.Serializable; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -20,11 +21,14 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractOrderedLayout; +import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.AbstractTextField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; @@ -40,9 +44,7 @@ import com.vaadin.ui.themes.ValoTheme; * Superclass for pop-up-windows including a minimize and close icon in the * upper right corner and a save and cancel button at the bottom. */ -@SpringComponent -@ViewScope -public class CommonDialogWindow extends Window { +public class CommonDialogWindow extends Window implements Serializable { private static final long serialVersionUID = -1321949234316858703L; @@ -100,12 +102,38 @@ public class CommonDialogWindow extends Window { init(); } + public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { + + if (StringUtils.isNotBlank(event.getText())) { + getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + } else { + getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + } + checkMandatoryFields(); + } + + public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { + + if (event.getProperty().getValue() != null) { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.TRUE); + } + getRequiredFields().put(select.getId(), Boolean.TRUE); + } else { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.FALSE); + } + getRequiredFields().put(select.getId(), Boolean.FALSE); + } + checkMandatoryFields(); + } + /** * Checks the mandatory fields in the pop-up-window content. If all * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - public void checkMandatoryFields() { + private void checkMandatoryFields() { for (final Map.Entry entry : requiredFields.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { @@ -116,6 +144,40 @@ public class CommonDialogWindow extends Window { saveButton.setEnabled(true); } + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + getRequiredFields().put(fieldId, Boolean.TRUE); + checkMandatoryFields(); + } + + public void checkChanges(final String newText, final String oldText) { + + if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) + || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { + saveButton.setEnabled(true); + } else { + saveButton.setEnabled(false); + } + } + + public void checkColorChange(final Color newColor, final Color oldColor) { + + if (newColor.equals(oldColor)) { + setSaveButtonEnabled(false); + } else { + setSaveButtonEnabled(true); + } + } + + public void resetRequiredFieldsValues() { + // Reset mandatory fields are filled marker + if (getRequiredFields() != null) { + for (final Map.Entry entry : getRequiredFields().entrySet()) { + entry.setValue(null); + } + } + } + private final void init() { if (content instanceof AbstractOrderedLayout) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 2b743d2a8..3ba71fce5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -205,6 +205,8 @@ public final class SPUIComponentProvider { /** * Get Label UI component. * * + * @param caption + * set the caption of the textArea * @param style * set style * @param styleName diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 48cdbfc6a..a04136a48 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -8,7 +8,10 @@ */ package org.eclipse.hawkbit.ui.distributions.disttype; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -37,9 +40,11 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -94,11 +99,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); + typeKey.addTextChangeListener(this::listenerTypeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -109,6 +116,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setNullRepresentation(""); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTypeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -247,10 +263,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addSMType() { final Set selectedIds = (Set) sourceTable.getValue(); - if (null != selectedIds && !selectedIds.isEmpty()) { + if (selectedIds != null && !selectedIds.isEmpty()) { for (final Long id : selectedIds) { addTargetTableData(id); } + + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); } } @@ -264,6 +282,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout selectedTable.removeItem(id); } } + if (selectedIds == null || selectedIds.isEmpty()) { + window.updateRequiredFields(selectedTable.getId(), Boolean.FALSE); + } } @SuppressWarnings("unchecked") @@ -484,9 +505,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { selectedTable.getContainerDataSource().removeAllItems(); @@ -551,18 +572,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout final DistributionSetType selectedTypeTag = fetchDistributionSetType(distSetTypeSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); - window.setSaveButtonEnabled(true); } else { uiNotification.displayValidationError( selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update")); distTypeSelectLayout.setEnabled(false); selectedTable.setEnabled(false); - window.setSaveButtonEnabled(false); } for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) { addTargetTableforUpdate(swModuleType, false); @@ -607,15 +627,30 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { updateDistributionSetType(existingDistTypeByKey); } + window.setSaveButtonEnabled(false); } } - // TODO MR requiredFields @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + // Selected SoftwareModulesType + requiredFields.put(selectedTable.getId(), null); + + return requiredFields; } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index d5f9fef94..f8fb5c3e0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -8,6 +8,10 @@ */ package org.eclipse.hawkbit.ui.layouts; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; @@ -25,7 +29,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; 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.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -33,11 +36,14 @@ import org.vaadin.spring.events.EventBus; import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; @@ -87,7 +93,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected CommonDialogWindow window; protected Label colorLabel; - protected Label madatoryLabel; protected TextField tagName; protected TextArea tagDesc; protected Button tagColorPreviewBtn; @@ -105,11 +110,25 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - // TODO MR requiredFields + private Color selectedColorOriginal; + private String tagDescOriginal; + protected void createWindow() { reset(); setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null)); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields())); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -158,7 +177,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createTagStr = i18n.get("label.create.tag"); updateTagStr = i18n.get("label.update.tag"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -166,6 +184,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), @@ -174,6 +193,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", "", null, null, false, "", i18n.get("label.combobox.tag")); @@ -186,6 +206,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTagDescTextAreaChanged(final TextChangeEvent event) { + + window.checkChanges(event.getText(), tagDescOriginal); + } + protected void buildLayout() { mainLayout = new GridLayout(3, 2); @@ -201,7 +231,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent formLayout.addComponent(optiongroup); formLayout.addComponent(comboLayout); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(tagName); formLayout.addComponent(tagDesc); formLayout.addStyleName("form-lastrow"); @@ -269,12 +298,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } } - protected Label getMandatoryLabel() { - final Label label = new Label(i18n.get("label.mandatory.field")); - label.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return label; - } - private void tagNameChosen(final ValueChangeEvent event) { final String tagSelected = (String) event.getProperty().getValue(); if (null != tagSelected) { @@ -319,6 +342,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color @@ -347,6 +371,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } /** @@ -434,11 +462,14 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview); colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } + + window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); } protected void closeWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -643,4 +674,20 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return formLayout; } + public Color getSelectedColorOriginal() { + return selectedColorOriginal; + } + + public void setSelectedColorOriginal(final Color selectedColorOriginal) { + this.selectedColorOriginal = selectedColorOriginal; + } + + public String getTagDescOriginal() { + return tagDescOriginal; + } + + public void setTagDescOriginal(final String tagDescOriginal) { + this.tagDescOriginal = tagDescOriginal; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 1987d6053..c67d35321 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -52,7 +52,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -61,7 +61,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createTypeStr = i18n.get("label.create.type"); updateTypeStr = i18n.get("label.update.type"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -137,7 +136,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { * @param event * ValueChangeEvent */ - protected void createOptionValueChanged(final ValueChangeEvent event) { + @Override + protected void optionValueChanged(final ValueChangeEvent event) { if (updateTypeStr.equals(event.getProperty().getValue())) { tagName.clear(); @@ -158,6 +158,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); restoreComponentStyles(); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); getColorPickerLayout().getSelPreview() @@ -236,12 +237,14 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, ColorPickerConstants.DEFAULT_COLOR); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { getColorPickerLayout().setSelectedColor(ColorPickerHelper.rgbToColorConverter(color)); getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, color); getPreviewButtonColor(color); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(color)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index c0a4dc165..82cf2390c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -49,12 +50,12 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -92,13 +93,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private TextField distNameTextField; private TextField distVersionTextField; - private Label madatoryLabel; private TextArea descTextArea; private CheckBox reqMigStepCheckbox; private ComboBox distsetTypeNameComboBox; private boolean editDistribution = Boolean.FALSE; private Long editDistId; - private CommonDialogWindow addDistributionWindow; + private CommonDialogWindow window; private String originalDistName; private String originalDistVersion; private String originalDistDescription; @@ -132,7 +132,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { setSizeUndefined(); formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(distsetTypeNameComboBox); formLayout.addComponent(distNameTextField); formLayout.addComponent(distVersionTextField); @@ -152,12 +151,14 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); distNameTextField.setNullRepresentation(""); + distNameTextField.addTextChangeListener(this::listenerDistNameTextFieldChanged); distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); distVersionTextField.setNullRepresentation(""); + distVersionTextField.addTextChangeListener(this::listenerDistVersionTextFieldChanged); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); @@ -171,16 +172,20 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC); descTextArea.setNullRepresentation(""); - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"), "dist-checkbox-style", null, false, ""); reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL); reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); } + private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distNameTextField); + } + + private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distVersionTextField); + } + /** * Get the LazyQueryContainer instance for DistributionSetTypes. * @@ -201,7 +206,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void enableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(true); + window.setSaveButtonEnabled(true); } private DistributionSetType getDefaultDistributionSetType() { @@ -210,17 +215,16 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void disableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); } private void saveDistribution() { - /* add new or update target */ if (editDistribution) { updateDistribution(); } else { addNewDistribution(); } - + window.setSaveButtonEnabled(false); } /** @@ -298,8 +302,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { * Close window. */ private void closeThisWindow() { - addDistributionWindow.close(); - UI.getCurrent().removeWindow(addDistributionWindow); + window.close(); + UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -398,11 +403,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); descTextArea.clear(); reqMigStepCheckbox.clear(); - if (addDistributionWindow != null) { - addDistributionWindow.setSaveButtonEnabled(true); + if (window != null) { + window.setSaveButtonEnabled(true); } removeListeners(); changedComponents.clear(); + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void populateRequiredComponents() { @@ -482,7 +491,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { public void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; editDistribution = Boolean.TRUE; - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); if (distSet != null) { distNameTextField.setValue(distSet.getName()); @@ -504,17 +513,28 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); populateRequiredComponents(); resetComponents(); - addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, null); - addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin"); + null, getMandatoryFields()); + window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - return addDistributionWindow; + return window; + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 0d4da54e8..3bee67345 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -98,6 +98,7 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat updateExistingTag(existingDistTag); } } + window.setSaveButtonEnabled(false); } /** @@ -159,11 +160,14 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat final DistributionSetTag selectedDistTag = tagManagement.findDistributionSetTag(distTagSelected); if (null != selectedDistTag) { tagDesc.setValue(selectedDistTag.getDescription()); + setTagDescOriginal(selectedDistTag.getDescription()); if (null == selectedDistTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour()), selectedDistTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour())); } } } @@ -181,4 +185,5 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(), permChecker.hasUpdateDistributionPermission()); } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index a5a562c11..e5d65295b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -8,9 +8,13 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; @@ -35,6 +39,8 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -73,7 +79,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private TextField controllerIDTextField; private TextField nameTextField; private TextArea descTextArea; - private Label madatoryLabel; private boolean editTarget = Boolean.FALSE; private String controllerId; private FormLayout formLayout; @@ -100,6 +105,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); + controllerIDTextField.addTextChangeListener(this::listenerControllerIDTextFieldChanged); /* Textfield for target name */ nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null, @@ -111,10 +117,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC); descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); - - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); + } + + private void listenerControllerIDTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, controllerIDTextField); } private void buildLayout() { @@ -125,14 +131,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { */ formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(controllerIDTextField); formLayout.addComponent(nameTextField); formLayout.addComponent(descTextArea); - if (Boolean.TRUE.equals(editTarget)) { - madatoryLabel.setVisible(Boolean.FALSE); - } nameTextField.focus(); } @@ -211,6 +213,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } else { addNewTarget(); } + window.setSaveButtonEnabled(false); } private void discardTargetListner() { @@ -241,13 +244,24 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields()); return window; } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; + } /** * clear all fields of Target Edit Window. @@ -261,12 +275,17 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void closeThisWindow() { editTarget = Boolean.FALSE; window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } private void setTargetValues(final Target target, final String name, final String description) { @@ -287,7 +306,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { - uINotification.displayValidationError(i18n.get("message.target.duplicate.check")); + uINotification.displayValidationError(i18n.get("message.target.duplicate.check", new Object[] {newControlllerId})); return false; } else { return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index a7d612f72..81c0c72ae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -91,11 +91,14 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa final TargetTag selectedTargetTag = tagManagement.findTargetTag(targetTagSelected); if (null != selectedTargetTag) { tagDesc.setValue(selectedTargetTag.getDescription()); + setTagDescOriginal(selectedTargetTag.getDescription()); if (null == selectedTargetTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour()), selectedTargetTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour())); } } } @@ -112,6 +115,7 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa updateExistingTag(existingTag); } } + window.setSaveButtonEnabled(false); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 41742d5f7..1226ec5fb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -10,7 +10,9 @@ package org.eclipse.hawkbit.ui.rollout.rollout; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -58,6 +60,7 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Validator; import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.ComboBox; @@ -115,8 +118,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Autowired private transient EventBus.SessionEventBus eventBus; - private Label mandatoryLabel; - private TextField rolloutName; private ComboBox distributionSet; @@ -135,7 +136,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private OptionGroup errorThresholdOptionGroup; - private CommonDialogWindow addUpdateRolloutWindow; + private CommonDialogWindow window; private Boolean editRolloutEnabled; @@ -157,13 +158,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } - // TODO MR requiredFields public CommonDialogWindow getWindow() { - addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), null); - return addUpdateRolloutWindow; + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields()); + return window; + } + + private Map getMandatoryFields() { + + final Map requiredFields = new HashMap<>(); + requiredFields.put(rolloutName.getId(), null); + requiredFields.put(distributionSet.getId(), null); + requiredFields.put(targetFilterQueryCombo.getId(), null); + requiredFields.put(noOfGroups.getId(), null); + requiredFields.put(triggerThreshold.getId(), null); + requiredFields.put(errorThreshold.getId(), null); + + return requiredFields; } /** @@ -187,6 +200,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { actionTypeOptionGroupLayout.selectDefaultOption(); totalTargetsCount = 0L; rolloutForEdit = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void resetFields() { @@ -208,26 +225,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setRows(9); setColumns(3); - addComponent(mandatoryLabel, 1, 0, 2, 0); - addComponent(getLabel("textfield.name"), 0, 1); - addComponent(rolloutName, 1, 1); - addComponent(getLabel("prompt.distribution.set"), 0, 2); - addComponent(distributionSet, 1, 2); - addComponent(getLabel("prompt.target.filter"), 0, 3); - addComponent(targetFilterQueryCombo, 1, 3); - addComponent(totalTargetsLabel, 2, 3); - addComponent(getLabel("prompt.number.of.groups"), 0, 4); - addComponent(noOfGroups, 1, 4); - addComponent(groupSizeLabel, 2, 4); - addComponent(getLabel("prompt.tigger.threshold"), 0, 5); - addComponent(triggerThreshold, 1, 5); - addComponent(getPercentHintLabel(), 2, 5); - addComponent(getLabel("prompt.error.threshold"), 0, 6); - addComponent(errorThreshold, 1, 6); - addComponent(errorThresholdOptionGroup, 2, 6); - addComponent(getLabel("textfield.description"), 0, 7); - addComponent(description, 1, 7, 2, 7); - addComponent(actionTypeOptionGroupLayout, 0, 8, 2, 8); + addComponent(getLabel("textfield.name"), 0, 0); + addComponent(rolloutName, 1, 0); + addComponent(getLabel("prompt.distribution.set"), 0, 1); + addComponent(distributionSet, 1, 1); + addComponent(getLabel("prompt.target.filter"), 0, 2); + addComponent(targetFilterQueryCombo, 1, 2); + addComponent(totalTargetsLabel, 2, 2); + addComponent(getLabel("prompt.number.of.groups"), 0, 3); + addComponent(noOfGroups, 1, 3); + addComponent(groupSizeLabel, 2, 3); + addComponent(getLabel("prompt.tigger.threshold"), 0, 4); + addComponent(triggerThreshold, 1, 4); + addComponent(getPercentHintLabel(), 2, 4); + addComponent(getLabel("prompt.error.threshold"), 0, 5); + addComponent(errorThreshold, 1, 5); + addComponent(errorThresholdOptionGroup, 2, 5); + addComponent(getLabel("textfield.description"), 0, 6); + addComponent(description, 1, 6, 2, 6); + addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7); rolloutName.focus(); } @@ -249,7 +265,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void createRequiredComponents() { - mandatoryLabel = createMandatoryLabel(); rolloutName = createRolloutNameField(); distributionSet = createDistributionSetCombo(); populateDistributionSet(); @@ -308,11 +323,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL); errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP); errorThresoldOptions.setSizeUndefined(); - errorThresoldOptions.addValueChangeListener(this::onErrorThresoldOptionChange); + errorThresoldOptions.addValueChangeListener(this::listenerOnErrorThresoldOptionChange); return errorThresoldOptions; } - private void onErrorThresoldOptionChange(final ValueChangeEvent event) { + private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) { errorThreshold.clear(); errorThreshold.removeAllValidators(); if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) { @@ -331,11 +346,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID); targetFilter.setSizeUndefined(); - targetFilter.addValueChangeListener(event -> onTargetFilterChange()); + targetFilter.addValueChangeListener(this::onTargetFilterChange); return targetFilter; } - private void onTargetFilterChange() { + private void onTargetFilterChange(final ValueChangeEvent event) { final String filterQueryString = getTargetFilterQuery(); if (!Strings.isNullOrEmpty(filterQueryString)) { totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString); @@ -346,6 +361,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel.setVisible(false); } onGroupNumberChange(); + + window.checkMandatoryComboBox(event, targetFilterQueryCombo); } private String getTotalTargetMessage() { @@ -490,8 +507,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void closeThisWindow() { - addUpdateRolloutWindow.close(); - UI.getCurrent().removeWindow(addUpdateRolloutWindow); + window.close(); + UI.getCurrent().removeWindow(window); } private boolean mandatoryCheck() { @@ -560,18 +577,29 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); errorField.setSizeUndefined(); + errorField.addTextChangeListener(this::listenerErrorThresholdTextFieldChanged); return errorField; } + private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, errorThreshold); + } + private TextField createTriggerThresold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); + thresholdField.addTextChangeListener(this::listenerTriggerThresholdTextFieldChanged); return thresholdField; } + private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, triggerThreshold); + } + private TextField createNoOfGroupsField() { final TextField noOfGroupsField = getTextfield("prompt.number.of.groups"); noOfGroupsField.setId(SPUIComponentIdProvider.ROLLOUT_NO_OF_GROUPS_ID); @@ -579,9 +607,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange()); + noOfGroupsField.addTextChangeListener(this::listenerNoOfGroupsTextFieldChanged); return noOfGroupsField; } + private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, noOfGroups); + } + private void onGroupNumberChange() { if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); @@ -599,9 +632,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); dsSet.setId(SPUIComponentIdProvider.ROLLOUT_DS_ID); dsSet.setSizeUndefined(); + dsSet.addValueChangeListener(this::listenerDistributionSetChanged); return dsSet; } + private void listenerDistributionSetChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, distributionSet); + } + private void populateDistributionSet() { final Container container = createDsComboContainer(); distributionSet.setContainerDataSource(container); @@ -620,13 +658,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { final TextField rolloutNameField = getTextfield("textfield.name"); rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); + rolloutNameField.addTextChangeListener(this::listenerRolloutNameTextFieldChanged); return rolloutNameField; } - private Label createMandatoryLabel() { - final Label madatoryLbl = new Label(i18n.get("label.mandatory.field")); - madatoryLbl.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return madatoryLbl; + private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, rolloutName); } private String getRolloutName() {