Some small UI glitches (#622)

* Show error notification if exception occurs while saving

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* General solution for Validation Exceptions

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* Use String not Long for presenting ID in UI

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* Table for displaying softwareModules of distributionSet contains as much
rows as necessary.

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* Add validator to the target filter combobox

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* Error Notification displays the exception message if available,
otherwise displays the exception's class name

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>

* Refactor validation message

Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>
This commit is contained in:
Melanie Retter
2018-01-23 15:32:40 +01:00
committed by Kai Zimmermann
parent 722c5ad2c2
commit b9f6fcea02
5 changed files with 38 additions and 30 deletions

View File

@@ -163,10 +163,15 @@ public class SoftwareModuleDetailsTable extends Table {
if (!CollectionUtils.isEmpty(swModuleOptionalTypes)) { if (!CollectionUtils.isEmpty(swModuleOptionalTypes)) {
swModuleOptionalTypes.forEach(swModule -> setSwModuleProperties(swModule, false, distributionSet)); swModuleOptionalTypes.forEach(swModule -> setSwModuleProperties(swModule, false, distributionSet));
} }
setAmountOfTableRows(getContainerDataSource().size());
} }
} }
private void setAmountOfTableRows(final int amountOfRows) {
setPageLength(amountOfRows);
}
private void setSwModuleProperties(final SoftwareModuleType swModType, final Boolean isMandatory, private void setSwModuleProperties(final SoftwareModuleType swModType, final Boolean isMandatory,
final DistributionSet distributionSet) { final DistributionSet distributionSet) {
final Set<SoftwareModule> alreadyAssignedSwModules = distributionSet.getModules(); final Set<SoftwareModule> alreadyAssignedSwModules = distributionSet.getModules();
@@ -179,7 +184,6 @@ public class SoftwareModuleDetailsTable extends Table {
saveTblitem.getItemProperty(SOFT_TYPE_MANDATORY).setValue(mandatoryLabel); saveTblitem.getItemProperty(SOFT_TYPE_MANDATORY).setValue(mandatoryLabel);
saveTblitem.getItemProperty(SOFT_TYPE_NAME).setValue(typeName); saveTblitem.getItemProperty(SOFT_TYPE_NAME).setValue(typeName);
saveTblitem.getItemProperty(SOFT_MODULE).setValue(verticalLayout); saveTblitem.getItemProperty(SOFT_MODULE).setValue(verticalLayout);
} }
private void unassignSW(final ClickEvent event, final DistributionSet distributionSet, private void unassignSW(final ClickEvent event, final DistributionSet distributionSet,

View File

@@ -8,16 +8,11 @@
*/ */
package org.eclipse.hawkbit.ui.components; package org.eclipse.hawkbit.ui.components;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource; import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.vaadin.server.ClientConnector.ConnectorErrorEvent; import com.vaadin.server.ClientConnector.ConnectorErrorEvent;
@@ -99,25 +94,17 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler {
LOG.error("Error in UI: ", ex); LOG.error("Error in UI: ", ex);
final String errorMessage = extractMessageFrom(ex); final String errorMessage = extractMessageFrom(ex);
final VaadinMessageSource i18n = SpringContextHelper.getBean(VaadinMessageSource.class); final VaadinMessageSource i18n = SpringContextHelper.getBean(VaadinMessageSource.class);
return new HawkbitErrorNotificationMessage(STYLE, i18n.getMessage("caption.error"),
i18n.getMessage("message.error.temp", errorMessage), false); return new HawkbitErrorNotificationMessage(STYLE, i18n.getMessage("caption.error"), errorMessage, true);
} }
private String extractMessageFrom(final Throwable ex) { private static String extractMessageFrom(final Throwable ex) {
if (!(ex instanceof ConstraintViolation)) { if (!StringUtils.isEmpty(ex.getMessage())) {
return ex.getClass().getSimpleName(); return ex.getMessage();
} }
final Set<ConstraintViolation<?>> violations = ((ConstraintViolationException) ex).getConstraintViolations(); return ex.getClass().getSimpleName();
if (violations == null) {
return ex.getClass().getSimpleName();
}
return violations.stream().map(violation -> violation.getPropertyPath() + " " + violation.getMessage())
.collect(Collectors.joining(System.lineSeparator()));
} }
} }

View File

@@ -206,7 +206,7 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_LAST_MODIFIED_AT, Long.class, null, true, true); rawCont.addContainerProperty(ProxyAction.PXY_ACTION_LAST_MODIFIED_AT, Long.class, null, true, true);
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_STATUS, Action.Status.class, null, true, false); rawCont.addContainerProperty(ProxyAction.PXY_ACTION_STATUS, Action.Status.class, null, true, false);
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ID, Long.class, null, true, true); rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ID, String.class, null, true, true);
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ROLLOUT_NAME, String.class, null, true, true); rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ROLLOUT_NAME, String.class, null, true, true);
} }

View File

