simple_ui: add assign function in Target view

add assign function in Target view

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
Fin Maaß
2025-04-08 15:30:12 +02:00
parent 3481461536
commit 5a884661ed
2 changed files with 136 additions and 8 deletions

View File

@@ -16,7 +16,11 @@ import java.util.List;
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.Stream;
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.Key;
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.datetimepicker.DateTimePicker;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
@@ -34,11 +40,15 @@ 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.Text;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.PageTitle;
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.target.MgmtTarget;
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
@@ -91,6 +101,16 @@ public class TargetView extends TableView<MgmtTarget, String> {
hawkbitClient.getTargetRestApi().deleteTarget(toDelete.getControllerId()));
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 {
@@ -325,4 +345,99 @@ 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 = 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();
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();
});
}
}
}

View File

@@ -15,8 +15,12 @@ import java.util.function.Function;
import java.util.stream.Stream;
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.data.provider.Query;
import com.vaadin.flow.theme.lumo.LumoUtility;
import org.eclipse.hawkbit.ui.simple.view.Constants;
@SuppressWarnings("java:S119") // better readability
@@ -24,16 +28,19 @@ public class TableView<T, ID> extends Div implements Constants {
protected SelectionGrid<T, ID> selectionGrid;
private final Filter filter;
final VerticalLayout gridLayout;
protected final HorizontalLayout controlsLayout;
public TableView(
final Filter.Rsql rsql,
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
this(rsql, null, entityRepresentation, queryFn, null, null);
this(rsql, null, entityRepresentation, queryFn);
}
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 BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
this(rsql, alternativeRsql, entityRepresentation, queryFn, null, null);
@@ -59,13 +66,19 @@ public class TableView<T, ID> extends Div implements Constants {
setSizeFull();
final VerticalLayout layout = new VerticalLayout(filter, selectionGrid);
layout.setSizeFull();
layout.setPadding(false);
layout.setSpacing(false);
gridLayout = new VerticalLayout(filter, selectionGrid);
gridLayout.setSizeFull();
gridLayout.setPadding(false);
gridLayout.setSpacing(false);
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);
}
}