Skip to content

Commit

Permalink
feat: feature completed
Browse files Browse the repository at this point in the history
Signed-off-by: SimoneFiorani <[email protected]>
  • Loading branch information
sfiorani committed Dec 13, 2024
1 parent acce55f commit d32ecad
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.eclipse.kura.web.client.messages.Messages;
import org.eclipse.kura.web.client.ui.wires.SnapshotDownloadOptions;
import org.gwtbootstrap3.client.ui.Anchor;
import org.gwtbootstrap3.client.ui.Button;
import org.gwtbootstrap3.client.ui.CheckBox;
import org.gwtbootstrap3.client.ui.FormLabel;
import org.gwtbootstrap3.client.ui.Modal;
import org.gwtbootstrap3.client.ui.html.Paragraph;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
Expand All @@ -42,6 +42,7 @@
public class SnapshotDownloadModal extends Composite {

private static SnapshotDownloadModalUiBinder uiBinder = GWT.create(SnapshotDownloadModalUiBinder.class);
private static final Messages MSGS = GWT.create(Messages.class);

private static final String SELECT_ALL_PIDS_SELECTION = "Select All Pids";
private static final String REMOVE_ALL_PIDS_SELECTION = "Remove All Pids";
Expand All @@ -55,9 +56,11 @@ interface SnapshotDownloadModalUiBinder extends UiBinder<Widget, SnapshotDownloa
}

@UiField
ScrollPanel scrollPanel;
Paragraph downloadModalDescription;
@UiField
Anchor resetColumnsAnchor;
ScrollPanel pidSelectionScrollPanel;
@UiField
Anchor resetPidSelection;
@UiField
Modal modal;
@UiField
Expand All @@ -75,21 +78,51 @@ public SnapshotDownloadModal() {

initWidget(uiBinder.createAndBindUi(this));

this.scrollPanel.setVisible(false);

this.pidSelectionScrollPanel.setVisible(false);
this.resetPidSelection.setVisible(false);
this.noPidSelectedError.setVisible(false);
this.noPidSelectedError.setText("Please select at least one pid from the list");

initResetAnchor();
}

initDownloadButtons();
public void show(Consumer<SnapshotDownloadOptions> consumer) {
this.snapshotDownloadConsumer = consumer;
this.modal.setTitle(MSGS.deviceWiregraphDownloadModalTitle());
this.downloadModalDescription.setText(MSGS.deviceWiregraphDownloadModalHint());
initWiregraphDownloadButtons();
this.modal.show();
}

public void show(Consumer<SnapshotDownloadOptions> consumer, List<String> availablePids) {
this.snapshotDownloadConsumer = consumer;
this.noPidSelectedError.setVisible(false);
this.modal.setTitle(MSGS.deviceSnapshotDownloadModalTitle());
this.downloadModalDescription.setText(MSGS.deviceSnapshotDownloadModalHint());
initSnapshotPidList(availablePids);
initSnapshotScrollPanel();
initSnapshotDownloadButtons();
initSnapshotResetAnchor();
this.modal.show();
}

private void initDownloadButtons() {
private void initWiregraphDownloadButtons() {

this.downloadJson.addClickHandler(e -> {
this.modal.hide();
this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("JSON"));
});

this.downloadXml.addClickHandler(e -> {
this.modal.hide();
this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("XML"));
});
}

