Skip to content

Commit b9c3bb5

Browse files
committed
webadmin: added filter to display only not in use LUNs
An existing problem: When creating a new storage domain, when selecting a LUN, both unused LUNs and used LUNs are shown in the list. Since the list of LUNs can be very large, it is very difficult to search for unused LUNs that can be selected for a storage domain. This happens in the following cases: - selecting a LUN when creating a new storage domain; - selecting a LUN when editing an existing storage domain; - selecting a LUN when creating RDM disks for a VM. Problem solving: The filter "Hide used LUNs" is added to the list of LUNs. When this filter is checked, the list shows only unused LUNs that can be added to the storage domain. This filter is checked by default. Signed-off-by: Evgeniy Kononov <[email protected]>
1 parent 2fb96e7 commit b9c3bb5

File tree

25 files changed

+446
-66
lines changed

25 files changed

+446
-66
lines changed

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,4 +1964,6 @@ public interface CommonApplicationConstants extends Constants {
19641964
String permissionFilter();
19651965

19661966
String propertyId();
1967+
1968+
String hideUsedLunsLabel();
19671969
}

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/PaginationControl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public void goBack() {
5454
@Override
5555
public void refresh() {
5656
}
57+
58+
@Override
59+
public void reload() {
60+
}
5761
};
5862

5963
interface WidgetUiBinder extends UiBinder<FlowPanel, PaginationControl> {
@@ -114,6 +118,11 @@ public void setDataProvider(PagingDataProvider dataProvider) {
114118
updateTableControls();
115119
}
116120

121+
public void reload() {
122+
getDataProvider().reload();
123+
updateTableControls();
124+
}
125+
117126
@UiHandler("prevPageButton")
118127
public void handlePrevPageButtonClick(ClickEvent event) {
119128
getDataProvider().goBack();

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/HasPaging.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.ovirt.engine.ui.common.widget.table;
22

3+
import java.util.Collection;
4+
35
/**
46
* Classes that implement this interface support forward/back paging functionality.
57
*
@@ -30,4 +32,18 @@ public interface HasPaging {
3032
* Refresh the current page.
3133
*/
3234
void refresh();
35+
36+
/**
37+
* Reload all and go to the first page.
38+
*/
39+
default void reload() {
40+
41+
}
42+
43+
/**
44+
* Reload all and go to the first page (with providing access to the items, if needed).
45+
*/
46+
default void reload(Collection items) {
47+
48+
}
3349
}

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import java.util.List;
44

5+
import org.gwtbootstrap3.client.ui.CheckBox;
6+
import org.ovirt.engine.ui.common.CommonApplicationConstants;
57
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
8+
import org.ovirt.engine.ui.common.gin.AssetProvider;
69
import org.ovirt.engine.ui.common.widget.HasValidation;
710
import org.ovirt.engine.ui.common.widget.PaginationControl;
811
import org.ovirt.engine.ui.common.widget.ValidatedPanelWidget;
@@ -11,6 +14,7 @@
1114

1215
import com.google.gwt.core.client.GWT;
1316
import com.google.gwt.dom.client.Style.Unit;
17+
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
1418
import com.google.gwt.uibinder.client.UiBinder;
1519
import com.google.gwt.uibinder.client.UiField;
1620
import com.google.gwt.user.client.ui.Label;
@@ -32,14 +36,23 @@ public class FcpStorageView extends AbstractStorageView<SanStorageModelBase> imp
3236
@UiField
3337
PaginationControl paginationControl;
3438

39+
@UiField
40+
@Ignore
41+
CheckBox hideUsedLunsCheckBox;
42+
43+
LunFilter lunFilter;
44+
3545
private final Driver driver = GWT.create(Driver.class);
3646

3747
private double panelHeight = 292;
3848

3949
private double listHeight = 278;
4050

51+
private static final CommonApplicationConstants constants = AssetProvider.getConstants();
52+
4153
public FcpStorageView(boolean multiSelection) {
4254
initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
55+
localize();
4356
driver.initialize(this);
4457
this.multiSelection = multiSelection;
4558
}
@@ -51,6 +64,10 @@ public FcpStorageView(boolean multiSelection, double panelHeight, double listHei
5164
this.listHeight = listHeight;
5265
}
5366

67+
void localize() {
68+
hideUsedLunsCheckBox.setHTML(SafeHtmlUtils.fromString(constants.hideUsedLunsLabel()));
69+
}
70+
5471
@Override
5572
public void edit(final SanStorageModelBase object) {
5673
driver.edit(object);
@@ -64,6 +81,8 @@ public void edit(final SanStorageModelBase object) {
6481
onIsValidPropertyChange(object);
6582
}
6683
});
84+
85+
initHideUsedLunsCheckBox();
6786
}
6887