@@ -77,6 +77,7 @@ import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Validator; import com.vaadin.data.Validator;
import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.util.converter.StringToIntegerConverter;
import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.data.validator.LongRangeValidator;
import com.vaadin.data.validator.NullValidator; import com.vaadin.data.validator.NullValidator;
import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.ComboBox; import com.vaadin.ui.ComboBox;
@@ -99,6 +100,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private static final String MESSAGE_ROLLOUT_FIELD_VALUE_RANGE = "message.rollout.field.value.range"; private static final String MESSAGE_ROLLOUT_FIELD_VALUE_RANGE = "message.rollout.field.value.range";
private static final String MESSAGE_ROLLOUT_FILTER_TARGET_EXISTS = "message.rollout.filter.target.exists";
private static final String MESSAGE_ENTER_NUMBER = "message.enter.number"; private static final String MESSAGE_ENTER_NUMBER = "message.enter.number";
private final ActionTypeOptionGroupLayout actionTypeOptionGroupLayout; private final ActionTypeOptionGroupLayout actionTypeOptionGroupLayout;
@@ -201,6 +204,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
* Save or update the rollout. * Save or update the rollout.
*/ */
private final class SaveOnDialogCloseListener implements SaveDialogCloseListener { private final class SaveOnDialogCloseListener implements SaveDialogCloseListener {
@Override @Override
public void saveOrUpdate() { public void saveOrUpdate() {
if (editRolloutEnabled) { if (editRolloutEnabled) {
@@ -267,8 +271,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
private boolean duplicateCheckForEdit() { private boolean duplicateCheckForEdit() {
final String rolloutNameVal = getRolloutName(); final String rolloutNameVal = getRolloutName();
if (!rollout.getName().equals(rolloutNameVal) if (!rollout.getName().equals(rolloutNameVal) && rolloutManagement.getByName(rolloutNameVal).isPresent()) {
&& rolloutManagement.getByName(rolloutNameVal).isPresent()) {
uiNotification uiNotification
.displayValidationError(i18n.getMessage("message.rollout.duplicate.check", rolloutNameVal)); .displayValidationError(i18n.getMessage("message.rollout.duplicate.check", rolloutNameVal));
return false; return false;
@@ -344,6 +347,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
return (AutoStartOptionGroupLayout.AutoStartOption) autoStartOptionGroupLayout.getAutoStartOptionGroup() return (AutoStartOptionGroupLayout.AutoStartOption) autoStartOptionGroupLayout.getAutoStartOptionGroup()
.getValue(); .getValue();
} }
} }
CommonDialogWindow getWindow(final Long rolloutId, final boolean copy) { CommonDialogWindow getWindow(final Long rolloutId, final boolean copy) {
@@ -443,6 +447,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2);
addComponent(targetFilterQueryCombo, 1, 2); addComponent(targetFilterQueryCombo, 1, 2);
targetFilterQueryCombo.addValidator(nullValidator); targetFilterQueryCombo.addValidator(nullValidator);
targetFilterQueryCombo.addValidator(new TargetExistsValidator());
targetFilterQuery.removeValidator(nullValidator); targetFilterQuery.removeValidator(nullValidator);
addComponent(getLabel("textfield.description"), 0, 3); addComponent(getLabel("textfield.description"), 0, 3);
@@ -734,8 +739,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
} }
private void populateTargetFilterQuery(final Rollout rollout) { private void populateTargetFilterQuery(final Rollout rollout) {
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findByQuery(new PageRequest(0, 1),
.findByQuery(new PageRequest(0, 1), rollout.getTargetFilterQuery()); rollout.getTargetFilterQuery());
if (filterQueries.getTotalElements() > 0) { if (filterQueries.getTotalElements() > 0) {
final TargetFilterQuery filterQuery = filterQueries.getContent().get(0); final TargetFilterQuery filterQuery = filterQueries.getContent().get(0);
targetFilterQueryCombo.setValue(filterQuery.getName()); targetFilterQueryCombo.setValue(filterQuery.getName());
@@ -868,6 +873,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
return (int) Math.ceil((double) totalTargetsCount / Double.parseDouble(noOfGroups.getValue())); return (int) Math.ceil((double) totalTargetsCount / Double.parseDouble(noOfGroups.getValue()));
} }
class TargetExistsValidator implements Validator {
private static final long serialVersionUID = 1L;
@Override
public void validate(final Object value) {
if (value != null) {
new LongRangeValidator(i18n.getMessage(MESSAGE_ROLLOUT_FILTER_TARGET_EXISTS), 1L, null)
.validate(totalTargetsCount);
}
}
}
class ThresholdFieldValidator implements Validator { class ThresholdFieldValidator implements Validator {
private static final long serialVersionUID = 9049939751976326550L; private static final long serialVersionUID = 9049939751976326550L;
@@ -936,10 +953,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
window.updateAllComponents(this); window.updateAllComponents(this);
window.setOrginaleValues(); window.setOrginaleValues();
updateGroupsChart( updateGroupsChart(rolloutGroupManagement
rolloutGroupManagement.findByRollout(new PageRequest(0, quotaManagement.getMaxRolloutGroupsPerRollout()), .findByRollout(new PageRequest(0, quotaManagement.getMaxRolloutGroupsPerRollout()), rollout.getId())
rollout.getId()).getContent(), .getContent(), rollout.getTotalTargets());
rollout.getTotalTargets());
} }
totalTargetsCount = targetManagement.countByRsql(rollout.getTargetFilterQuery()); totalTargetsCount = targetManagement.countByRsql(rollout.getTargetFilterQuery());

View File

@@ -556,6 +556,7 @@ message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value
message.correct.invalid.value = Please correct invalid values message.correct.invalid.value = Please correct invalid values
message.enter.number = Please enter number message.enter.number = Please enter number
message.rollout.field.value.range = Value should be in range {0} to {1} message.rollout.field.value.range = Value should be in range {0} to {1}
message.rollout.filter.target.exists = The selected target filter does not match any existing target
message.rollout.started = Rollout {0} started successfully message.rollout.started = Rollout {0} started successfully
message.rollout.paused = Rollout {0} paused successfully message.rollout.paused = Rollout {0} paused successfully
message.rollout.resumed = Rollout {0} resumed successfully message.rollout.resumed = Rollout {0} resumed successfully