SimpleUI: improve dialogs and add delete confirmation dialog (#2401)

* simple-ui: add systematic prompt before deletion

Signed-off-by: Mohamed Zenadi <mohamed.zenadi@wattsense.com>

* simple-ui: fix the dialogs layouts

Signed-off-by: Mohamed Zenadi <mohamed.zenadi@wattsense.com>

---------

Signed-off-by: Mohamed Zenadi <mohamed.zenadi@wattsense.com>
This commit is contained in:
Mohamed Zenadi
2025-05-15 08:32:47 +02:00
committed by GitHub
parent 9c53858de6
commit c306ed2d4f
5 changed files with 62 additions and 45 deletions

View File

@@ -25,6 +25,7 @@ import jakarta.annotation.security.RolesAllowed;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.dependency.Uses;
@@ -237,15 +238,15 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
final Button cancel = Utils.tooltip(new Button("Cancel"), "Cancel (Esc)");
cancel.addClickListener(e -> close());
create.addClickShortcut(Key.ESCAPE);
final HorizontalLayout actions = new HorizontalLayout(create, cancel);
actions.setSizeFull();
actions.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
create.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
getFooter().add(cancel);
getFooter().add(create);
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
layout.setPadding(true);
layout.setSpacing(false);
layout.add(type, name, version, vendor, description, requiredMigrationStep, actions);
layout.add(type, name, version, vendor, description, requiredMigrationStep);
add(layout);
open();
}
@@ -304,7 +305,8 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
softwareModulesGrid.refreshGrid(false);
close();
});
add(addBtn);
addBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
getFooter().add(addBtn);
open();
}}.result(),
v -> {
@@ -324,9 +326,9 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
close();
});
finishBtn.addClickShortcut(Key.ENTER);
final HorizontalLayout finish = new HorizontalLayout(finishBtn);
finish.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
finish.setWidthFull();
finishBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
getFooter().add(finishBtn);
final HorizontalLayout addRemove = new HorizontalLayout(addRemoveControls);
addRemove.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
addRemove.setWidthFull();
@@ -334,7 +336,7 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
layout.setSpacing(false);
layout.add(softwareModulesGrid, addRemove, finish);
layout.add(softwareModulesGrid, addRemove);
add(layout);
}
}

View File

@@ -23,6 +23,7 @@ import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
import com.vaadin.flow.component.dependency.Uses;
@@ -31,7 +32,6 @@ import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.select.Select;
@@ -358,13 +358,13 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
errorThreshold.setSuffixComponent(percentSuffix);
create.setEnabled(false);
create.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
addCreateClickListener(hawkbitClient);
final Button cancel = Utils.tooltip(new Button("Cancel"), "Cancel (Esc)");
cancel.addClickListener(e -> close());
cancel.addClickShortcut(Key.ESCAPE);
final HorizontalLayout actions = new HorizontalLayout(create, cancel);
actions.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
actions.setSizeFull();
getFooter().add(cancel);
getFooter().add(create);
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
@@ -373,8 +373,7 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
name, distributionSet, targetFilter, description,
actionType, startType,
groupNumber, triggerThreshold, errorThreshold,
dynamic,
actions);
dynamic);
add(layout);
open();
}

View File

@@ -28,14 +28,13 @@ import jakarta.annotation.security.RolesAllowed;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Key;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.select.Select;
import com.vaadin.flow.component.textfield.TextArea;
@@ -269,20 +268,19 @@ public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
create.setEnabled(false);
addCreateClickListener(hawkbitClient);
create.addClickShortcut(Key.ENTER);
create.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
final Button cancel = Utils.tooltip(new Button("Cancel"), "Cancel (Esc)");
cancel.addClickListener(e -> close());
cancel.addClickShortcut(Key.ESCAPE);
final HorizontalLayout actions = new HorizontalLayout(create, cancel);
actions.setSizeFull();
actions.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
getFooter().add(cancel);
getFooter().add(create);
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
layout.setSpacing(false);
layout.add(
type, name, version, vendor, description, enableArtifactEncryption,
createDistributionSet, distType, distRequiredMigrationStep,
actions);
createDistributionSet, distType, distRequiredMigrationStep);
add(layout);
open();
}
@@ -373,11 +371,10 @@ public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
finishBtn.addClickListener(e -> close());
finishBtn.addClickShortcut(Key.ENTER);
finishBtn.setHeightFull();
final HorizontalLayout finish = new HorizontalLayout(finishBtn);
finish.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
finish.setWidthFull();
finishBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
getFooter().add(finishBtn);
final VerticalLayout layout = new VerticalLayout(artifactGrid, uploadBtn, finish);
final VerticalLayout layout = new VerticalLayout(artifactGrid, uploadBtn);
layout.setSizeFull();
layout.setSpacing(false);
add(layout);

View File

