Merge pull request #2346 from maass-hamburg/simple_ui_add_assign_targets
simple_ui: add assign function in Target view
This commit is contained in:
@@ -318,26 +318,8 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
description.setMinLength(2);
|
description.setMinLength(2);
|
||||||
description.setWidthFull();
|
description.setWidthFull();
|
||||||
|
|
||||||
actionType = new Select<>();
|
actionType = Utils.actionTypeControls(forceTime);
|
||||||
actionType.setLabel(Constants.ACTION_TYPE);
|
|
||||||
actionType.setItems(MgmtActionType.values());
|
|
||||||
actionType.setValue(MgmtActionType.FORCED);
|
|
||||||
final ComponentRenderer<Component, MgmtActionType> actionTypeRenderer = new ComponentRenderer<>(actionTypeO ->
|
|
||||||
switch (actionTypeO) {
|
|
||||||
case SOFT -> new Text(Constants.SOFT);
|
|
||||||
case FORCED -> new Text(Constants.FORCED);
|
|
||||||
case DOWNLOAD_ONLY -> new Text(Constants.DOWNLOAD_ONLY);
|
|
||||||
case TIMEFORCED -> forceTime;
|
|
||||||
});
|
|
||||||
actionType.addValueChangeListener(e -> actionType.setRenderer(actionTypeRenderer));
|
|
||||||
actionType.setItemLabelGenerator(startTypeO ->
|
|
||||||
switch (startTypeO) {
|
|
||||||
case SOFT -> Constants.SOFT;
|
|
||||||
case FORCED -> Constants.FORCED;
|
|
||||||
case DOWNLOAD_ONLY -> Constants.DOWNLOAD_ONLY;
|
|
||||||
case TIMEFORCED -> "Time Forced at " + (forceTime.isEmpty() ? "" : " " + forceTime.getValue());
|
|
||||||
});
|
|
||||||
actionType.setWidthFull();
|
|
||||||
startType = new Select<>();
|
startType = new Select<>();
|
||||||
startType.setValue(StartType.MANUAL);
|
startType.setValue(StartType.MANUAL);
|
||||||
startType.setLabel(Constants.START_TYPE);
|
startType.setLabel(Constants.START_TYPE);
|
||||||
|
|||||||
@@ -16,7 +16,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionStage;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
@@ -24,7 +28,9 @@ import jakarta.annotation.security.RolesAllowed;
|
|||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
import com.vaadin.flow.component.checkbox.CheckboxGroup;
|
import com.vaadin.flow.component.checkbox.CheckboxGroup;
|
||||||
|
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
||||||
import com.vaadin.flow.component.dependency.Uses;
|
import com.vaadin.flow.component.dependency.Uses;
|
||||||
import com.vaadin.flow.component.formlayout.FormLayout;
|
import com.vaadin.flow.component.formlayout.FormLayout;
|
||||||
import com.vaadin.flow.component.grid.Grid;
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
@@ -39,6 +45,9 @@ import com.vaadin.flow.component.textfield.TextField;
|
|||||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentRequestBody;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
||||||
@@ -91,6 +100,16 @@ public class TargetView extends TableView<MgmtTarget, String> {
|
|||||||
hawkbitClient.getTargetRestApi().deleteTarget(toDelete.getControllerId()));
|
hawkbitClient.getTargetRestApi().deleteTarget(toDelete.getControllerId()));
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Function<SelectionGrid<MgmtTarget, String>, CompletionStage<Void>> assignHandler = source -> new AssignDialog(
|
||||||
|
hawkbitClient, source.getSelectedItems()).result();
|
||||||
|
|
||||||
|
final Button assignBtn = Utils.tooltip(new Button(VaadinIcon.LINK.create()), "Assign");
|
||||||
|
assignBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
assignBtn.addClickListener(e -> assignHandler
|
||||||
|
.apply(selectionGrid)
|
||||||
|
.thenAccept(v -> selectionGrid.refreshGrid(false)));
|
||||||
|
controlsLayout.addComponentAtIndex(0, assignBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SimpleFilter implements Filter.Rsql {
|
private static class SimpleFilter implements Filter.Rsql {
|
||||||
@@ -325,4 +344,80 @@ public class TargetView extends TableView<MgmtTarget, String> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class AssignDialog extends Utils.BaseDialog<Void> {
|
||||||
|
|
||||||
|
private final Select<MgmtDistributionSet> distributionSet;
|
||||||
|
private final Select<MgmtActionType> actionType;
|
||||||
|
private final DateTimePicker forceTime = new DateTimePicker("Force Time");
|
||||||
|
private final Button assign = new Button("Assign");
|
||||||
|
|
||||||
|
private AssignDialog(final HawkbitMgmtClient hawkbitClient, Set<MgmtTarget> selectedTargets) {
|
||||||
|
super("Assign Distribution Set");
|
||||||
|
|
||||||
|
distributionSet = new Select<>(
|
||||||
|
"Distribution Set",
|
||||||
|
this::readyToAssign,
|
||||||
|
Optional.ofNullable(
|
||||||
|
hawkbitClient.getDistributionSetRestApi()
|
||||||
|
.getDistributionSets(0, 30, Constants.NAME_ASC, null)
|
||||||
|
.getBody())
|
||||||
|
.map(body -> body.getContent().toArray(new MgmtDistributionSet[0]))
|
||||||
|
.orElseGet(() -> new MgmtDistributionSet[0]));
|
||||||
|
distributionSet.setRequiredIndicatorVisible(true);
|
||||||
|
distributionSet.setItemLabelGenerator(distributionSetO ->
|
||||||
|
distributionSetO.getName() + ":" + distributionSetO.getVersion());
|
||||||
|
distributionSet.setWidthFull();
|
||||||
|
|
||||||
|
actionType = Utils.actionTypeControls(forceTime);
|
||||||
|
|
||||||
|
assign.setEnabled(false);
|
||||||
|
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();
|
||||||
|
|
||||||
|
final VerticalLayout layout = new VerticalLayout();
|
||||||
|
layout.setSizeFull();
|
||||||
|
layout.setSpacing(false);
|
||||||
|
layout.add(
|
||||||
|
distributionSet, actionType, actions);
|
||||||
|
add(layout);
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readyToAssign(final Object v) {
|
||||||
|
final boolean assignEnabled = !distributionSet.isEmpty();
|
||||||
|
if (assign.isEnabled() != assignEnabled) {
|
||||||
|
assign.setEnabled(assignEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAssignClickListener(final HawkbitMgmtClient hawkbitClient, final Set<MgmtTarget> selectedTargets) {
|
||||||
|
assign.addClickListener(e -> {
|
||||||
|
close();
|
||||||
|
List<MgmtTargetAssignmentRequestBody> requests = new LinkedList<MgmtTargetAssignmentRequestBody>();
|
||||||
|
|
||||||
|
for (final MgmtTarget target : selectedTargets) {
|
||||||
|
|
||||||
|
MgmtTargetAssignmentRequestBody request = new MgmtTargetAssignmentRequestBody(target.getControllerId());
|
||||||
|
|
||||||
|
request.setType(actionType.getValue());
|
||||||
|
if (actionType.getValue() == MgmtActionType.TIMEFORCED) {
|
||||||
|
request.setForcetime(
|
||||||
|
forceTime.isEmpty() ?
|
||||||
|
System.currentTimeMillis() :
|
||||||
|
forceTime.getValue().toEpochSecond(ZoneOffset.UTC) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
requests.add(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
hawkbitClient.getDistributionSetRestApi().createAssignedTarget(distributionSet.getValue().getId(), requests, null).getBody();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ import java.util.function.Function;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.vaadin.flow.component.html.Div;
|
import com.vaadin.flow.component.html.Div;
|
||||||
|
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.orderedlayout.VerticalLayout;
|
||||||
import com.vaadin.flow.data.provider.Query;
|
import com.vaadin.flow.data.provider.Query;
|
||||||
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.Constants;
|
import org.eclipse.hawkbit.ui.simple.view.Constants;
|
||||||
|
|
||||||
@SuppressWarnings("java:S119") // better readability
|
@SuppressWarnings("java:S119") // better readability
|
||||||
@@ -24,16 +28,19 @@ public class TableView<T, ID> extends Div implements Constants {
|
|||||||
|
|
||||||
protected SelectionGrid<T, ID> selectionGrid;
|
protected SelectionGrid<T, ID> selectionGrid;
|
||||||
private final Filter filter;
|
private final Filter filter;
|
||||||
|
final VerticalLayout gridLayout;
|
||||||
|
protected final HorizontalLayout controlsLayout;
|
||||||
|
|
||||||
public TableView(
|
public TableView(
|
||||||
final Filter.Rsql rsql,
|
final Filter.Rsql rsql,
|
||||||
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
||||||
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
||||||
this(rsql, null, entityRepresentation, queryFn, null, null);
|
this(rsql, null, entityRepresentation, queryFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableView(
|
public TableView(
|
||||||
final Filter.Rsql rsql, final Filter.Rsql alternativeRsql,
|
final Filter.Rsql rsql,
|
||||||
|
final Filter.Rsql alternativeRsql,
|
||||||
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
||||||
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
||||||
this(rsql, alternativeRsql, entityRepresentation, queryFn, null, null);
|
this(rsql, alternativeRsql, entityRepresentation, queryFn, null, null);
|
||||||
@@ -59,13 +66,19 @@ public class TableView<T, ID> extends Div implements Constants {
|
|||||||
|
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
|
|
||||||
final VerticalLayout layout = new VerticalLayout(filter, selectionGrid);
|
gridLayout = new VerticalLayout(filter, selectionGrid);
|
||||||
layout.setSizeFull();
|
gridLayout.setSizeFull();
|
||||||
layout.setPadding(false);
|
gridLayout.setPadding(false);
|
||||||
layout.setSpacing(false);
|
gridLayout.setSpacing(false);
|
||||||
if (addHandler != null || removeHandler != null) {
|
if (addHandler != null || removeHandler != null) {
|
||||||
layout.add(Utils.addRemoveControls(addHandler, removeHandler, selectionGrid, false));
|
controlsLayout = Utils.addRemoveControls(addHandler, removeHandler, selectionGrid, false);
|
||||||
|
} else {
|
||||||
|
controlsLayout = new HorizontalLayout();
|
||||||
|
controlsLayout.setWidthFull();
|
||||||
|
controlsLayout.addClassNames(LumoUtility.Padding.Horizontal.XLARGE, LumoUtility.Padding.Vertical.SMALL, LumoUtility.BoxSizing.BORDER);
|
||||||
|
controlsLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
|
||||||
}
|
}
|
||||||
add(layout);
|
gridLayout.add(controlsLayout);
|
||||||
|
add(gridLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ import java.util.concurrent.CompletionStage;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.Constants;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.HasValue;
|
import com.vaadin.flow.component.HasValue;
|
||||||
import com.vaadin.flow.component.Text;
|
import com.vaadin.flow.component.Text;
|
||||||
import com.vaadin.flow.component.UI;
|
import com.vaadin.flow.component.UI;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
import com.vaadin.flow.component.button.ButtonVariant;
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
||||||
import com.vaadin.flow.component.dialog.Dialog;
|
import com.vaadin.flow.component.dialog.Dialog;
|
||||||
import com.vaadin.flow.component.html.Div;
|
import com.vaadin.flow.component.html.Div;
|
||||||
import com.vaadin.flow.component.icon.VaadinIcon;
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
@@ -30,9 +34,11 @@ import com.vaadin.flow.component.notification.Notification;
|
|||||||
import com.vaadin.flow.component.notification.NotificationVariant;
|
import com.vaadin.flow.component.notification.NotificationVariant;
|
||||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.select.Select;
|
||||||
import com.vaadin.flow.component.shared.Tooltip;
|
import com.vaadin.flow.component.shared.Tooltip;
|
||||||
import com.vaadin.flow.component.textfield.NumberField;
|
import com.vaadin.flow.component.textfield.NumberField;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.data.value.ValueChangeMode;
|
import com.vaadin.flow.data.value.ValueChangeMode;
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
|
||||||
@@ -148,6 +154,31 @@ public class Utils {
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Select<MgmtActionType> actionTypeControls(DateTimePicker forceTime) {
|
||||||
|
|
||||||
|
Select<MgmtActionType> actionType = new Select<>();
|
||||||
|
actionType.setLabel(Constants.ACTION_TYPE);
|
||||||
|
actionType.setItems(MgmtActionType.values());
|
||||||
|
actionType.setValue(MgmtActionType.FORCED);
|
||||||
|
final ComponentRenderer<Component, MgmtActionType> actionTypeRenderer = new ComponentRenderer<>(actionTypeO ->
|
||||||
|
switch (actionTypeO) {
|
||||||
|
case SOFT -> new Text(Constants.SOFT);
|
||||||
|
case FORCED -> new Text(Constants.FORCED);
|
||||||
|
case DOWNLOAD_ONLY -> new Text(Constants.DOWNLOAD_ONLY);
|
||||||
|
case TIMEFORCED -> forceTime;
|
||||||
|
});
|
||||||
|
actionType.addValueChangeListener(e -> actionType.setRenderer(actionTypeRenderer));
|
||||||
|
actionType.setItemLabelGenerator(startTypeO ->
|
||||||
|
switch (startTypeO) {
|
||||||
|
case SOFT -> Constants.SOFT;
|
||||||
|
case FORCED -> Constants.FORCED;
|
||||||
|
case DOWNLOAD_ONLY -> Constants.DOWNLOAD_ONLY;
|
||||||
|
case TIMEFORCED -> "Time Forced at " + (forceTime.isEmpty() ? "" : " " + forceTime.getValue());
|
||||||
|
});
|
||||||
|
actionType.setWidthFull();
|
||||||
|
return actionType;
|
||||||
|
}
|
||||||
|
|
||||||
public static class BaseDialog<T> extends Dialog {
|
public static class BaseDialog<T> extends Dialog {
|
||||||
|
|
||||||
protected final transient CompletableFuture<T> result = new CompletableFuture<>();
|
protected final transient CompletableFuture<T> result = new CompletableFuture<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user