diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.java index bdb844a1ded..07bfec9b507 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.java @@ -13,13 +13,25 @@ package org.eclipse.kura.web.client.ui.settings; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; +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 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; @@ -30,77 +42,174 @@ public class SnapshotDownloadModal extends Composite { private static SnapshotDownloadModalUiBinder uiBinder = GWT.create(SnapshotDownloadModalUiBinder.class); - // private static final Logger logger = Logger.getLogger(SnapshotDownloadModal.class.getSimpleName()); + + private static final String SELECT_ALL_PIDS_SELECTION = "Select All Pids"; + private static final String REMOVE_ALL_PIDS_SELECTION = "Remove All Pids"; + private static final List DEFAULT_PID_SELECTION = Arrays.asList("org.eclipse.kura.cloud.CloudService", + "org.eclipse.kura.internal.rest.provider.RestService", + "org.eclipse.kura.net.admin.FirewallConfigurationService", + "org.eclipse.kura.net.admin.NetworkConfigurationService", + "org.eclipse.kura.net.admin.ipv6.FirewallConfigurationServiceIPv6", "org.eclipse.kura.web.Console"); interface SnapshotDownloadModalUiBinder extends UiBinder { } - private List snapshotConfigs = new ArrayList<>(); - @UiField ScrollPanel scrollPanel; @UiField + Anchor resetColumnsAnchor; + @UiField Modal modal; @UiField Button downloadXml; @UiField Button downloadJson; + @UiField + FormLabel noPidSelectedError; VerticalPanel pidPanel = new VerticalPanel(); - private Listener listener = format -> { - }; + Consumer snapshotDownloadConsumer; public SnapshotDownloadModal() { initWidget(uiBinder.createAndBindUi(this)); - initPidList(); + this.scrollPanel.setVisible(false); - initScrollPanel(); + this.noPidSelectedError.setVisible(false); + this.noPidSelectedError.setText("Please select at least one pid from the list"); + + initResetAnchor(); + initDownloadButtons(); + + } + + private void initDownloadButtons() { this.downloadJson.addClickHandler(e -> { - this.modal.hide(); - this.listener.onDonwload("TEST"); + if (isOnePidSelected()) { + this.modal.hide(); + this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("JSON", getSelectedPids())); + } else { + this.noPidSelectedError.setVisible(true); + } + }); this.downloadXml.addClickHandler(e -> { - this.modal.hide(); - this.listener.onDonwload("TEST"); + if (isOnePidSelected()) { + this.modal.hide(); + this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("XML", getSelectedPids())); + } else { + this.noPidSelectedError.setVisible(true); + } }); } - private void initPidList() { + private void initResetAnchor() { + this.resetColumnsAnchor.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + + pidPanel.iterator().forEachRemaining(widget -> { + CheckBox checkBox = (CheckBox) widget; + if (DEFAULT_PID_SELECTION.contains(checkBox.getText())) { + checkBox.setValue(true); + } else { + checkBox.setValue(false); + } + }); + } + }); + } + + private void initPidList(List snapshotConfigs) { this.pidPanel.clear(); - this.snapshotConfigs.forEach(pid -> { + List orderedPids = snapshotConfigs.stream().sorted().collect(Collectors.toList()); + orderedPids.forEach(pid -> { CheckBox box = new CheckBox(pid); this.pidPanel.add(box); }); + + CheckBox selectAll = new CheckBox(SELECT_ALL_PIDS_SELECTION); + selectAll.addValueChangeHandler(new ValueChangeHandler() { + + @Override + public void onValueChange(ValueChangeEvent event) { + + Iterator widgetIterator = pidPanel.iterator(); + + widgetIterator.forEachRemaining(widget -> { + + 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 (isSelectOrRemoveAll && event.getValue().booleanValue()) { + checkBox.setText(REMOVE_ALL_PIDS_SELECTION); + } else if (isSelectOrRemoveAll && !event.getValue().booleanValue()) { + checkBox.setText(SELECT_ALL_PIDS_SELECTION); + } + }); + } + }); + + this.pidPanel.insert(selectAll, 0); } private void initScrollPanel() { this.scrollPanel.setAlwaysShowScrollBars(false); - this.scrollPanel.setHeight("500px"); + this.scrollPanel.setHeight("350px"); this.scrollPanel.clear(); this.scrollPanel.add(pidPanel); + this.scrollPanel.setVerticalScrollPosition(1); + this.scrollPanel.setVisible(true); } - public void show(final Listener listener) { - this.listener = listener; - initPidList(); - this.modal.show(); - } + private Optional> getSelectedPids() { + List selectedPids = new ArrayList<>(); + this.pidPanel.iterator().forEachRemaining(pid -> { + CheckBox checkBox = (CheckBox) pid; + if (checkBox.getValue().booleanValue()) { + selectedPids.add(checkBox.getText()); + } + }); - public interface Listener { + return selectedPids.isEmpty() ? Optional.empty() : Optional.of(selectedPids); + } - public void onDonwload(String format); + private boolean isOnePidSelected() { + boolean result = false; + Iterator pidPanelIterator = this.pidPanel.iterator(); + while (pidPanelIterator.hasNext()) { + CheckBox box = (CheckBox) pidPanelIterator.next(); + if (box.getValue().booleanValue()) { + result = true; + break; + } + } + + return result; } - public void setSnapshotConfigurations(List configs) { - this.snapshotConfigs = configs; + public void show(Consumer consumer) { + this.snapshotDownloadConsumer = consumer; + this.scrollPanel.setVisible(false); + this.modal.show(); + } + public void show(Consumer consumer, List availablePids) { + this.snapshotDownloadConsumer = consumer; + this.noPidSelectedError.setVisible(false); + initPidList(availablePids); + initScrollPanel(); + this.modal.show(); } } diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.ui.xml b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.ui.xml index a6b3d834a48..b03339800f8 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.ui.xml +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotDownloadModal.ui.xml @@ -22,6 +22,15 @@ + + .channel-name-validation-label { + padding-top: 5px; + color: red; + font-size: 0.35cm; + font-weight: normal; + } + + @@ -29,9 +38,11 @@ + + diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotsTabUi.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotsTabUi.java index aa85289e9e6..b6580688cf6 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotsTabUi.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/settings/SnapshotsTabUi.java @@ -363,16 +363,20 @@ public void onFailure(Throwable ex) { @Override public void onSuccess(List configs) { - downloadModal.setSnapshotConfigurations(configs); - downloadModal.show(format -> { + downloadModal.show(snapshotDownloadOptions -> { + sbUrl.append("/device_snapshots?snapshotId=").append(snapshot).append("&format=") - .append(format); + .append(snapshotDownloadOptions.getFormat()); - DownloadHelper.instance().startDownload(token, sbUrl.toString()); - }); + if (snapshotDownloadOptions.getSelectedPids().isPresent()) { + DownloadHelper.instance().startDownload(token, sbUrl.toString(), + snapshotDownloadOptions.getSelectedPids().get()); + } else { + DownloadHelper.instance().startDownload(token, sbUrl.toString()); + } + }, configs); } }); - } private void uploadAndApply() { diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/SnapshotDownloadOptions.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/SnapshotDownloadOptions.java new file mode 100644 index 00000000000..152223cf797 --- /dev/null +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/SnapshotDownloadOptions.java @@ -0,0 +1,30 @@ +package org.eclipse.kura.web.client.ui.wires; + +import java.util.List; +import java.util.Optional; + +public class SnapshotDownloadOptions { + + private String format; + private Optional> selectedPids; + + public SnapshotDownloadOptions(String format, Optional> selectedPids) { + super(); + this.format = format; + this.selectedPids = selectedPids; + } + + public SnapshotDownloadOptions(String format) { + super(); + this.format = format; + this.selectedPids = Optional.empty(); + } + + public String getFormat() { + return this.format; + } + + public Optional> getSelectedPids() { + return selectedPids; + } +} diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/WiresRPC.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/WiresRPC.java index d1d35ec2a93..2e4a02b4488 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/WiresRPC.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/ui/wires/WiresRPC.java @@ -219,7 +219,7 @@ public void onSuccess(GwtConfigComponent result) { }); } - public static void downloadWiresSnapshot(final String format) { + public static void downloadWiresSnapshot(final SnapshotDownloadOptions snapshotDownloadOptions) { EntryClassUi.showWaitModal(); gwtXSRFService.generateSecurityToken(new AsyncCallback() { @@ -232,7 +232,8 @@ public void onFailure(Throwable ex) { @Override public void onSuccess(GwtXSRFToken token) { EntryClassUi.hideWaitModal(); - DownloadHelper.instance().startDownload(token, "/wiresSnapshot?format=" + format); + DownloadHelper.instance().startDownload(token, + "/wiresSnapshot?format=" + snapshotDownloadOptions.getFormat()); } }); } diff --git a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/util/DownloadHelper.java b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/util/DownloadHelper.java index 29c0ef3f9f8..edad53a8ad0 100644 --- a/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/util/DownloadHelper.java +++ b/kura/org.eclipse.kura.web2/src/main/java/org/eclipse/kura/web/client/util/DownloadHelper.java @@ -12,6 +12,9 @@ *******************************************************************************/ package org.eclipse.kura.web.client.util; +import java.util.List; +import java.util.logging.Logger; + import org.eclipse.kura.web.Console; import org.eclipse.kura.web.shared.model.GwtXSRFToken; @@ -21,6 +24,8 @@ public final class DownloadHelper { + private static final Logger logger = Logger.getLogger(DownloadHelper.class.getSimpleName()); + private static DownloadHelper instance; private Element downloadIframe; @@ -52,6 +57,18 @@ public void startDownload(GwtXSRFToken token, String resource) { startDownload(sbUrl.toString()); } + public void startDownload(GwtXSRFToken token, String resource, List selectedPids) { + final StringBuilder sbUrl = new StringBuilder(); + + 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"); + + startDownload(sbUrl.toString()); + } + public static DownloadHelper instance() { if (instance == null) { instance = new DownloadHelper(); diff --git a/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties b/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties index e6eb2b6b673..32aaae26f0f 100644 --- a/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties +++ b/kura/org.eclipse.kura.web2/src/main/resources/org/eclipse/kura/web/client/messages/Messages.properties @@ -308,10 +308,10 @@ 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=Download all the snapshot in XML or JSON format -deviceSnapshotDownloadModalPids=Or select which bundle configurations will be included in the snapshot +deviceSnapshotDownloadModalHint=Chose which service configurations will be included in the downloaded snapshot. downloadSnapshotXmlButton=Download as XML downloadSnapshotJsonButton=Download as JSON +downloadSnapshotResetSelection=Reset selection to default netIntro=Select a Network Interface and configure it. DHCP Server and NAT can be configured only for interfaces enabled for LAN usage. When applying your changes, your connection to the gateway may be lost depending on your network configuration changes. netInterfaceName=Interface Name