6988
void onIsValidPropertyChange(Model model) {
@@ -105,8 +124,10 @@ public void focus() {
105124

106125
protected void initLists(SanStorageModelBase model) {
107126
PageFilter pageFilter = new PageFilter(50);
127+
lunFilter = new LunFilter(hideUsedLunsCheckBox.getValue());
108128
SanStorageLunToTargetList sanStorageLunToTargetList =
109-
new SanStorageLunToTargetList(PagingProxyModel.create(pageFilter, model), true, multiSelection);
129+
new SanStorageLunToTargetList(PagingFilteredProxyModel.create(pageFilter, lunFilter, model),
130+
true, multiSelection);
110131
sanStorageLunToTargetList.activateItemsUpdate();
111132
paginationControl.setDataProvider(StoragePagingDataProvider.create(pageFilter, sanStorageLunToTargetList));
112133
model.getItemsChangedEvent().addListener((ev, sender, args) -> paginationControl.updateTableControls());
@@ -119,6 +140,15 @@ protected void initLists(SanStorageModelBase model) {
119140
contentPanel.setWidget(sanStorageLunToTargetList);
120141
}
121142

143+
private void initHideUsedLunsCheckBox() {
144+
hideUsedLunsCheckBox.addValueChangeHandler(event -> {
145+
if (lunFilter != null) {
146+
lunFilter.setIsHideUsedLuns(event.getValue());
147+
}
148+
paginationControl.reload();
149+
});
150+
}
151+
122152
interface Driver extends UiCommonEditorDriver<SanStorageModelBase, FcpStorageView> {
123153
}
124154

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/FcpStorageView.ui.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
justify-content: flex-end;
1515
border-bottom: none;
1616
}
17+
18+
.hideUsedLunsCheckBox {
19+
font-size: 12px;
20+
padding-left: 23px;
21+
height: 10px;
22+
}
1723
</ui:style>
1824

1925
<b:Container fluid="true">
@@ -27,6 +33,9 @@
2733
<g:Label ui:field="warning" addStyleNames="{style.errorMessageLabel}"/>
2834
</b:Column>
2935
</b:Row>
36+
<b:Row>
37+
<b:CheckBox ui:field="hideUsedLunsCheckBox" value="true" addStyleNames="{style.hideUsedLunsCheckBox}" />
38+
</b:Row>
3039
<b:Row>
3140
<b:Column size="SM_12">
3241
<g:FlowPanel addStyleNames="content-view-pf-pagination clearfix {style.paginationBar}">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.ovirt.engine.ui.common.widget.uicommon.storage;
2+
3+
import java.util.Collection;
4+
5+
import org.ovirt.engine.ui.uicommonweb.models.storage.SanStorageModelBase;
6+
7+
/**
8+
* Create a proxy model that will intercept {@link SanStorageModelBase#getItems()} and filter the items.
9+
* From a logical point of view all data is still one model i.e. user changes are not lost when
10+
* applying the filter and submitting.
11+
*/
12+
public class FilteredProxyModel extends ProxyModelBase {
13+
14+
private final ModelFilter<?> filter;
15+
16+
public FilteredProxyModel(SanStorageModelBase model, ModelFilter<?> filter) {
17+
super(model);
18+
this.filter = filter;
19+
}
20+
21+
public static FilteredProxyModel create(ModelFilter<?> filter, SanStorageModelBase model) {
22+
return new FilteredProxyModel(model, filter);
23+
}
24+
25+
@Override
26+
public Collection getItems() {
27+
return filter.filter(getModel().getItems());
28+
}
29+
}

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiLunToTargetView.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ interface ViewUiBinder extends UiBinder<Widget, IscsiLunToTargetView> {
3030
private final double treeHeight;
3131
private final boolean multiSelection;
3232

33+
private LunFilter lunFilter;
34+
3335
public IscsiLunToTargetView(double treeHeight, boolean multiSelection) {
3436
this.treeHeight = treeHeight;
3537
this.multiSelection = multiSelection;
@@ -38,14 +40,20 @@ public IscsiLunToTargetView(double treeHeight, boolean multiSelection) {
3840
driver.initialize(this);
3941
}
4042

43+
public IscsiLunToTargetView(double treeHeight, boolean multiSelection, LunFilter lunFilter) {
44+
this(treeHeight, multiSelection);
45+
this.lunFilter = lunFilter;
46+
}
47+
4148
@Override
4249
public void edit(final SanStorageModelBase object) {
4350
driver.edit(object);
4451
initLists(object);
4552
}
4653

4754
void initLists(SanStorageModelBase object) {
48-
sanStorageLunToTargetList = new SanStorageLunToTargetList(object, false, multiSelection);
55+
sanStorageLunToTargetList = new SanStorageLunToTargetList(FilteredProxyModel.create(lunFilter, object),
56+
false, multiSelection);
4957
sanStorageLunToTargetList.setTreeContainerHeight(treeHeight);
5058
lunsListPanel.add(sanStorageLunToTargetList);
5159
}

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44

5+
import org.gwtbootstrap3.client.ui.CheckBox;
56
import org.ovirt.engine.core.compat.StringHelper;
67
import org.ovirt.engine.ui.common.CommonApplicationConstants;
78
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
@@ -72,11 +73,18 @@ interface ViewUiBinder extends UiBinder<Widget, IscsiStorageView> {
7273
@Ignore
7374
Label subLabel;
7475

76+
@UiField
77+
@Ignore
78+
CheckBox hideUsedLunsCheckBox;
79+
7580
private double treeCollapsedHeight = 245;
7681
private double treeExpandedHeight = 355;
7782
private double lunsTreeHeight = 405;
7883
private double tabContentHeight = 100;
7984

85+
private LunFilter lunFilter;
86+
private SanTargetFilter sanTargetFilter;
87+
8088
private final Driver driver = GWT.create(Driver.class);
8189

8290
private static final CommonApplicationConstants constants = AssetProvider.getConstants();
@@ -103,6 +111,7 @@ public IscsiStorageView(boolean multiSelection,
103111
void localize() {
104112
lunToTargetsTab.setLabel(constants.storageIscsiPopupLunToTargetsTabLabel());
105113
targetsToLunTab.setLabel(constants.storageIscsiPopupTargetsToLunTabLabel());
114+
hideUsedLunsCheckBox.setHTML(SafeHtmlUtils.fromString(constants.hideUsedLunsLabel()));
106115
}
107116

108117
@Override
@@ -170,12 +179,17 @@ public void edit(final IscsiStorageModel object) {
170179
warning.setVisible(!StringHelper.isNullOrEmpty(warningText));
171180
}
172181
});
182+
183+
initHideUsedLunsCheckBox(object);
173184
}
174185

175186
void initLists(IscsiStorageModel object) {
187+
lunFilter = new LunFilter(hideUsedLunsCheckBox.getValue());
188+
sanTargetFilter = new SanTargetFilter(hideUsedLunsCheckBox.getValue());
176189
// Create discover panel and storage lists
177-
iscsiTargetToLunView = new IscsiTargetToLunView(treeCollapsedHeight, treeExpandedHeight, false, multiSelection);
178-
iscsiLunToTargetView = new IscsiLunToTargetView(lunsTreeHeight, multiSelection);
190+
iscsiTargetToLunView = new IscsiTargetToLunView(treeCollapsedHeight, treeExpandedHeight, false, multiSelection,
191+
sanTargetFilter, lunFilter);
192+
iscsiLunToTargetView = new IscsiLunToTargetView(lunsTreeHeight, multiSelection, lunFilter);
179193

180194
// Update Style
181195
dialogTabPanel.getElement().getStyle().setHeight(tabContentHeight, Unit.PCT);
@@ -243,6 +257,18 @@ public void cleanup() {
243257
public void focus() {
244258
}
245259

260+
private void initHideUsedLunsCheckBox(IscsiStorageModel object) {
261+
hideUsedLunsCheckBox.addValueChangeHandler(event -> {
262+
if (lunFilter != null) {
263+
lunFilter.setIsHideUsedLuns(event.getValue());
264+
}
265+
if (sanTargetFilter != null) {
266+
sanTargetFilter.setIsHideUsedLuns(event.getValue());
267+
}
268+
updateListByGrouping(object);
269+
});
270+
}
271+
246272
interface WidgetStyle extends CssResource {
247273
String barEditDomain();
248274

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiStorageView.ui.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
font-size: 12px;
9191
padding-left: 50px;
9292
}
93+
94+
.hideUsedLunsCheckBox {
95+
font-size: 12px;
96+
padding-left: 60px;
97+
height: 10px;
98+
}
9399
</ui:style>
94100

95101
<b:Container fluid="true">
@@ -105,6 +111,9 @@
105111
<pa:AlertPanel ui:field="warning" visible="false" />
106112
</b:Column>
107113
</b:Row>
114+
<b:Row>
115+
<b:CheckBox ui:field="hideUsedLunsCheckBox" value="true" addStyleNames="{style.hideUsedLunsCheckBox}" />
116+
</b:Row>
108117
<b:Row>
109118
<t:DialogTabPanel ui:field="dialogTabPanel" contentStyle="{style.content}" navStyle="{style.maxHeight}" addStyleNames="{style.tabPanel}" height="100%" width="100%">
110119
<t:tab>

frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/storage/IscsiTargetToLunView.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ interface ViewUiBinder extends UiBinder<Widget, IscsiTargetToLunView> {
3636
private boolean hideLeaf;
3737
private boolean multiSelection;
3838

39+
private SanTargetFilter sanTargetFilter;
40+
private LunFilter leafLunFilter;
41+
3942
private final Driver driver = GWT.create(Driver.class);
4043

4144
public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeight) {
@@ -53,6 +56,14 @@ public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeigh
5356
driver.initialize(this);
5457
}
5558

59+
public IscsiTargetToLunView(double treeCollapsedHeight, double treeExpandedHeight,
60+
boolean hideLeaf, boolean multiSelection, SanTargetFilter sanTargetFilter,
61+
LunFilter leafLunFilter) {
62+
this(treeCollapsedHeight, treeExpandedHeight, hideLeaf, multiSelection);
63+
this.sanTargetFilter = sanTargetFilter;
64+
this.leafLunFilter = leafLunFilter;
65+
}
66+
5667
@Override
5768
public void edit(final SanStorageModelBase object) {
5869
driver.edit(object);
@@ -88,7 +99,8 @@ private void setProposeDiscover(boolean proposeDiscover) {
8899
void initLists(SanStorageModelBase object) {
89100
// Create discover panel and storage lists
90101
iscsiDiscoverTargetsView = new IscsiDiscoverTargetsView();
91-
sanStorageTargetToLunList = new SanStorageTargetToLunList(object, hideLeaf, multiSelection);
102+
sanStorageTargetToLunList = new SanStorageTargetToLunList(FilteredProxyModel.create(sanTargetFilter, object),
103+
hideLeaf, multiSelection, leafLunFilter);
92104

93105
// Add view widgets to panel
94106
targetsToLunsDiscoverPanel.add(iscsiDiscoverTargetsView);

0 commit comments

Comments
 (0)