Skip to content

Commit

Permalink
feat(web2): partial snapshot download (#5617)
Browse files Browse the repository at this point in the history
* feat: first ui implementation of partial snapshot download

Signed-off-by: SimoneFiorani <[email protected]>

* feat: working frontend

Signed-off-by: SimoneFiorani <[email protected]>

* feat: feature completed

Signed-off-by: SimoneFiorani <[email protected]>

* feat: updated copyrights

Signed-off-by: SimoneFiorani <[email protected]>

* feat: changed anchor and added details

Signed-off-by: SimoneFiorani <[email protected]>

* Trigger Build

* feat: refactored both popups

Signed-off-by: SimoneFiorani <[email protected]>

* feat: added japanese translation of messages

Signed-off-by: SimoneFiorani <[email protected]>

* feat: updated wiregraph hint

Signed-off-by: SimoneFiorani <[email protected]>

---------

Signed-off-by: SimoneFiorani <[email protected]>
  • Loading branch information
sfiorani authored Dec 16, 2024
1 parent e2bc005 commit bddc863
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021 Eurotech and/or its affiliates and others
* Copyright (c) 2024 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -12,50 +12,250 @@
*******************************************************************************/
package org.eclipse.kura.web.client.ui.settings;

import java.util.ArrayList;
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.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.ListBox;
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.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class SnapshotDownloadModal extends Composite {

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

interface SnapshotDownloadModalUiBinder extends UiBinder<Widget, SnapshotDownloadModal> {
}

@UiField
Paragraph downloadModalDescription;
@UiField
Paragraph formatModalHint;
@UiField
ScrollPanel pidSelectionScrollPanel;
@UiField
Anchor selectOrRemoveAllAnchor;
@UiField
Modal modal;
@UiField
ListBox formatList;
Button downloadXml;
@UiField
Button downloadJson;
@UiField
Button download;
Button cancelButton;
@UiField
FormLabel noPidSelectedError;

boolean areAllPidsSelected = true;
VerticalPanel pidPanel = new VerticalPanel();

private Listener listener = format -> {
};
HandlerRegistration anchorClickHandler;

Consumer<SnapshotDownloadOptions> snapshotDownloadConsumer;

public SnapshotDownloadModal() {

initWidget(uiBinder.createAndBindUi(this));

this.download.addClickHandler(e -> {
this.pidSelectionScrollPanel.setVisible(false);
this.selectOrRemoveAllAnchor.setVisible(false);
this.noPidSelectedError.setVisible(false);

this.cancelButton.addClickHandler(this::onCancelClick);

}

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);
initSnapshotSelectAllAnchor();
initSnapshotScrollPanel();
initSnapshotDownloadButtons();
this.modal.show();
}

/*
* Snapshot Download Inits
*/

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.setValue(true);
box.addClickHandler(this::onCheckboxClick);
this.pidPanel.add(box);
});
}

private void initSnapshotSelectAllAnchor() {
if (this.anchorClickHandler != null) {
this.anchorClickHandler.removeHandler();
}
this.areAllPidsSelected = true;
this.selectOrRemoveAllAnchor.setText(MSGS.removeAllAnchorText());
this.anchorClickHandler = this.selectOrRemoveAllAnchor.addClickHandler(this::selectOrRemoveAllSelection);
this.selectOrRemoveAllAnchor.setVisible(true);
}

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

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);
}

});

this.downloadXml.addClickHandler(e -> {
if (isOnePidSelected()) {
this.modal.hide();
resetScrollPanel();
this.snapshotDownloadConsumer.accept(new SnapshotDownloadOptions("XML", getSelectedPids()));
} else {
this.noPidSelectedError.setVisible(true);
}
});
}

/*
* Wiregraph Snapshot Download Inits
*/

