Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added pid filtering searchbox and selection counter in snapshot download popup #5627

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.eclipse.kura.web.client.ui.settings;

public enum PartialSnapshotCheckboxStatus {

ALL_VISIBLE_ALL_SELECTED,
ALL_VISIBLE_PARTIAL_SELECTED,
PARTIAL_VISIBLE_ALL_SELECTED,
PARTIAL_VISIBLE_PARTIAL_SELECTED;

public static PartialSnapshotCheckboxStatus fromVisibleAndSelectedStatus(boolean allVisible, boolean allSelected) {
if (allVisible) {
if (allSelected) {
return PartialSnapshotCheckboxStatus.ALL_VISIBLE_ALL_SELECTED;
} else {
return PartialSnapshotCheckboxStatus.ALL_VISIBLE_PARTIAL_SELECTED;
}
} else {
if (allSelected) {
return PartialSnapshotCheckboxStatus.PARTIAL_VISIBLE_ALL_SELECTED;
} else {
return PartialSnapshotCheckboxStatus.PARTIAL_VISIBLE_PARTIAL_SELECTED;
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@
import org.gwtbootstrap3.client.ui.CheckBox;
import org.gwtbootstrap3.client.ui.FormLabel;
import org.gwtbootstrap3.client.ui.Modal;
import org.gwtbootstrap3.client.ui.TextBox;
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.KeyUpEvent;
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.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
Expand All @@ -51,6 +54,12 @@ interface SnapshotDownloadModalUiBinder extends UiBinder<Widget, SnapshotDownloa
@UiField
Paragraph formatModalHint;
@UiField
Label searchBoxSeparatorSmall;
@UiField
TextBox pidSearch;
@UiField
Label searchBoxSeparatorBig;
@UiField
ScrollPanel pidSelectionScrollPanel;
@UiField
Anchor selectOrRemoveAllAnchor;
Expand All @@ -64,8 +73,9 @@ interface SnapshotDownloadModalUiBinder extends UiBinder<Widget, SnapshotDownloa
Button cancelButton;
@UiField
FormLabel noPidSelectedError;
@UiField
Label selectedPidCounter;

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

HandlerRegistration anchorClickHandler;
Expand All @@ -76,9 +86,13 @@ public SnapshotDownloadModal() {

initWidget(uiBinder.createAndBindUi(this));

this.pidSearch.setVisible(false);
this.pidSelectionScrollPanel.setVisible(false);
this.selectOrRemoveAllAnchor.setVisible(false);
this.noPidSelectedError.setVisible(false);
this.selectedPidCounter.setVisible(false);
this.searchBoxSeparatorSmall.setVisible(false);
this.searchBoxSeparatorBig.setVisible(false);

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

Expand All @@ -95,19 +109,29 @@ public void show(Consumer<SnapshotDownloadOptions> consumer) {
public void show(Consumer<SnapshotDownloadOptions> consumer, List<String> availablePids) {
this.snapshotDownloadConsumer = consumer;
this.noPidSelectedError.setVisible(false);
this.searchBoxSeparatorSmall.setVisible(true);
this.searchBoxSeparatorBig.setVisible(true);
this.modal.setTitle(MSGS.deviceSnapshotDownloadModalTitle());
this.downloadModalDescription.setText(MSGS.deviceSnapshotDownloadModalHint());
initPidSearch();
initSnapshotPidList(availablePids);
initSnapshotSelectAllAnchor();
initSnapshotScrollPanel();
initSnapshotDownloadButtons();
initSelectedPidCounter();
this.modal.show();
}

/*
* Snapshot Download Inits
*/

private void initPidSearch() {
this.pidSearch.clear();
this.pidSearch.setVisible(true);
this.pidSearch.addKeyUpHandler(this::onSearchBoxEvent);
}

private void initSnapshotPidList(List<String> snapshotConfigs) {

this.pidPanel.clear();
Expand All @@ -125,9 +149,8 @@ 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.anchorClickHandler = this.selectOrRemoveAllAnchor.addClickHandler(this::onSelectOrRemoveAllSelection);
this.selectOrRemoveAllAnchor.setVisible(true);
}

Expand Down Expand Up @@ -162,6 +185,11 @@ private void initSnapshotDownloadButtons() {
});
}

private void initSelectedPidCounter() {
updateSelectedPidsCounter();
this.selectedPidCounter.setVisible(true);
}

/*
* Wiregraph Snapshot Download Inits
*/
Expand All @@ -180,16 +208,36 @@ private void initWiregraphDownloadButtons() {
}

/*
* Utils
* OnEvents Methods
*/

private void onSearchBoxEvent(KeyUpEvent event) {
TextBox searchBox = (TextBox) event.getSource();
String searchedPid = searchBox.getValue();

if (searchedPid == null || searchedPid.isEmpty() || searchedPid.equals("")) {
this.pidPanel.iterator().forEachRemaining(widget -> widget.setVisible(true));
} else {
this.pidPanel.iterator().forEachRemaining(widget -> {
CheckBox box = (CheckBox) widget;
box.setVisible(box.getText().toLowerCase().contains(searchedPid.toLowerCase()));
});
}

if (this.noPidSelectedError.isVisible()) {
this.noPidSelectedError.setVisible(false);
}

updateSelectOrRemoveAllText(checkPidsCheckboxStates());
}

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

checkAllPidsSelected();
updateSelectOrRemoveAllText();
updateSelectOrRemoveAllText(checkPidsCheckboxStates());
updateSelectedPidsCounter();

}

Expand All @@ -199,6 +247,41 @@ private void onCancelClick(ClickEvent handler) {
this.noPidSelectedError.setVisible(false);
}

private void onSelectOrRemoveAllSelection(ClickEvent handler) {
PartialSnapshotCheckboxStatus state = checkPidsCheckboxStates();
switch (state) {
case ALL_VISIBLE_ALL_SELECTED:
case PARTIAL_VISIBLE_ALL_SELECTED: {
pidPanel.iterator().forEachRemaining(widget -> {
if (widget.isVisible()) {
((CheckBox) widget).setValue(false);
}
});
break;
}

case ALL_VISIBLE_PARTIAL_SELECTED:
case PARTIAL_VISIBLE_PARTIAL_SELECTED:
pidPanel.iterator().forEachRemaining(widget -> {
if (widget.isVisible()) {
((CheckBox) widget).setValue(true);
}
});
break;
}

updateSelectOrRemoveAllText(checkPidsCheckboxStates());
updateSelectedPidsCounter();

if (this.noPidSelectedError.isVisible()) {
this.noPidSelectedError.setVisible(false);
}
}

/*
* Utils
*/

private Optional<List<String>> getSelectedPids() {
List<String> selectedPids = new ArrayList<>();
this.pidPanel.iterator().forEachRemaining(pid -> {
Expand All @@ -212,12 +295,6 @@ private Optional<List<String>> getSelectedPids() {
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();
Expand All @@ -232,23 +309,43 @@ private boolean isOnePidSelected() {
return result;
}

private void checkAllPidsSelected() {
private PartialSnapshotCheckboxStatus checkPidsCheckboxStates() {
boolean areAllVisible = true;
boolean areAllSelected = true;

Iterator<Widget> pidPanelIterator = this.pidPanel.iterator();
while (pidPanelIterator.hasNext()) {
if (!((CheckBox) pidPanelIterator.next()).getValue().booleanValue()) {
Widget widget = pidPanelIterator.next();
if (!widget.isVisible()) {
areAllVisible = false;
}

if (widget.isVisible() && !((CheckBox) widget).getValue().booleanValue()) {
areAllSelected = false;
break;
}
}
this.areAllPidsSelected = areAllSelected;

return PartialSnapshotCheckboxStatus.fromVisibleAndSelectedStatus(areAllVisible, areAllSelected);
}

private void updateSelectOrRemoveAllText() {
if (this.areAllPidsSelected) {
private void updateSelectOrRemoveAllText(PartialSnapshotCheckboxStatus state) {

switch (state) {
case ALL_VISIBLE_ALL_SELECTED:
this.selectOrRemoveAllAnchor.setText(MSGS.removeAllAnchorText());
} else {
break;

case ALL_VISIBLE_PARTIAL_SELECTED:
this.selectOrRemoveAllAnchor.setText(MSGS.selectAllAnchorText());
break;

case PARTIAL_VISIBLE_ALL_SELECTED:
this.selectOrRemoveAllAnchor.setText(MSGS.removeAllVisibleAnchorText());
break;

case PARTIAL_VISIBLE_PARTIAL_SELECTED:
this.selectOrRemoveAllAnchor.setText(MSGS.selectAllVisibleAnchorText());
break;
}
}

Expand All @@ -258,4 +355,20 @@ private void resetScrollPanel() {
this.noPidSelectedError.setVisible(false);
}

private void updateSelectedPidsCounter() {

int selectedPids = 0;

Iterator<Widget> pidPanelIterator = this.pidPanel.iterator();
while (pidPanelIterator.hasNext()) {
if (((CheckBox) pidPanelIterator.next()).getValue().booleanValue()) {
selectedPids++;
}
}

StringBuilder counterTextBuilder = new StringBuilder("Pids Selected ").append(selectedPids).append("/")
.append(this.pidPanel.getWidgetCount());

this.selectedPidCounter.setText(counterTextBuilder.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,34 @@

<ui:style>
.channel-name-validation-label {
padding-top: 10px;
color: red;
font-size: 0.35cm;
font-weight: normal;
padding-top: 10px;
color: red;
font-size: 0.35cm;
font-weight: normal;
}
.small-spacing {
padding-bottom: 10px;
}
.big-spacing {
padding-bottom: 20px;
}

.text-button {
background: none;
border: none;
color: blue;
text-decoration: underline;
cursor: pointer;
float: left;
}

.right-label {
margin-left: auto;
float: right;
font-weight: bold;
}
.horizontal-panel {
width: 100%;
}
</ui:style>

Expand All @@ -38,12 +62,19 @@
<b:FormGroup>
<b.html:Paragraph ui:field="downloadModalDescription" />
<b.html:Paragraph ui:field="formatModalHint" text="{msgs.formatDownloadHint}" />
<g:Label ui:field="searchBoxSeparatorSmall" addStyleNames="{style.small-spacing}"/>
<b:TextBox placeholder="{msgs.snapshotDownloadSearchBoxPlaceholder}"
ui:field="pidSearch" addStyleNames="services-search" />
<g:Label ui:field="searchBoxSeparatorBig" addStyleNames="{style.big-spacing}"/>
<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" />
<g:HorizontalPanel addStyleNames="{style.horizontal-panel}" >
<b:Anchor ui:field="selectOrRemoveAllAnchor" />
<g:Label ui:field="selectedPidCounter" addStyleNames="{style.right-label}" />
</g:HorizontalPanel>
</b:ModalBody>
<b:ModalFooter>
<b:Button addStyleNames="fa" type="PRIMARY" ui:field= "cancelButton" text="{msgs.cancelButton}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,10 @@ downloadSnapshotXmlButton=Download as XML
downloadSnapshotJsonButton=Download as JSON
downloadSnapshotError=Please select at least one pid from the list
selectAllAnchorText=Select All Pids
selectAllVisibleAnchorText=Select All Visible Pids
removeAllAnchorText=Remove All Pids
removeAllVisibleAnchorText=Remove All Visible Pids
snapshotDownloadSearchBoxPlaceholder=Filter pids by name...

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,10 @@ downloadSnapshotXmlButton=XML としてダウンロード
downloadSnapshotJsonButton=JSON としてダウンロード
downloadSnapshotError=リストから少なくとも一つの PID を選択してください
selectAllAnchorText=すべての Pid を選択します
selectAllVisibleAnchorText=すべての可視 PID を選択
removeAllAnchorText=すべての PID を削除する
removeAllVisibleAnchorText=すべての目に見える PID を取除いて下さい
snapshotDownloadSearchBoxPlaceholder=名前でピドをフィルター...

netIntro=ネットワークインターフェースを選択して設定を変更します。DHCPサーバーとNATはLANの使用が可能なインターフェースに対してのみ設定変更が可能です。変更を適用した際、新しいネットワーク環境設定の内容によっては、ゲートウェイへの接続が遮断される場合があります。
netInterfaceName=インターフェースの名称
Expand Down
Loading