@@ -9,6 +9,7 @@
*/
package org.eclipse.hawkbit.ui.simple.view;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
@@ -17,10 +18,10 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.time.ZoneOffset;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.annotation.security.RolesAllowed;
@@ -61,7 +62,6 @@ import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
import org.springframework.util.ObjectUtils;
import java.util.stream.Collectors;
@PageTitle("Targets")
@Route(value = "targets", layout = MainLayout.class)
@@ -187,7 +187,6 @@ public class TargetView extends TableView<MgmtTarget, String> {
final Button saveBtn = Utils.tooltip(new Button(VaadinIcon.ARCHIVE.create()), "Save (Enter)");
saveBtn.addClickListener(e ->
new Utils.BaseDialog<Void>("Save Filter") {{
setHeight("40%");
final Button finishBtn = Utils.tooltip(new Button("Save"), "Save (Enter)");
final TextField name = Utils.textField(
Constants.NAME,
@@ -205,7 +204,8 @@ public class TargetView extends TableView<MgmtTarget, String> {
.getFilters(0, 30, null, null, null).getBody().getContent());
close();
});
add(name, finishBtn);
getFooter().add(finishBtn);
add(name);
open();
}});
saveBtn.addClickShortcut(Key.ENTER);
@@ -307,19 +307,18 @@ public class TargetView extends TableView<MgmtTarget, String> {
addCreateClickListener(register, hawkbitClient);
register.setEnabled(false);
register.addClickShortcut(Key.ENTER);
register.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
final Button cancel = Utils.tooltip(new Button("Cancel"), "Cancel (Esc)");
cancel.addClickListener(e -> close());
register.addClickShortcut(Key.ESCAPE);
final HorizontalLayout actions = new HorizontalLayout(register, cancel);
actions.setSizeFull();
actions.setPadding(true);
actions.setSpacing(true);
getFooter().add(cancel);
getFooter().add(register);
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
layout.setPadding(true);
layout.setSpacing(false);
layout.add(type, controllerId, name, description, actions);
layout.add(type, controllerId, name, description);
add(layout);
open();
}
@@ -372,19 +371,18 @@ public class TargetView extends TableView<MgmtTarget, String> {
actionType = Utils.actionTypeControls(forceTime);
assign.setEnabled(false);
assign.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
addAssignClickListener(hawkbitClient, selectedTargets);
final Button cancel = Utils.tooltip(new Button("Cancel"), "Cancel (Esc)");
cancel.addClickListener(e -> close());
cancel.addClickShortcut(Key.ESCAPE);
final HorizontalLayout actions = new HorizontalLayout(assign, cancel);
actions.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
actions.setSizeFull();
getFooter().add(cancel);
getFooter().add(assign);
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
layout.setSpacing(false);
layout.add(
distributionSet, actionType, actions);
layout.add(distributionSet, actionType);
add(layout);
open();
}

View File

@@ -17,15 +17,17 @@ import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import java.util.function.Function;
import org.eclipse.hawkbit.ui.simple.view.Constants;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
import org.eclipse.hawkbit.ui.simple.view.Constants;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.confirmdialog.ConfirmDialog;
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.Div;
@@ -105,16 +107,35 @@ public class Utils {
layout.add(addBtn);
}
if (removeHandler != null) {
final ConfirmDialog dialog = promptForDeleteConfirmation(removeHandler, selectionGrid);
final Button removeBtn = tooltip(new Button(VaadinIcon.MINUS.create()), "Remove");
removeBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_CONTRAST);
removeBtn.addClickListener(e -> removeHandler
.apply(selectionGrid)
.thenAccept(v -> selectionGrid.refreshGrid(false)));
removeBtn.addClickListener(e -> dialog.open());
layout.add(removeBtn);
}
return layout;
}
private static <T, ID> ConfirmDialog promptForDeleteConfirmation(Function<SelectionGrid<T, ID>, CompletionStage<Void>> removeHandler, SelectionGrid<T, ID> selectionGrid) {
final ConfirmDialog dialog = new ConfirmDialog();
dialog.setHeader("Confirm Deletion");
dialog.setText("Are you sure you want to delete the selected items? This action cannot be undone.");
dialog.setCancelable(true);
dialog.addCancelListener(event -> dialog.close());
dialog.setConfirmButtonTheme(ButtonVariant.LUMO_ERROR.getVariantName());
dialog.setConfirmText("Delete");
dialog.addConfirmListener(event -> {
removeHandler
.apply(selectionGrid)
.thenAccept(v -> selectionGrid.refreshGrid(false));
dialog.close();
});
return dialog;
}
public static <T> void remove(final Collection<T> remove, final Set<T> from, final Function<T, ?> idFn) {
remove.forEach(toRemove -> {
final Object id = idFn.apply(toRemove);
@@ -185,7 +206,7 @@ public class Utils {
protected BaseDialog(final String headerTitle) {
setHeaderTitle(headerTitle);
setHeightFull();
setMinWidth(640, Unit.PIXELS);
setModal(true);
setDraggable(true);