private void initSnapshotDownloadButtons() {
this.downloadJson.addClickHandler(e -> {
if (isOnePidSelected()) {
this.modal.hide();
resetScrollPanel();
this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("JSON", getSelectedPids()));
} else {
this.noPidSelectedError.setVisible(true);
Expand All @@ -100,83 +133,84 @@ private void initDownloadButtons() {
this.downloadXml.addClickHandler(e -> {
if (isOnePidSelected()) {
this.modal.hide();
resetScrollPanel();
this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("XML", getSelectedPids()));
} else {
this.noPidSelectedError.setVisible(true);
}
});
}

private void initResetAnchor() {
this.resetColumnsAnchor.addClickHandler(new ClickHandler() {

@Override
public void onClick(ClickEvent event) {
private void initSnapshotResetAnchor() {
this.resetPidSelection.addClickHandler(event -> {

pidPanel.iterator().forEachRemaining(widget -> {
CheckBox checkBox = (CheckBox) widget;
if (DEFAULT_PID_SELECTION.contains(checkBox.getText())) {
checkBox.setValue(true);
} else {
checkBox.setValue(false);
}
});
}
pidPanel.iterator().forEachRemaining(widget -> {
CheckBox checkBox = (CheckBox) widget;
checkBox.setValue(DEFAULT_PID_SELECTION.contains(checkBox.getText()));
});
});
}

private void initPidList(List<String> snapshotConfigs) {
private void initSnapshotPidList(List<String> snapshotConfigs) {

this.pidPanel.clear();

List<String> orderedPids = snapshotConfigs.stream().sorted().collect(Collectors.toList());
orderedPids.forEach(pid -> {
CheckBox box = new CheckBox(pid);
box.addClickHandler(this::hideErrorMessageOnSelection);
this.pidPanel.add(box);
});

CheckBox selectAll = new CheckBox(SELECT_ALL_PIDS_SELECTION);
selectAll.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
CheckBox allChannelsButton = new CheckBox(SELECT_ALL_PIDS_SELECTION);
allChannelsButton.addValueChangeHandler(this::selectOrRemoveAllSelection);
allChannelsButton.addClickHandler(this::hideErrorMessageOnSelection);
this.pidPanel.insert(allChannelsButton, 0);

@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
}

Iterator<Widget> widgetIterator = pidPanel.iterator();
private void hideErrorMessageOnSelection(ClickEvent handler) {
if (noPidSelectedError.isVisible()) {
noPidSelectedError.setVisible(false);
}
}

private void selectOrRemoveAllSelection(ValueChangeEvent<Boolean> event) {
Iterator<Widget> widgetIterator = pidPanel.iterator();

widgetIterator.forEachRemaining(widget -> {
widgetIterator.forEachRemaining(widget -> {

CheckBox checkBox = (CheckBox) widget;
checkBox.setValue(event.getValue());
CheckBox checkBox = (CheckBox) widget;
checkBox.setValue(event.getValue());

boolean isSelectOrRemoveAll = checkBox.getText().equals(SELECT_ALL_PIDS_SELECTION)
|| checkBox.getText().equals(REMOVE_ALL_PIDS_SELECTION);
if (checkBox.getText().equals(SELECT_ALL_PIDS_SELECTION)
|| checkBox.getText().equals(REMOVE_ALL_PIDS_SELECTION)) {

if (isSelectOrRemoveAll && event.getValue().booleanValue()) {
checkBox.setText(REMOVE_ALL_PIDS_SELECTION);
} else if (isSelectOrRemoveAll && !event.getValue().booleanValue()) {
checkBox.setText(SELECT_ALL_PIDS_SELECTION);
}
});
if (event.getValue().booleanValue()) {
checkBox.setText(REMOVE_ALL_PIDS_SELECTION);
} else {
checkBox.setText(SELECT_ALL_PIDS_SELECTION);
}
}
});

this.pidPanel.insert(selectAll, 0);
}

private void initScrollPanel() {
this.scrollPanel.setAlwaysShowScrollBars(false);
this.scrollPanel.setHeight("350px");
this.scrollPanel.clear();
this.scrollPanel.add(pidPanel);
this.scrollPanel.setVerticalScrollPosition(1);
this.scrollPanel.setVisible(true);
private void initSnapshotScrollPanel() {
this.pidSelectionScrollPanel.setAlwaysShowScrollBars(false);
this.pidSelectionScrollPanel.setHeight("350px");
this.pidSelectionScrollPanel.clear();
this.pidSelectionScrollPanel.add(pidPanel);
this.pidSelectionScrollPanel.setVisible(true);

this.resetPidSelection.setVisible(true);
}

private Optional<List<String>> getSelectedPids() {
List<String> selectedPids = new ArrayList<>();
this.pidPanel.iterator().forEachRemaining(pid -> {
CheckBox checkBox = (CheckBox) pid;
if (checkBox.getValue().booleanValue()) {
if (checkBox.getValue().booleanValue() && !checkBox.getText().equals(SELECT_ALL_PIDS_SELECTION)
&& !checkBox.getText().equals(REMOVE_ALL_PIDS_SELECTION)) {
selectedPids.add(checkBox.getText());
}
});
Expand All @@ -198,18 +232,10 @@ private boolean isOnePidSelected() {
return result;
}

public void show(Consumer<SnapshotDownloadOptions> consumer) {
this.snapshotDownloadConsumer = consumer;
this.scrollPanel.setVisible(false);
this.modal.show();
}

public void show(Consumer<SnapshotDownloadOptions> consumer, List<String> availablePids) {
this.snapshotDownloadConsumer = consumer;
private void resetScrollPanel() {
this.pidSelectionScrollPanel.setVerticalScrollPosition(0);
this.pidSelectionScrollPanel.setHorizontalScrollPosition(0);
this.noPidSelectedError.setVisible(false);
initPidList(availablePids);
initScrollPanel();
this.modal.show();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@

<ui:style>
.channel-name-validation-label {
padding-top: 5px;
padding-top: 10px;
color: red;
font-size: 0.35cm;
font-weight: normal;
}
</ui:style>

<b:Modal closable="false" fade="true" dataBackdrop="STATIC" ui:field="modal" title="{msgs.deviceSnapshotDownloadModalTitle}">
<b:Modal closable="false" fade="true" dataBackdrop="STATIC" ui:field="modal">
<b:ModalBody>
<g:FormPanel>
<b:FieldSet>
<b:FormGroup>
<b.html:Paragraph text="{msgs.deviceSnapshotDownloadModalHint}" />
<g:ScrollPanel ui:field="scrollPanel"></g:ScrollPanel>
<b.html:Paragraph ui:field="downloadModalDescription" />
<g:ScrollPanel ui:field="pidSelectionScrollPanel"></g:ScrollPanel>
<b:FormLabel addStyleNames="{style.channel-name-validation-label}" ui:field="noPidSelectedError" />
</b:FormGroup>
</b:FieldSet>
</g:FormPanel>
<b:Anchor text="{msgs.downloadSnapshotResetSelection}" ui:field="resetColumnsAnchor" />
<b:Anchor text="{msgs.downloadSnapshotResetSelection}" ui:field="resetPidSelection" />
</b:ModalBody>
<b:ModalFooter>
<b:Button addStyleNames="fa" type="PRIMARY" dataDismiss="MODAL" text="{msgs.cancelButton}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ public void onSuccess(Void result) {
}

private void downloadSnapshot(GwtXSRFToken token) {
final StringBuilder sbUrl = new StringBuilder();

Long snapshot = this.selected.getSnapshotId();
this.gwtSnapshotService.getSnapshotConfigurationFromSid(token, snapshot.longValue(),
Expand All @@ -365,12 +364,16 @@ public void onFailure(Throwable ex) {
public void onSuccess(List<String> configs) {
downloadModal.show(snapshotDownloadOptions -> {

final StringBuilder sbUrl = new StringBuilder();

sbUrl.append("/device_snapshots?snapshotId=").append(snapshot).append("&format=")
.append(snapshotDownloadOptions.getFormat());

if (snapshotDownloadOptions.getSelectedPids().isPresent()) {

DownloadHelper.instance().startDownload(token, sbUrl.toString(),
snapshotDownloadOptions.getSelectedPids().get());

} else {
DownloadHelper.instance().startDownload(token, sbUrl.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ public void startDownload(GwtXSRFToken token, String resource) {
public void startDownload(GwtXSRFToken token, String resource, List<String> selectedPids) {
final StringBuilder sbUrl = new StringBuilder();

final StringBuilder sbPids = new StringBuilder();
selectedPids.forEach(pid -> sbPids.append(pid + ","));
selectedPids.remove(selectedPids.size() - 1);

sbUrl.append(Console.ADMIN_ROOT).append("/").append(GWT.getModuleName()).append(resource)
.append(resource.indexOf('?') != -1 ? '&' : '?').append("xsrfToken=")
.append(URL.encodeQueryString(token.getToken()));

logger.info("\n\nPIDS: " + selectedPids + "\n\n");
.append(URL.encodeQueryString(token.getToken())).append("&selectedPids=").append(sbPids.toString());

startDownload(sbUrl.toString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
package org.eclipse.kura.web.server.servlet;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -42,7 +44,7 @@ public DeviceSnapshotsServlet() {

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
KuraRemoteServiceServlet.requirePermissions(request, Mode.ALL, new String[] { KuraPermission.ADMIN });
KuraRemoteServiceServlet.requirePermissions(request, Mode.ALL, new String[] { KuraPermission.ADMIN });

// BEGIN XSRF - Servlet dependent code

Expand All @@ -63,7 +65,20 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
if (snapshotId != null) {

long sid = Long.parseLong(snapshotId);
List<ComponentConfiguration> configs = cs.getSnapshot(sid);

List<ComponentConfiguration> configs;

String optionalSelectedPids = request.getParameter("selectedPids");
if (optionalSelectedPids != null) {

List<String> selectedPids = Arrays.asList(optionalSelectedPids.split(","));
configs = cs.getSnapshot(sid).stream().filter(config -> {
return selectedPids.contains(config.getPid());
}).collect(Collectors.toList());

} else {
configs = cs.getSnapshot(sid);
}

GwtServerUtil.writeSnapshot(request, response, configs, "snapshot_" + sid);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ deviceSnapshotCreatedOn=Created On
deviceSnapshotsNone=No Snapshots Available
deviceSnapshotRollbackConfirm=Are you sure you want to rollback to a previous configuration? During the rollback operation, the device will disconnect and reconnect. If a timeout is encountered during the reload of the device configuration, please refresh it manually.
deviceSnapshotDownloadModalTitle=Download snapshot
deviceSnapshotDownloadModalHint=Chose which service configurations will be included in the downloaded snapshot.
deviceWiregraphDownloadModalTitle=Download wiregraph
deviceSnapshotDownloadModalHint=Chose the format and which service configurations will be included in the downloaded snapshot.
deviceWiregraphDownloadModalHint=Chose in which format the wiregraph will be downloaded.
downloadSnapshotXmlButton=Download as XML
downloadSnapshotJsonButton=Download as JSON
downloadSnapshotResetSelection=Reset selection to default
Expand Down

0 comments on commit d32ecad

Please sign in to comment.