Skip to content

Commit 5a5da05

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 5a5da05

25 files changed

+445
-66
lines changed

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

+2
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
}

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

+9
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();

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

+16
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
}

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

+30-1
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;
@@ -32,14 +35,23 @@ public class FcpStorageView extends AbstractStorageView<SanStorageModelBase> imp
3235
@UiField
3336
PaginationControl paginationControl;
3437

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

3746
private double panelHeight = 292;
3847

3948
private double listHeight = 278;
4049

50+
private static final CommonApplicationConstants constants = AssetProvider.getConstants();
51+
4152
public FcpStorageView(boolean multiSelection) {
4253
initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
54+
localize();
4355
driver.initialize(this);
4456
this.multiSelection = multiSelection;
4557
}
@@ -51,6 +63,10 @@ public FcpStorageView(boolean multiSelection, double panelHeight, double listHei
5163
this.listHeight = listHeight;
5264
}
5365

66+
void localize() {
67+
hideUsedLunsCheckBox.setHTML(constants.hideUsedLunsLabel());
68+
}
69+
5470
@Override
5571
public void edit(final SanStorageModelBase object) {
5672
driver.edit(object);
@@ -64,6 +80,8 @@ public void edit(final SanStorageModelBase object) {
6480
onIsValidPropertyChange(object);
6581
}
6682
});
83+
84+
initHideUsedLunsCheckBox();
6785
}
6886

6987
void onIsValidPropertyChange(Model model) {
@@ -105,8 +123,10 @@ public void focus() {
105123

106124
protected void initLists(SanStorageModelBase model) {
107125
PageFilter pageFilter = new PageFilter(50);
126+
lunFilter = new LunFilter(hideUsedLunsCheckBox.getValue());
108127
SanStorageLunToTargetList sanStorageLunToTargetList =
109-
new SanStorageLunToTargetList(PagingProxyModel.create(pageFilter, model), true, multiSelection);
128+
new SanStorageLunToTargetList(PagingFilteredProxyModel.create(pageFilter, lunFilter, model),
129+
true, multiSelection);
110130
sanStorageLunToTargetList.activateItemsUpdate();
111131
paginationControl.setDataProvider(StoragePagingDataProvider.create(pageFilter, sanStorageLunToTargetList));
112132
model.getItemsChangedEvent().addListener((ev, sender, args) -> paginationControl.updateTableControls());
@@ -119,6 +139,15 @@ protected void initLists(SanStorageModelBase model) {
119139
contentPanel.setWidget(sanStorageLunToTargetList);
120140
}
121141

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

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

+9
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+
}

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

+9-1
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
}

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

+28-2
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(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

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

+9
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>

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

+13-1
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);
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+
import java.util.stream.Collectors;
5+
6+
import org.ovirt.engine.ui.uicommonweb.models.storage.LunModel;
7+
8+
/**
9+
* LUN model filter.
10+
*/
11+
public class LunFilter extends LunFilterBase implements ModelFilter<LunModel> {
12+
13+
public LunFilter(boolean isHideUsedLuns) {
14+
super(isHideUsedLuns);
15+
}
16+
17+
public Collection<LunModel> filter(Collection<LunModel> items) {
18+
if (items == null || !needFilter()) {
19+
return items;
20+
}
21+
22+
return items.stream().filter(lunModel -> {
23+
if (getIsHideUsedLuns()) {
24+
return !lunModel.getIsUsed();
25+
}
26+
return true;
27+
}).collect(Collectors.toList());
28+
}
29+
}

0 commit comments

Comments
 (0)