private void initWiregraphDownloadButtons() {

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

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

public void show(final Listener listener) {
this.listener = listener;
this.modal.show();
/*
* Utils
*/

private void onCheckboxClick(ClickEvent handler) {
if (noPidSelectedError.isVisible()) {
noPidSelectedError.setVisible(false);
}

checkAllPidsSelected();
updateSelectOrRemoveAllText();

}

public interface Listener {
private void onCancelClick(ClickEvent handler) {
this.modal.hide();
resetScrollPanel();
this.noPidSelectedError.setVisible(false);
}

private Optional<List<String>> getSelectedPids() {
List<String> selectedPids = new ArrayList<>();
this.pidPanel.iterator().forEachRemaining(pid -> {
CheckBox checkBox = (CheckBox) pid;
if (checkBox.getValue().booleanValue() && !checkBox.getText().equals(MSGS.selectAllAnchorText())
&& !checkBox.getText().equals(MSGS.removeAllAnchorText())) {
selectedPids.add(checkBox.getText());
}
});

return selectedPids.isEmpty() ? Optional.empty() : Optional.of(selectedPids);
}

private void selectOrRemoveAllSelection(ClickEvent handler) {
pidPanel.iterator().forEachRemaining(widget -> ((CheckBox) widget).setValue(!this.areAllPidsSelected));
this.areAllPidsSelected = !this.areAllPidsSelected;
updateSelectOrRemoveAllText();
}

private boolean isOnePidSelected() {
boolean result = false;
Iterator<Widget> pidPanelIterator = this.pidPanel.iterator();
while (pidPanelIterator.hasNext()) {
CheckBox box = (CheckBox) pidPanelIterator.next();
if (box.getValue().booleanValue()) {
result = true;
break;
}
}

return result;
}

private void checkAllPidsSelected() {
boolean areAllSelected = true;
Iterator<Widget> pidPanelIterator = this.pidPanel.iterator();
while (pidPanelIterator.hasNext()) {
if (!((CheckBox) pidPanelIterator.next()).getValue().booleanValue()) {
areAllSelected = false;
break;
}
}
this.areAllPidsSelected = areAllSelected;
}

private void updateSelectOrRemoveAllText() {
if (this.areAllPidsSelected) {
this.selectOrRemoveAllAnchor.setText(MSGS.removeAllAnchorText());
} else {
this.selectOrRemoveAllAnchor.setText(MSGS.selectAllAnchorText());
}
}

public void onDonwload(String format);
private void resetScrollPanel() {
this.pidSelectionScrollPanel.setVerticalScrollPosition(0);
this.pidSelectionScrollPanel.setHorizontalScrollPosition(0);
this.noPidSelectedError.setVisible(false);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!--
Copyright (c) 2021 Eurotech and/or its affiliates and others
Copyright (c) 2024 Eurotech and/or its affiliates and others
This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
Expand All @@ -22,24 +22,34 @@

<ui:with field="msgs" type="org.eclipse.kura.web.client.messages.Messages" />

<b:Modal closable="false" fade="true" dataBackdrop="STATIC" ui:field="modal" title="{msgs.deviceSnapshotDownloadModalTitle}">
<ui:style>
.channel-name-validation-label {
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">
<b:ModalBody>
<g:FormPanel>
<b:FieldSet>
<b:FormGroup>
<b.html:Paragraph text="{msgs.deviceSnapshotDownloadModalLabel}" />
<b:ListBox b:id="formatList" ui:field="formatList">
<g:item>XML</g:item>
<g:item>JSON</g:item>
</b:ListBox>
<b.html:Paragraph ui:field="downloadModalDescription" />
<b.html:Paragraph ui:field="formatModalHint" text="{msgs.formatDownloadHint}" />
<g:ScrollPanel ui:field="pidSelectionScrollPanel"></g:ScrollPanel>
<b:FormLabel addStyleNames="{style.channel-name-validation-label}" ui:field="noPidSelectedError" text="{msgs.downloadSnapshotError}" />
</b:FormGroup>
</b:FieldSet>
</g:FormPanel>
<b:Anchor ui:field="selectOrRemoveAllAnchor" />
</b:ModalBody>
<b:ModalFooter>
<b:Button addStyleNames="fa" type="PRIMARY" dataDismiss="MODAL" text="{msgs.cancelButton}" />
<b:Button addStyleNames="fa" type="PRIMARY" ui:field="download" text="{msgs.download}" />
<b:Button addStyleNames="fa" type="PRIMARY" ui:field= "cancelButton" text="{msgs.cancelButton}" />
<b:Button addStyleNames="fa" type="PRIMARY" ui:field="downloadJson" text="{msgs.downloadSnapshotJsonButton}" />
<b:Button addStyleNames="fa" type="PRIMARY" ui:field="downloadXml" text="{msgs.downloadSnapshotXmlButton}" />
</b:ModalFooter>
</b:Modal>

</ui:UiBinder>
</ui:UiBinder>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011, 2021 Eurotech and/or its affiliates and others
* Copyright (c) 2011, 2024 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand Down Expand Up @@ -350,16 +350,36 @@ 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(),
new AsyncCallback<List<String>>() {

downloadModal.show(format -> {
sbUrl.append("/device_snapshots?snapshotId=").append(snapshot).append("&format=").append(format);
@Override
public void onFailure(Throwable ex) {
FailureHandler.handle(ex);
}

DownloadHelper.instance().startDownload(token, sbUrl.toString());
});
@Override
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());
}
}, configs);
}
});
}

private void uploadAndApply() {
Expand Down
Loading

0 comments on commit bddc863

Please sign in to comment.